多重继承(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