C++ 虚拟继承(virtual Inheritance)

前言

关于继承有一个总结如下

Accesspublicprotectedprivate
Same class objyesyesyes
Derived classesyesyesno
Outside classesyesnono

三级继承如何访问最上一级

我们都知道继承后的class对象内部其实有关于父类成员所有信息,只不过父类放置于public的成员子类可以访问protected的成员子类也可以访问,但是放置于private的成员子类不可以访问
那么我们如何通过第三级class对象访问爷爷class呢?如下面代码

#include <iostream>

class Base{

public:
    int base_value = 12;
};

class intermediate1 : public Base{

public:
    int i = 1;

};

class intermediate2 : public Base{

public:
    int i = 2;

};

class Derive : public intermediate1, intermediate2{


};

int main(){
    Derive d;
    std::cout << d.intermediate1::i << '\n'; 
}

上图中孙子class对象Derive,可以通过d.intermediate1::i去访问父类的public成员,同理因为可以通过父类访问父类成员,那么也可以通过父类访问父类的父类成员,也就是derive的爷爷class,这样访问d.intermediate1::base_value,不过我们要注意base_valueintermediate1intermediate2各有一份副本,所以我们对d.intermediate1::base_value做操作不会影响到d.intermediate2::base_value

虚拟继承

首先要明确的是虚拟继承和虚函数没有关系,还是上述的例子,假设我们想要class intermediate1和class intermediate2共享继承成员变量base_value,也就是说改动intermediate1::base_value相当于改动intermediate2::base_value那么我们可以使用virtual inheritance让class intermediate1和class intermediate2虚拟继承base,此时class intermediate1和class intermediate2通过虚拟继承而来的base的public或者protected的成员变得共享,如下所示

#include <iostream>

class Base{

public:
    int base_value = 12;
};

class intermediate1 : public virtual Base{

public:
    int i = 1;

};

class intermediate2 : public virtual Base{

public:
    int i = 2;

};

class Derive : public intermediate1, intermediate2{


};

int main(){
    Derive d;
    ++d.intermediate1::base_value;
    ++d.intermediate1::base_value;

    std::cout << d.intermediate1::base_value << '\n'; 
}

C++ 中的虚拟继承virtual inheritance)是一种特殊的继承方式,它可以解决多重继承中的“菱形继承”问题。 “菱形继承”是指在多重继承中,如果派生类继承了两个或多个基类,而这些基类都继承自同一个基类,那么派生类就会包含多个相同的基类子对象,这就导致了访问这些子对象时的二义性。 例如: ``` class A { ... }; class B : public A { ... }; class C : public A { ... }; class D : public B, public C { ... }; ``` 在这个例子中,D 类继承了 B 和 C 两个类,而 B 和 C 类都继承了 A 类,因此 D 类会包含两个 A 类的子对象,从而导致访问 A 类成员时的二义性。 为了解决这个问题,可以使用虚拟继承虚拟继承可以让共同基类在派生类中只出现一次,从而避免重复继承的问题。 例如: ``` class A { ... }; class B : virtual public A { ... }; class C : virtual public A { ... }; class D : public B, public C { ... }; ``` 在这个例子中,B 和 C 类都使用了 virtual 关键字来继承 A 类,从而避免了重复继承的问题。此时,D 类中只包含一个 A 类的子对象。 虚拟继承需要注意以下几点: 1. 虚拟继承只能用于直接继承自虚基类的派生类中。 2. 虚基类必须在最终派生类中被构造。 3. 虚基类的构造顺序是在最终派生类的构造函数中以其出现的顺序进行的。 4. 虚基类的析构顺序是与构造顺序相反的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值