class Shape {
public:
virtual void draw() = 0;
. . .
};
class Circle : public Shape {
public:
void draw() { . . . }
. . .
};
class Rectangle : public Shape {
public:
void draw() { . . . }
. . .
};
class Square : public Rectangle {
public:
void draw() { . . . }
. . .
};
Rectangle* rect = new Rectangle;
rect->draw(); // Statically bound to the draw in the Rectangle class
在一本教科书中,"编程语言的概念,第10期",
有一部分是关于动态方法绑定的。
我认为rect指向的对象的类型不能静态解析,因为rect是polymorhpic引用类型。rect也可能在运行时引用Sqaure类型的对象。
代码上方的最后一行不正确??
考虑以下示例
int main
{
Shape* cir = new Circle;
Shape* rec = new Rectangle;
Shape* sqr = new Square;
cir->draw(); // Circle::draw
rec->draw(); // Rectangle::draw
sqr->draw(); // Square::draw
}
所有这些变量cir
、rec
和sqr
都是Shape*
,但由于多态性,它们将调用各自的draw
方法。当我们重复使用相同的变量时,这一点就更清楚了
int main
{
Shape* shape = new Circle;
shape->draw(); // Circle::draw
delete shape;
shape = new Rectangle;
shape->draw(); // Rectangle::draw
delete shape;
shape = new Square;
shape->draw(); // Square::draw
delete shape;
}
在这种情况下,必须在运行时解析draw
函数,因为shape
的底层类型可以在整个运行时进行修改。
从概念上讲,由于draw((是一个虚拟方法,rect->draw()
将始终查询rect
所指向的Rectangle
派生对象的vtable
。
但是
如果编译器能够证明rect
实际上指向的是Rectangle
的一个实例,而不是从中派生的覆盖draw()
方法的其他类,那么它可以(但不是必需的(绕过多态查找,从而节省了几次内存获取。
您的代码没有问题,因为多态类virtual
函数调用是在运行时使用虚拟函数表解决的,事实上,它在c++
中被称为动态绑定。