派生类的虚表中除了父类的虚函数外没有任何虚函数

6

如果派生类除了继承自父类的虚函数之外没有其他虚函数,那么是否会为该派生类创建虚表?

例如:

class A{
public:
    virtual void show();

};

class B : public A
{

};

类B的虚拟表如何?

3
哪个编译器?标准的C++不知道什么是vTable。 - Quentin
1
你为什么关心这个?这有什么区别吗? - n. m.
我只是好奇虚拟表格及其所有需要使用虚拟表格实现动态多态性的情况。 - Anoop Kumar
我认为我们也需要类B的虚表。如果我们继承类B并覆盖show函数,这是必需的。在这种情况下,我们需要一个虚表来确定在运行时使用基类A指针调用哪个函数。 - Anoop Kumar
3个回答

2

当使用g++编译器(Ubuntu 8.2.0-1ubuntu2~18.04)8.2.0版本时,以下是gdb的原始回答:


15  class A
16  {
17      public:
18          virtual void show(){}
19  };  
20  
21  class B:public A
22  {
23  };  
24  
(gdb) l
25  int main()
26  {
27      A a;
28      B b;
29  }
(gdb) p a 
$5 = {_vptr.A = 0x55555575f5c8 <vtable for A+16>}
(gdb) p b 
$6 = {<A> = {_vptr.A = 0x55555575f5b0 <vtable for B+16>}, <No data fields>}
(gdb) 

因此,至少在这种情况下,我们可以得出结论:基类和派生类具有不同的虚函数表。最初的回答。

2
你的问题没有标准答案,它主要取决于编译器版本。 在C ++中没有指定标准ABI。如果你对此有更深入的兴趣,请查看“Itanium C ++ ABI”,或者通过查看汇编代码自行寻找答案。
甚至有一个提案为C ++定义可移植的ABI。 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4028.pdf

0

您可以通过查看对象的内容来检查它。我编写了这个简单的程序,打印出基类、派生类和一个与基类相同但具有普通方法而不是虚拟方法的类的内容:

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

class Base {
public:
    virtual void show() {}
};

class Derived : public Base
{ };

class NonVirtual {
public:
    void show() {}
};

struct Test
{
    int data1, data2;
};

template <typename T>
void showContents(T* obj, string name)
{
    Test* test = new Test{};
    test = reinterpret_cast<Test*>(obj);
    cout << name << ": " << hex << "0x" << test->data1 << " " << "0x" << test->data2 << endl;
    delete test;
}

int main()
{
    Base* base = new Base{};
    Derived* derived = new Derived{};
    NonVirtual* nonVirtual = new NonVirtual{};

    showContents(base, "Base");
    showContents(derived, "Derived");
    showContents(nonVirtual, "NonVirtual");

    delete base;
    delete derived;
    delete nonVirtual;
}

现场演示


在使用cpp.sh编译上述程序后运行的结果(我不确定那里使用了什么编译器):
Base: 0x4013e0 0x0
Derived: 0x401400 0x0
NonVirtual: 0x0 0x0

所以我期望它意味着确实为Derived对象创建了一个虚拟表(至少对于这个编译器而言——因为在C++标准中未定义所需的行为)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接