Shape
类指针的数组,其中每个指针都指向一个不同的派生类对象。在运行时,调用Draw()
方法会导致调用被该派生类重写的方法,并绘制(或呈现)特定的Shape
。Shape *basep[] = { &line_obj, &tri_obj,
&rect_obj, &cir_obj};
for (i = 0; i < NO_PICTURES; i++)
basep[i] -> Draw ();
shape
,程序不必发生巨大变化。原因是实际上仅有很少的代码段使用(依赖于)具体的Shape
类型。virtual
,而是在子类中重新定义它们,比如Line
和Triangle
,那么会有什么不同? - Mathew Kurian当您需要以相同的方式处理不同的对象时,您可以使用虚函数。这被称为多态性。让我们想象您有一些基类 - 类似于经典的形状:
class Shape
{
public:
virtual void draw() = 0;
virtual ~Shape() {}
};
class Rectange: public Shape
{
public:
void draw() { // draw rectangle here }
};
class Circle: public Shape
{
public:
void draw() { // draw circle here }
};
现在你可以有不同形状的向量:
vector<Shape*> shapes;
shapes.push_back(new Rectangle());
shapes.push_back(new Circle());
你可以像这样绘制所有形状:
for(vector<Shape*>::iterator i = shapes.begin(); i != shapes.end(); i++)
{
(*i)->draw();
}
以这种方式,您使用一个虚方法 - draw()来绘制不同的形状。根据指针背后对象的类型的运行时信息,选择正确版本的方法。想象一下动物类,它的衍生类有猫、狗和牛。动物类有一个
virtual void SaySomething()
{
cout << "Something";
}
函数。
Animal *a;
a = new Dog();
a->SaySomething();
不要打印“Something”,狗应该说“Bark”,猫应该说“Meow”。在这个例子中,a是一只狗,但有时您可能会有一只动物指针,而不知道它是哪种动物。您不想知道它是什么动物,您只想让动物说些什么。因此,您只需调用虚函数,猫将说“meow”,狗将说“bark”。
当然,SaySomething函数应该是纯虚函数,以避免可能出现的错误。
Fox
实例将会说“Something”,这是不正确的。如果我们将SaySomething声明为纯虚方法,我们就不能实例化“狐狸”,包含new Fox(...)
的代码将会引发错误。这样,创建Fox
类的开发者将在编译时被通知他/她的错误。编译时错误很好,因为它们不浪费时间 :) - holgac