求助sizeof类,多重继承,混合继承

本文详细解析了C++中多重继承类的sizeof计算过程,通过具体实例展示了如何计算不同类的大小,包括类成员、虚继承和虚函数表的影响。深入理解sizeof在C++中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)下面的程序的输出结果为什么是 19,18?

class R{};
class Ir1:public R{public:char r1[16];};
class Ir2:public R{};
class Ir3:public R{};
class Ir4:public R{};


class C1{char c1[16];};
class C2{};
class C3{};
class C4{};
class Ir:public Ir1,public Ir2,public Ir3,public Ir4
{
};
class Ic:public C1,public C2,public C3,public C4
{
};
void main()
{
 Ir ir;
 cout<<endl<<"sizeof(ir):"<<sizeof(ir)<<" ,sizeof(Ir)"<<sizeof(Ir)<<endl;//输出19 ,sizeof(Ir)=sizeof(Ir1)+sizeof(Ir2)+sizeof(Ir3)+sizeof(Ir4)=16+1+1+1=19

 Ic ic;
 cout<<endl<<"sizeof(ic):"<<sizeof(ic)<<" ,sizeof(Ic)"<<sizeof(Ic)<<endl;//输出18,sizeof(Ic)=sizeof(C1)+sizeof(C2)+sizeof(C3)+sizeof(C4)=16+1+1+1=19, 为什么输出是18

                                                                                                                                                  //呢?不理解

(2)多重继承的类sizeof怎么计算?

class A {
 int a;               //占4个字节
 virtual ~A(){}  //有一个虚指针4字节
};//8

class B:virtual public A{//虚继承指向父类的指针,4字节

 virtual void myfunB(){}; //定义了新的虚函数,B类需新建一个虚函数表,需要一个虚函数表指针,4字节

};//16

class C:virtual public A{//虚继承指向父类的指针,4字节

 virtual void myfunC(){}//定义了新的虚函数,C类需新建一个虚函数表,需要一个虚函数表指针,4字节

};//16

class D0: public  B,public virtual C{// 虚继承,有一个指向父类的指针,4字节

 virtual void myfunD(){} //  定义了新的虚函数,但是非虚继承了B,B中已经有了虚函数表,所以直接放入B的虚函数表即可,不需要额外的空间

};//28  24

void main()
{
  cout<<sizeof(D0)<<endl;
}

我想的是sizeof(D0)=sizeof(B)+sizeof(C)+4字节(虚继承指向父类的指针)-sizeof(A)(因为B,C有公共的虚基类要减去重复的)=16+16+4-8=28,可是为什么我用vs2010得到的结果是 24呢?

### C++多重继承中元素的确定方式 在C++中,多重继承是一种强大的特性,但也带来了复杂的内存布局和元素访问机制。以下是关于如何在多重继承情况下确定元素的具体方法: #### 1. **名称查找规则** 当一个派生从多个基继承时,编译器会按照一定的顺序来解析成员名。如果某个成员名存在于多个基中,则会发生歧义问题。为了避免这种情况,通常需要显式指定作用域。 例如,在以下代码中: ```cpp class Base1 { public: void func() { cout << "Base1::func()" << endl; } }; class Base2 { public: void func() { cout << "Base2::func()" << endl; } }; class Derived : public Base1, public Base2 {}; int main() { Derived d; d.func(); // 错误:存在歧义 } ``` 在这种情况下,可以通过显式指定作用域解决歧义问题: ```cpp d.Base1::func(); d.Base2::func(); ``` 这种行为遵循了C++标准中的名称查找规则[^1]。 --- #### 2. **虚继承下的元素定位** 在涉及虚继承的情况下,由于引入了虚基表(VBT),元素的位置不再固定,而是通过动态计算得出。这主要体现在以下几个方面: - **虚基指针的作用** 当一个使用虚继承时,该会在内部维护一个指向虚基的指针。这个指针用于调整偏移量,以便正确访问共享的虚基实例。 - **运行时地址计算** 在虚继承结构中,派生对象的实际布局可能因不同平台或编译器而异。然而,基本原理保持一致:通过虚基表找到正确的偏移量并完成访问。 考虑如下例子: ```cpp #include <iostream> using namespace std; class A { public: int a; }; class B : virtual public A {}; class C : virtual public A {}; class D : public B, public C {}; int main() { D obj; cout << "&obj.a: " << &obj.a << endl; // 动态计算得到实际位置 return 0; } ``` 在此示例中,`D` 的对象包含了两个虚基指针分别对应 `B` 和 `C` 的虚基部分。因此,即使 `A` 是间接继承而来,也能唯一确定其成员 `a` 的位置[^3]。 --- #### 3. **内存布局的影响因素** 为了更清楚地理解多重继承下元素的确切位置,还需要关注以下几点: - **非虚继承的情况** 如果不存在虚继承,那么子的内存布局通常是按声明顺序依次排列各个父的内容。例如: ```cpp class Parent1 { int p1; }; class Parent2 { int p2; }; class Child : public Parent1, public Parent2 {}; // 布局为 [Parent1][Parent2] int main() { cout << sizeof(Child); // 输出等于 sizeof(Parent1) + sizeof(Parent2) } ``` - **虚继承的存在** 若某一层级中有虚继承,则需额外分配空间存储虚基指针。这些指针的数量取决于有多少条路径通向同一个虚基[^4]。 --- #### 4. **总结** 综上所述,C++ 中多重继承的元素确定依赖于静态型信息以及潜在的运行时支持(如虚继承)。对于简单情况可以直接依据定义次序推断;而对于复杂情形则应借助工具观察具体实现细节[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值