C++之多继承

普通的继承中,子类的虚表是从父类拷贝过来的,子类新增加的特有的虚函数,会添加在这个虚表里。参考文章:优快云

多继承

问:如果A1、A2中有相同的虚函数,覆盖谁的?

答案:覆盖A1的

多继承还存在一种特殊情况——菱形继承:即此时A1、A2有一个公共的父类。

菱形继承(钻石继承)

继承向上的二义性:

例:Base类中有属性m,我们在Base1的构造函数中将m的值改成2, 在Base2的构造函数中将m的值改成3,那么当Derived中想使用m时,我们取2还是取3?答案是不知道的,在程序中这种情况也是通过不了编译的。为了解决多继承中的菱形继承问题,下面介绍虚继承来解决这一问题。

虚继承

目的:主要解决多继承中的菱形继承问题

class A
{
public:
    virtual void vfun(){}
};
class B:virtual public A
{
public:
    virtual void vfun1(){}
};//B包含两个虚表

虚继承特性:

  • 父类和子类在空间上一种倒置关系(与普通继承相比)
  • 当子类有特有的虚函数时,会有自己的虚表,就会有自己的虚指针
  • 子类存在指向虚基类(虚继承里面的基类)的虚基表,子类会有虚基表的指针vbptr,它指向这个虚基表,虚基表里面的内容是指向自己及虚基类的地址偏移量
  • 对于虚基类的初始化由最底层的派生类负责

虚继承解决菱形继承问题方案

1.先虚继承,再多继承 

2.先虚继承,再虚多继承 

重点掌握虚继承特性所占内存空间大小

#include<iostream>
using namespace std;

class Base
{
public:Base(int i) { cout << "B()" << " "; }
	  virtual void vfun() {}
	  int a;
};
class Base1:virtual public Base
{
public:Base1(int i): Base(i) { cout << "B1()" << " "; }
	  virtual void vfun1() {}
	  int b;
};
class Base2 :virtual public Base
{
public:Base2(int i) : Base(i) { cout << "B2()" << " "; }
	  virtual void vfun2() {}
	  int c;
};
//1.先虚继承,再多继承
class Derived1 :public Base1, public Base2
{
public:
	Derived1(int i) :Base1(i), Base2(i), Base(i) { cout << "D1()" << " "; }
	virtual void vfun3() {}
	int d;
};
//2.先虚继承,再虚多继承
class Derived2 :virtual public Base1, virtual public Base2
{
public:
	Derived2(int i) :Base1(i), Base2(i), Base(i) { cout << "D2()" << " "; }
	virtual void vfun4() {}
	int e;
};
int main()
{
	//测试所占内存大小
	Derived1 d1(1);
	cout << sizeof(d1) << endl;//B() B1() B2() D1() 36

	Derived2 d2(1);
	cout << sizeof(d2) << endl;//B() B1() B2() D2() 44

	return 0;
}

如有问题,欢迎交流指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值