在C ++中,此方法是调用静态绑定还是动态绑定?

时间:2016-01-13 11:51:02

标签: c++ class virtual-functions

这是类定义:

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() { ... }
... };

这是客户端代码:

Square* sq = new Square; 
Rectangle* rect = new Rectangle; 
Shape* ptr_shape;
ptr_shape = sq;
ptr_shape->draw();
rect->draw();

我正在阅读的一本书说最后一个陈述是静态绑定:

enter image description here

然而,该语句仍然看起来是动态绑定给我的,因为rect->draw应该被" vtable"中的指针调用。在运行时间rect

有没有人对rect->draw是静态绑定还是动态绑定有想法?

3 个答案:

答案 0 :(得分:8)

Rect::draw()不是finalrect是指针,因此它使用动态绑定。

但是如果所有变量都在本地范围内且所有类型都已知,编译器可以使用去虚拟化作为优化。

答案 1 :(得分:1)

您对vtable的整体理解是正确的。

我认为这本书试图说的是编译器可能并且通常会优化rect-> draw,而无需转到vtable。

在这种情况下,编译器可以看到rect指向Rectangle对象。

在大多数生产代码中,很少会出现这种情况。

答案 2 :(得分:0)

这取决于哪里。在类的代码之外,这将始终是动态绑定。在对象构造期间(在继承链中的任何构造函数内部),虚拟表查找被暂停,因为子类对象可能尚未初始化。