c++ - 具有虚拟指针和继承的cpp类大小

标签 c++ virtual-table

class A{
    virtual void a();
};  
class B : A{
    virtual void a();
};
class C{
    virtual void a();
};
class E : A, C{
    virtual void a();
};

int main(){
    std::cout << (sizeof(B)) << "\n"; // 4
    std::cout << (sizeof(C)) << "\n"; // 4
    std::cout << (sizeof(E)) << "\n"; // 8
}

在 32 位系统 linux 中

为什么 sizeof(B) 和 sizeof(C) 都是 4

对于C类,它有一个虚函数,所以在c类中隐藏了一个4字节的虚指针

但为什么 B 类的大小也是 4。我认为 B 类中存在两个指针,一个是 B 本身,因为 B 类有一个虚函数,一个是 A。

那么 E 有同样的问题吗?

感谢任何帮助

最佳答案

不,每个使用虚函数的对象中只有一个 vtable 指针,如果虚函数是在类本身中定义的,或者该类派生自另一个使用虚函数的类。

编译器生成的是一个函数指针表,因此每个类(不是实例/对象)都有自己的。在您的示例中,您有一张用于 A 类的表,一张用于 B 类的表,依此类推。在每个对象/实例中,您都有一个 vtable 指针。该指针仅指向表。如果您通过类指针调用虚函数,则可以间接访问 vtable 指针而不是 vtable 本身。

因此,类的每个实例都只保留一个 vtable 指针,指向该类的 vtable。如您所见,这会导致您编写的每个类的每个实例都具有相同的大小。

在多重继承的情况下,你会得到多个vtable指针。这里已经给出了更详细的答案: vtable and multiple inheritance

顺便说一句:标准不能保证你有一个 vtable 和一个 vtable 指针,如果结果是我们对语义的期望,每个编译器都可以做它想做的事。但是通过 vtable 指针指向函数表中指针的双重间接寻址是典型的实现。

关于c++ - 具有虚拟指针和继承的cpp类大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59589330/

相关文章:

c++ - 如何使用 Visual Studio 2008 将字符串映射到函数?

c++ - 如何在源文件的翻译单元中禁用 OMP?

c++ - 为什么gcc实现的VTT中会有top_offset?

c++ - C/C++ 赋值运算符实现的底层细节。它返回什么?

c++ - 如何让 doxygen 只为网页创建 "Include dependency graph for ..."(不为 tex/PDF)?

c++ - template<typename> - 它是如何工作的?

c++ - 虚拟表和 _vptr 存储方案

c++ - 如何正确地将带有 vtable 的类实例写入和读取到 QSharedMemory 中?

c++ - vptr 和 vtable 是从基类继承的吗?