2

如果我像这样创建一个非常简单的类:

class A
{
  public :
    virtual void foo()
    {
    }
};

(没有虚拟析构函数)编译器会创建 vtable 吗?或者现代编译器是否足够聪明以识别这种情况(这可能是错误的复制和粘贴)并且不为此类类添加虚拟表?

4

3 回答 3

5

v-table 是一个实现细节。将 v-tables 用于虚函数的编译器将为此类创建一个。那些不会,不会。

于 2011-04-11T13:31:47.840 回答
2

编译器不能确定该类不是在另一个编译单元中派生的,因此它必须确保调用正确地依赖于实例的运行时类型。

如果它使用 vtable 来解析虚拟调用,则将创建一个 vtable。如果使用另一个实现,则将使用该机制。


旧版本:将创建一个 vtable,因为编译器无法确定该类不会在另一个编译单元中派生。

于 2011-04-11T13:31:36.287 回答
1

答案是编译器必须生成一个 v-table。要了解为什么考虑:

class B : public A
{
    void foo() { do something interesting }
}

在其他地方:

void bar (A& obj)
{
obj.foo()
}

可以肯定地将 B 类型的对象传递给bar()并且B::foo()将调用。对所有多态类总是有一个虚拟析构函数是一种很好的编程习惯,因为它允许多态删除 A。在我们的例子中,obj是类型B

void bar2 (A& obj)
{
delete obj;
}

可能不会像预期的那样表现,因为 B 的析构函数永远不会被调用。

于 2011-04-11T14:25:49.680 回答