我正在浏览 Marshall Cline 的 C++ 常见问题解答 - 特别是 this link about how virtual functions are implemented in the compiler .
这似乎是说派生类的 vptr 存在于对象的基类部分。当创建派生类的实例时,不会在派生类部分中创建另一个 vptr - 只是将已存在于基类部分中的 vptr 初始化为指向正确的 vtable。
我的问题是:如果我在派生类中声明一个虚函数,而不是在基类中,开销是多少?是否在派生类部分中创建了一个额外的 vptr - 或者它仍然以相同的方式完成,即基类部分中的 vptr 被分配为指向特定的 vtable?
那么 - 为了使我的问题更具体一些 - 在下面的示例中,编译器是否为 Apple
类提供了一个额外的 vtable,因为它添加了 peel_me()
virtual功能? (我假设答案一定是肯定的)。如果是这样,编译器是否为 Apple
的实例提供另一个 vptr(即在 Fruit
基类部分的那个之上)?
class Fruit {
public:
virtual void display();
};
class Apple : public Fruit {
public:
virtual void display() { std::cout << "I'm an apple!\n"; }
virtual void peel_me(); // extra virtual function, that is not in the base class
};
我似乎无法在任何地方找到这个问题的答案。
最佳答案
通常:
Apple
需要自己的 vtable,无论您是否添加 peel_me
,因为它需要通过 virtual 找到其对 display
的覆盖调用 Apple
的实例。
添加 peel_me
使 vtable 的一个条目比其他条目大——与 peel_me
的代码相比,这个额外的条目可能会或可能不会占用大量空间>,但你可能不会想到。 Apple
的所有派生类的 vtables 也比没有 peel_me
时大了一个条目。
Apple
的实例有一个 vptr。它指向 Apple
的 vtable。此表包含 Apple
的所有虚拟成员函数的条目,包括从 Fruit
继承的那些,以及未在 Apple
中覆盖的任何条目(在这种情况下,Apple
中的 vtable 条目指的是 Fruit
中的实现。
关于c++ - 当我向派生类添加一个额外的虚函数时,开销是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21381056/