cpp class 具有虚拟指针和继承的大小
cpp class size with virutal pointer and inheritance
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
对于classC来说,它有一个虚函数,所以classc中隐藏了一个虚指针,是4个字节
但是为什么class B的大小也是4。我认为它在class B中存在两个指针,一个是B本身,因为class B有一个虚函数,一个是给A的。
那么 E 有同样的问题吗?
感谢任何帮助
不,每个使用虚函数的对象中只有一个 vtable 指针,如果虚函数是在 class 本身中定义的,或者 class 派生自另一个 class 使用虚函数。
编译器生成的是 table 函数指针,因此每个 class(不是 instance/object)都有自己的。在您的示例中,您有一个 table 用于 class A,一个用于 class B,依此类推。在每个 object/instance 中你都有一个 vtable 指针。这个指针只指向table。如果你通过 class 指针调用一个虚函数,你可以间接访问 vtable 指针而不是 vtable 本身。
因此,class 的每个实例只保留一个 vtable 指针,指向此 class 的 vtable。如您所见,这会导致您编写的每个 class 的每个实例的大小都相同。
在多重继承的情况下,会得到多个vtable指针。这里已经给出了更详细的答案:
vtable and multiple inheritance
顺便说一句:标准不能保证你有一个 vtable 和一个 vtable 指针,如果结果是我们对语义的期望,每个编译器都可以做它想做的事。但是通过 vtable 指针指向函数 table 中的指针的双重间接寻址是典型的实现。
对于单继承,派生class B 只是向虚拟table 再插入一个条目。
对于多重继承,派生 class E 有 2 个虚拟 table 指针。
进一步:C++ virtual table layout of MI(multiple inheritance)
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
对于classC来说,它有一个虚函数,所以classc中隐藏了一个虚指针,是4个字节
但是为什么class B的大小也是4。我认为它在class B中存在两个指针,一个是B本身,因为class B有一个虚函数,一个是给A的。
那么 E 有同样的问题吗?
感谢任何帮助
不,每个使用虚函数的对象中只有一个 vtable 指针,如果虚函数是在 class 本身中定义的,或者 class 派生自另一个 class 使用虚函数。
编译器生成的是 table 函数指针,因此每个 class(不是 instance/object)都有自己的。在您的示例中,您有一个 table 用于 class A,一个用于 class B,依此类推。在每个 object/instance 中你都有一个 vtable 指针。这个指针只指向table。如果你通过 class 指针调用一个虚函数,你可以间接访问 vtable 指针而不是 vtable 本身。
因此,class 的每个实例只保留一个 vtable 指针,指向此 class 的 vtable。如您所见,这会导致您编写的每个 class 的每个实例的大小都相同。
在多重继承的情况下,会得到多个vtable指针。这里已经给出了更详细的答案: vtable and multiple inheritance
顺便说一句:标准不能保证你有一个 vtable 和一个 vtable 指针,如果结果是我们对语义的期望,每个编译器都可以做它想做的事。但是通过 vtable 指针指向函数 table 中的指针的双重间接寻址是典型的实现。
对于单继承,派生class B 只是向虚拟table 再插入一个条目。 对于多重继承,派生 class E 有 2 个虚拟 table 指针。
进一步:C++ virtual table layout of MI(multiple inheritance)