[英]how to determine the size of virtual base class and derived classes from it?
#include <iostream>
using namespace std;
class base1{};
class base2{virtual void show(){}};
class test1{ };
class test2{virtual void show(){}};
class derv1:public virtual base1{};
class derv12:public virtual base2{};
class derv2:public virtual base2, public test1{};
class derv22:public virtual base2, public virtual test1{};
class derv222:public virtual base2, public virtual test2{};
int main()
{
cout<<"sizeof base1 = "<<sizeof(base1)<<endl;
cout<<"sizeof base2 = "<<sizeof(base2)<<endl;
cout<<"sizeof derv1 = "<<sizeof(derv1)<<endl;
cout<<"sizeof derv12 = "<<sizeof(derv12)<<endl;
cout<<"sizeof derv2 = "<<sizeof(derv2)<<endl;
cout<<"sizeof derv22 = "<<sizeof(derv22)<<endl;
cout<<"sizeof derv222 = "<<sizeof(derv222)<<endl;
}
输出:
sizeof base1 = 1
sizeof base2 = 4
sizeof derv1 = 4
sizeof derv12 = 8
sizeof derv2 = 8
sizeof derv22 = 8
sizeof derv222 = 12
我理解以下输出:
sizeof base1 : 1 => empty class , size is 1. result is OK.
sizeof base2 : 4 => since class has a virtual function, it adds
a vitual pointer in each object of the class
( 32 bit machine) , so added 4 bytes. Result is OK.
sizeof derv1 : 4 => base1 doesn't have virtual function but since
derv1 is virtually derived from base1 ,added 4 bytes.
I think that each virtual base class
added a pointer in object so i think Result is OK.
sizeof derv12: 8 => 4 bytes( from virtual pointer) + 4 bytes
(virtual base class ) = 8 bytes. Result is OK.
在上述输出之后,我的困惑开始了
sizeof derv2 : 8 => 8 bytes( virtual pointer + virtually base class)
from base2 + 1 byte from test1 => 9 bytes and adds 3 padding
bytes gives 12 bytes (should print).
why "sizeof (test1)" is not adding in the output ??
sizeof derv22 : 8 => 8 bytes( virtual pointer + virtually base class)
from base2 + 4 byte (virtually base class)
from test1 => 12 bytes (should print)
why 4 bytes from test1 (virtual base class) is not added
in the output?? In the size of(derv1 ) also has
a virtual base class( base1) and out put is 4 bytes means
they added 4 bytes in the output.
sizeof derv222: 12 => 12 bytes( virtual pointer + virtually derived)
from base2 + 8 byte( virtual pointer + virtually derived)
from test2 => 16 bytes (should print)
我错过了一些或者这些尺寸是系统依赖还是其他任何东西?
sizeof(base1)
和sizeof(test1)
为1的原因仅仅是为了防止大多数派生对象的大小为0.这就是所有标准的禁止。 允许基类子对象具有大小0(即,允许不占用任何字节),因此添加base1
作为基础不一定必须添加任何类的大小。
编译器所做的优化,而不是为类型为空类的基类子对象分配任何字节,称为“空基类优化”。 标准不要求实现应用它,但实现不适合认真工作。
我认为derv22
有点类似 - 如果编译器能够使用一个额外的指针处理两个虚拟基类,那么它有权这样做。 因此,您可能只需要“支付”一次,而不是每个虚拟基数“支付”。 这可能取决于编译器以及类之间的确切关系,但是,我从未调查过不同的实现,以查看它们是否以及何时被迫添加多个指针值得开销。
显然,至少对于你的编译器来说, derv222
已经做到了。 我想这是因为base2
和test2
基类子对象需要单独的vtable指针。 如果你认为当你发生什么事也许并不令人惊奇static_cast
一个derv222*
为指针,以一个基站或其他-无论结果需要能够具备的show()
叫上他们,并调用不同的功能(尽管在show
当前功能没做什么)。 我不知道这是否有可能为另一个编译器在8个字节实现这个继承-一个件事继承不必使用虚函数表来实现的。
如何从中确定虚基类和派生类的大小?
使用sizeof()
。
我的旧论文“C ++:Under the Hood”解释了虚拟基类的Microsoft C ++实现。 http://www.openrce.org/articles/files/jangrayhood.pdf
您可以使用cl / d1reportAllClassLayout进行编译,以获取类内存布局的文本报告。
快乐的黑客!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.