【问题标题】:Dynamic binding in virtual functions C++虚函数 C++ 中的动态绑定
【发布时间】:2012-08-03 17:48:07
【问题描述】:

我有一个带有 1 个虚函数的基类

class Base
{
public:
    virtual void print() {
        cout<<"IN BASE\n";
    }
}

现在我使用

创建它的对象
Base b

然后打电话

b.print();

这是动态绑定吗,因为“Base”类包含 1 个虚函数并创建了它的 VTable..

【问题讨论】:

  • 如果您有多个基类并且必须将派生类的实例转换为基类,然后调用该基类的虚拟成员函数,这将是动态绑定。

标签: c++


【解决方案1】:

在创建对象的同一上下文中,编译器不需要使用虚拟调度,因为它知道确切的类型。但这与虚函数的数量无关(是的,只要至少有一个,编译器就会生成一个 vtable 并在您的对象中存储一个 vptr )。

Base b;
b.print(); // can be optimized to b.Base::print(),
           // with no virtual dispatch

void f( Base& b ) {
   b.print();       // must use virtual dispatch (ignoring potential inlining)
}

【讨论】:

  • 谢谢。如果我有 3 个派生类,并且如果我在派生类中也定义了 print 并调用“Derived1 d; d.print()”,则可以认为是动态绑定的情况
  • @Akash:术语是动态调度,如果对象是在与调用相同的范围内创建的,那么编译器就知道动态调度的结果会怎样be并且可以优化它,调用适当的函数。这与对象的确切类型无关,因为编译器知道该确切类型。
【解决方案2】:

术语“动态绑定”通常意味着其他东西 - 允许您从外部文件(DLL 或 SO)调用函数的管道,就好像它们是可执行文件的一部分一样。

Base 类有一个 vtable 没问题 - 毕竟,在编译当前文件时,编译器无法确定在项目的其他地方是否有它的任何派生类。

现在,调用是否遵循 vtable 是一个实现细节 - 它取决于编译器和设置。一方面,它应该。另一方面,如果对象像这样是自动的,那么它的类型在编译时是已知的,并且不可能是 Base 以外的其他类型。一个好的编译器可能会优化 vtable 查找。

启用装配列表的构建肯定会显示给您。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 2018-02-07
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    相关资源
    最近更新 更多