关于c++中的virtual继承的总结

本文探讨了C++中虚拟继承的作用,特别是在解决多重继承时的冲突问题。虚拟继承通过引入虚拟基类指针,避免了钻石继承带来的数据冗余,但同时也带来了额外的空间开销和运行时的寻址时间。通过示例展示了虚拟继承如何影响对象大小,并解释了影响对象大小的因素,包括语言特性、编译器优化和对齐约束。

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

1.在什么时候需要虚拟继承呢?

虚拟继承是多重继承特有的概念。虚拟基类是为了解决多重继承而出现的。例如A继承了Y,Z。而Y,Z继承自X,因此A两次出现了类x中的变量和函数,可以将Y,Z定义为虚拟继承。而x则变成了虚拟继承的基类


class X{ };

class Y: public virtual X{ };

class Z: public virtual X{ };

class A :public Y, public Z{ };

上述的X,Y,Z,A中都没有任何一个class中含有明显的数据,只表明了之间的继承关系。所以认为每个的大小都为0?当然不对。即使是class X的大小也不为0;


#include<iostream>
using namespace std;
class A{


};


class B:public virtual A{


};


class C: public virtual A{


};


class D:public B,public C{


};


int main()
{
int a , b , c , d;


a = sizeof(A);
b = sizeof(B);
c = sizeof(C);
d

### 虚拟继承的概念 在C++中,当多个派生类从同一个基类继承时,如果这些派生类又共同被另一个类所继承,则可能会导致重复的基类成员。为了避免这种冗余并解决二义性问题,可以使用虚拟继承。 通过声明`class Derived : virtual public Base {}`的方式定义虚基类[^1]。编译器会为此创建特殊的机制来管理唯一的基类实例,通常涉及额外指针和更复杂的对象布局。 #### 使用场景 考虑如下情况: - 类A是一个普通的基类; - B和C都公有继承自A; - D同时继承B和C; 如果不采用虚拟方式,在D的对象模型里就会存在两个独立的A子对象副本。这不仅浪费空间还可能引发逻辑错误。因此应当让B和C以virtual形式继承于A。 ```cpp // 定义一个普通基类 A class A { public: void show() { cout << "Class A"; } }; // 让 B 和 C 都以虚拟方式继承自 A class B : virtual public A {}; class C : virtual public A {}; // 继承自 B 和 C 的 D 只有一个 A 子对象 class D : public B, public C {}; ``` 上述代码片段展示了如何利用关键字 `virtual` 来指定特定类型的继承关系。这样做之后,即使是从多条路径间接获得相同的直接父级,最终也只会共享同一份基础数据结构。 为了更好地理解这一点,下面给出一段完整的程序示例说明了带有纯虚函数接口的情况以及它们是如何与虚拟继承一起工作的。 ```cpp #include <iostream> using namespace std; // 抽象产品角色 Product 接口 class IProduct { public: // 声明为纯虚函数使得这个成为抽象类 virtual string getName() const = 0; protected: ~IProduct() {} }; // 实现具体的产品 ConcreteProductA class ConcreteProductA : virtual public IProduct { private: static constexpr char* name_ = "ConcreteProductA"; public: string getName() const override { return name_; } }; int main(){ auto p = new ConcreteProductA(); cout<<p->getName()<<endl; // 输出: ConcreteProductA delete p; } ``` 在这个例子中可以看到,`ConcreteProductA` 是作为 `IProduct` 的一种具体化而存在的,并且是以虚拟方式实现了该接口。这意味着任何进一步衍生出来的类型都将只保留单一版本的基础行为描述[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值