动态方法绑定

Dynamic method binding

本文关键字:绑定 方法 动态      更新时间:2023-10-16
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
}

所有这些变量cirrecsqr都是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++中被称为动态绑定。