动态方法绑定

Dynamic method binding

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

在课本中,"concepts of programming language, 10th",

有一部分是关于动态方法绑定的。

我认为rect指向的对象类型不能静态解析,因为rect是多态引用类型。 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 的基础类型可以在整个运行时修改。

你的代码没有问题,因为多态 类 virtual 函数调用在运行时使用虚函数 table 解析,事实上,这在 c++.

从概念上讲,因为 draw() 是一个虚拟方法,rect->draw() 将始终查询 rect 指向的 Rectangle 派生对象的 vtable

不过

如果编译器可以证明 rect 实际上指向 Rectangle 的一个实例,而不是从它派生的其他 class 的实例,它会覆盖 [=16] =] 方法,则允许(但不是必需)绕过多态查找,从而节省了几次内存提取。