c++ - 当我向派生类添加一个额外的虚函数时,开销是多少?

标签 c++

我正在浏览 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/

相关文章:

c++ - 对于迭代器,我的 vector 包装器的 'begin' 和 'end' 函数要返回什么?

c++ - 链接提取和插入、包围

c++ - 如何从 cv::Vec3f 转换为 float 类型?

C++构造函数差异

c++ - 使用指向抽象基类的指针时,是否有更有效的方法来获取派生类的类型?

c++ - OS X 10.7 上 MacPorts 的 Boost.Log 链接器错误

c++ - 如何访问派生类中定义的函数而不是多态性中的基类

c++ - BSF 操作码不工作

c++ - 将一种类型的对象分配给另一种类型

c++ - 找不到此 Quicksort 代码的问题