C++多重继承

多重继承(Multiple Inheritance)描述的是有多个直接基类的类。比如公有MI表示的也是is-a的关系。
例如,可以重类B和类C派生出类D:

class D :public B, public C
{
	...
};

多重继承存在两个问题:

  • 从两个不同的基类继承同名方法(B、C中有同名的方法怎么处理);
  • 从两个或者更多相关基类那里继承同一个类的多个实例(类B 和类C都是从类A派生出来的,这样D将有两个A的实例);

示例:

#include<iostream>
using namespace std;

class A
{
private :
	int a;
public:
	A() :a(0) {}
	A(int n) :a(n) {}
	virtual ~A() {};
	virtual void set() { std::cin >> a; }
	virtual void show()const { cout << " A:" << a << endl; }
	virtual void other() = 0;//纯虚函数-----A是抽象基类
};
class B: virtual public A
{
private:
	int b;
public:
	B() :A(0), b(0) {};
	B(int m, int n = 0) :A(m), b(n) {}
	virtual ~B() {}
	virtual void set() { std::cin >> b; }
	virtual void show() const{ cout << " B:" << b << endl; }
	virtual void other() { cout << "B other" << endl; }
};
class C : virtual public A
{
private:
	int c;
public:
	C() :A(0), c(0) {};
	C(int m, int n = 0) :A(m), c(n) {};
	virtual ~C() {};
	virtual void set() { std::cin >> c; }
	virtual void show()const { cout << " C:" << c << endl; }
	virtual void other() { cout << "C other" << endl; }
};

class D :public B, public C
{
private:
	int d;	
public:
	D():A(0),B(0,0),C(0,0),d(0) {}
	D(int m, int n, int x, int y):A(m), B(m, n), C(m, x), d(y) {}
	virtual ~D() {}
	virtual void set() 
	{ 
		A::set();
		B::set();
		C::set();
		std::cin >> d; 
	}
	virtual void show()const 
	{ 
		A::show();
		B::show();
		C::show();
		cout << " D: "<<d << endl; 
	}
	virtual void other() { cout << "D other" << endl; }
};
void main()
{
	cout << "Multiple Inheritance" << endl;
	A *p1 = new D(1, 2, 3, 4);
	p1->show();
	p1->set();
	p1->show();
	delete p1;
	D dd(1, 2, 3, 4);
	dd.B::show();
}

关于虚基类:
虚基类使得从多个类(他们的基类相同)派生出的对象只继承一个基类。虚继承的提出是为了解决多重继承时,可能会保存两份副本的问题,也就是说用了虚继承就只保留了一份副本,但是这个副本是被多重继承的基类所共享的。

class B: virtual public A{...}
class C : virtual public A{...}
class D :public B, public C{...}

通过虚基类,D中将不会存在两个A对象,即D继承的B和C对象共享一个A对象。这时候就可以使用多态了,基类A的指针可以指向派生类D对象。
注:虚函数和虚基类之间不存在明显的联系,这里使用了virtual-有点像关键字重载。

新的构造函数规则:
C++在基类是虚的时候,禁止信息通过中间类自动传递给给基类。必须显式调用基类的构造函数:

	D(int m, int n, int x, int y):A(m), B(m, n), C(m, x), d(y) {}

关于使用哪个方法:
通过作用域解析运算符进行区分。

关于对象内存大小:

cout << sizeof(A) << endl;//8
cout << sizeof(B) << endl;//20
cout << sizeof(C) << endl;//20
cout << sizeof(D) << endl;//32

sizeof(A)=整型变量a(4字节)+一个虚表指针(4字节)
=8字节。

sizeof(B)=整型变量b(4字节)+一个虚表指针(4字节)
+类A中的整型变量a(4字节)+类A虚表指针(4字节)
+指向A的虚基类指针(4字节)
=20字节

sizeof(C )=整型变量c(4字节)+一个虚表指针(4字节)
+类A中的整型变量a(4字节)+类A虚表指针(4字节)+
指向A的虚基类指针(4字节)
=20字节

sizeof(D)=整型变量d(4字节)+一个虚表指针(4字节)
+类B中的整型变量b(4字节)+类B虚表指针(4字节)
+类C中的整型变量C(4字节)+类C虚表指针(4字节)
+共享类A中的整型变量a(4字节)+指向A的虚基类指针(4字节)
=32字节

参考:https://blog.youkuaiyun.com/sunshinewave/article/details/51079204
https://blog.youkuaiyun.com/m0_38014304/article/details/84286266
https://blog.youkuaiyun.com/Neo_dot/article/details/80725800

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值