说我们有
Class A
{
public:
int _i;
virtual int getI();
};
class B : public A
{
public:
int _j;
virtual int getI();
};
因此,假设内存中类的大小是其成员的总和(即忽略填充或实际可能发生的任何事情),B实例的大小是多少?是sizeof(A)+ sizeof(int)+ sizeof(vptr)?或者B实例不在其个人A实例中持有A vptr,因此sizeof(b)将是sizeof(int)+ sizeof(int)+ sizeof(vptr)?
答案 0 :(得分:3)
这是使代码工作所需的任何实现。所有你
可以说它至少是2 * sizeof(int)
,因为它的对象
类型B
包含两个int
(可能还有其他内容)。在一个典型的
实施,A
和B
将共享一个vptr,总大小将
只是一个指针超过两个整数(模数填充为
对齐,但在大多数实现中,我不认为会有
任何)。但这只是一个典型的实施;你不能指望它。
答案 1 :(得分:1)
关于vtable的任何讨论都将特定于某个实现,因为即使是vtable的存在也没有由C ++标准指定 - 它是一个实现细节。
通常,一个对象只有一个指向vtable的指针,该vtable将在该类型的所有对象之间共享。派生类将在表中包含指针,用于基类的每个虚函数以及它没有继承的每个新虚函数,但同样这是一个静态表,它是不的一部分。对象
要真正回答这个问题,最有可能的结果是sizeof(B)== sizeof(A :: _ i)+ sizeof(B :: _ j)+ sizeof(vptr)。
答案 2 :(得分:0)
除了James Kanze所说的,或许值得一提的是(在一个典型的实现中)B的虚拟表将在其开头包含A的虚拟表。
例如:
class A {
virtual void x();
virtual void y();
};
class B : A {
virtual void y();
virtual void z();
};
A的虚拟表:
B的虚拟表:
这就是为什么B的实例可以只用一个虚拟表指针就可以了。
BTW,多重继承可能会使事情变得复杂,并为每个对象引入多个虚拟表指针。请记住,所有这些都是一个实现细节,您永远不应该编写依赖于它的代码。
答案 3 :(得分:0)
你为什么想知道?如果你打算在你的程序中使用它,我会尝试寻找一种比计算它更便携的方法,并添加一个返回大小的虚函数,或者使用运行时类型信息来获得正确的类型然后返回大小。
(如果您投票或添加评论,我将开始装饰答案)