C++多继承(多重继承)详解
在前面的例子中,派生类都只有一个基类,称为单继承(Single Inheritance)。除此之外,C++也支持多继承(Multiple Inheritance),即一个派生类可以有两个或多个基类。
下面是一个多继承的实例:
BaseA constructor
BaseB constructor
Derived constructor
1, 2, 3, 4, 5
Derived destructor
BaseB destructor
BaseA destructor
从运行结果中还可以发现,多继承形式下析构函数的执行顺序和构造函数的执行顺序相反。
修改上面的代码,为 BaseA 和 BaseB 类添加 show() 函数,并将 Derived 类的 show() 函数更名为 display():
多继承容易让代码逻辑复杂、思路混乱,一直备受争议,中小型项目中较少使用,后来的 Java、C#、PHP 等干脆取消了多继承。多继承的语法也很简单,将多个基类用逗号隔开即可。例如已声明了类A、类B和类C,那么可以这样来声明派生类D:
class D: public A, private B, protected C{
//类D新增加的成员
}
多继承下的构造函数
多继承形式下的构造函数和单继承形式基本相同,只是要在派生类的构造函数中调用多个基类的构造函数。以上面的 A、B、C、D 类为例,D 类构造函数的写法为:
D(形参列表): A(实参列表), B(实参列表), C(实参列表){
//其他操作
}
D(形参列表): B(实参列表), C(实参列表), A(实参列表){
//其他操作
}
下面是一个多继承的实例:
#include <iostream> using namespace std; //基类 class BaseA{ public: BaseA(int a, int b); ~BaseA(); protected: int m_a; int m_b; }; BaseA::BaseA(int a, int b): m_a(a), m_b(b){ cout<<"BaseA constructor"<<endl; } BaseA::~BaseA(){ cout<<"BaseA destructor"<<endl; } //基类 class BaseB{ public: BaseB(int c, int d); ~BaseB(); protected: int m_c; int m_d; }; BaseB::BaseB(int c, int d): m_c(c), m_d(d){ cout<<"BaseB constructor"<<endl; } BaseB::~BaseB(){ cout<<"BaseB destructor"<<endl; } //派生类 class Derived: public BaseA, public BaseB{ public: Derived(int a, int b, int c, int d, int e); ~Derived(); public: void show(); private: int m_e; }; Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){ cout<<"Derived constructor"<<endl; } Derived::~Derived(){ cout<<"Derived destructor"<<endl; } void Derived::show(){ cout<<m_a<<", "<<m_b<<", "<<m_c<<", "<<m_d<<", "<<m_e<<endl; } int main(){ Derived obj(1, 2, 3, 4, 5); obj.show(); return 0; }运行结果:
BaseA constructor
BaseB constructor
Derived constructor
1, 2, 3, 4, 5
Derived destructor
BaseB destructor
BaseA destructor
从运行结果中还可以发现,多继承形式下析构函数的执行顺序和构造函数的执行顺序相反。
命名冲突
当两个或多个基类中有同名的成员时,如果直接访问该成员,就会产生命名冲突,编译器不知道使用哪个基类的成员。这个时候需要在成员名字前面加上类名和域解析符::
,以显式地指明到底使用哪个类的成员,消除二义性。修改上面的代码,为 BaseA 和 BaseB 类添加 show() 函数,并将 Derived 类的 show() 函数更名为 display():
#include <iostream> using namespace std; //基类 class BaseA{ public: BaseA(int a, int b); ~BaseA(); public: void show(); protected: int m_a; int m_b; }; BaseA::BaseA(int a, int b): m_a(a), m_b(b){ cout<<"BaseA constructor"<<endl; } BaseA::~BaseA(){ cout<<"BaseA destructor"<<endl; } void BaseA::show(){ cout<<"m_a = "<<m_a<<endl; cout<<"m_b = "<<m_b<<endl; } //基类 class BaseB{ public: BaseB(int c, int d); ~BaseB(); void show(); protected: int m_c; int m_d; }; BaseB::BaseB(int c, int d): m_c(c), m_d(d){ cout<<"BaseB constructor"<<endl; } BaseB::~BaseB(){ cout<<"BaseB destructor"<<endl; } void BaseB::show(){ cout<<"m_c = "<<m_c<<endl; cout<<"m_d = "<<m_d<<endl; } //派生类 class Derived: public BaseA, public BaseB{ public: Derived(int a, int b, int c, int d, int e); ~Derived(); public: void display(); private: int m_e; }; Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){ cout<<"Derived constructor"<<endl; } Derived::~Derived(){ cout<<"Derived destructor"<<endl; } void Derived::display(){ BaseA::show(); //调用BaseA类的show()函数 BaseB::show(); //调用BaseB类的show()函数 cout<<"m_e = "<<m_e<<endl; } int main(){ Derived obj(1, 2, 3, 4, 5); obj.display(); return 0; }请读者注意第 64、65 行代码,我们显式的指明了要调用哪个基类的 show() 函数。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算