在C++中,这个方法调用的是静态绑定还是动态绑定?
In C++, is this method call static binding or dynamic binding?
这里是 class 定义:
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();
我读的一本书说最后一个语句是静态绑定:
但是,该语句对我来说仍然看起来是动态绑定,因为 rect->draw
应该在 运行 时间内由 rect
的 "vtable" 中的指针调用。
有人知道 rect->draw
是静态绑定还是动态绑定吗?
Rect::draw()
不是final
而rect
是一个指针,所以它使用动态绑定。
但是如果所有变量都在本地范围内并且所有类型都是已知的,编译器可能会使用 de-virtualization 作为优化。
您对 vtable 的整体理解是正确的。
我认为这本书想表达的是,编译器可能并且通常会优化 rect->draw 以在不进入 vtable 的情况下调用。
在这种情况下,编译器可以看到 rect 指向一个 Rectangle 对象。
在大多数生产代码中,很少会出现这种情况。
这取决于在哪里。在 class 的代码之外,这将始终是动态绑定。尽管在对象构造期间(在继承链上的任何构造函数内部)虚拟 table 查找被暂停,因为 children-class 对象可能尚未初始化。
这里是 class 定义:
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();
我读的一本书说最后一个语句是静态绑定:
但是,该语句对我来说仍然看起来是动态绑定,因为 rect->draw
应该在 运行 时间内由 rect
的 "vtable" 中的指针调用。
有人知道 rect->draw
是静态绑定还是动态绑定吗?
Rect::draw()
不是final
而rect
是一个指针,所以它使用动态绑定。
但是如果所有变量都在本地范围内并且所有类型都是已知的,编译器可能会使用 de-virtualization 作为优化。
您对 vtable 的整体理解是正确的。
我认为这本书想表达的是,编译器可能并且通常会优化 rect->draw 以在不进入 vtable 的情况下调用。
在这种情况下,编译器可以看到 rect 指向一个 Rectangle 对象。
在大多数生产代码中,很少会出现这种情况。
这取决于在哪里。在 class 的代码之外,这将始终是动态绑定。尽管在对象构造期间(在继承链上的任何构造函数内部)虚拟 table 查找被暂停,因为 children-class 对象可能尚未初始化。