本篇主要介绍多重继承,在C++中不是特别常用。
如果想要一个类同时具有多个类的属性,有两种方法可以选择:一个是多重继承
,一个是组合
,但由于继承可能导致一些问题(下篇将会介绍,特别是在菱形继承时),因此较为推荐的是组合的方法实现。
总结:
1.多重继承的定义及使用: 一个类可以同时继承多个类,使得同时具有多个类的属性;
2.多重继承构造和析构的顺序: 多重继承父类和子类的构造与析构顺序,也是与前面父子类的构造析构顺序一致,先构造父类,再析构子类,先析构子类,再析构父类,但是与继承声明的顺序相关;
3.多重继承的指针转换问题: 子类对象转为父类指针的方式可以将子类属性分别指向父类的对应部分;
4.组合的方式: 利用类中包含多个成员对象,从而达到包含多个类的属性的目的
。
1. 多重继承的定义及使用
C++中有一种方式叫做多重继承,一个类可以同时继承多个类,即有多个父类。
在以下代码中已经有了一个CSofa
沙发类和CBed
床类,如果想要在创建一个沙发床类,使其既有沙发的特点又有床的特点。可以通过class CSofaBed :public CSofa, public CBed
使得CSofaBed
有两个父类,也就使得CSofaBed
的对象既可以Sleep()
又可以Sit()
。
#include <iostream>
class CSofa
{
public:
CSofa() {
m_Length = 1;
printf("CSofa()\r\n");
}
~CSofa() {
printf("~CSofa()\r\n");
}
void Sit() {
printf("sit\r\n");
}
public:
int m_Length;
};
class CBed
{
public:
CBed() {
m_Height = 2;
printf("CBed()\r\n");
}
~CBed() {
printf("~CBed()\r\n");
}
void Sleep() {
printf("Sleep\r\n");
}
public:
int m_Height;
};
//某一个类既有沙发又有床的特点
//多重继承
class CSofaBed :public CSofa, public CBed
{
public:
CSofaBed() {
printf("CSofaBed()\r\n");
}
~CSofaBed() {
printf("~CSofaBed()\r\n");
}
};
int main(int argc, char* argv[])
{
//创建沙发床对象
CSofaBed sbObj;
sbObj.Sleep();
sbObj.Sit();
return 0;
}
2. 多重继承构造和析构的顺序
多重继承父类和子类的构造与析构顺序,也是与前面父子类的构造析构顺序一致,先构造父类,再析构子类,先析构子类,再析构父类,但是与继承声明的顺序相关。
上面代码的运行结果如下:class CSofaBed :public CSofa, public CBed
先声明了CSofa
就先构造
3. 多重继承的指针转换问题
多重继承中常常会遇到指针转换的问题,由于子类继承自多个父类,因此 不需要强转就可以转换为多种父类形式。
#include <iostream>
class CSofa
{
public:
CSofa() {
m_Length = 1;
printf("CSofa()\r\n");
}
~CSofa() {
printf("~CSofa()\r\n");
}
void Sit() {
printf("sit\r\n");
}
public:
int m_Length;
};
class CBed
{
public:
CBed() {
m_Height = 2;
printf("CBed()\r\n");
}
~CBed() {
printf("~CBed()\r\n");
}
void Sleep() {
printf("Sleep\r\n");
}
public:
int m_Height;
};
//某一个类既有沙发又有床的特点
//多重继承
class CSofaBed :public CSofa, public CBed
{
public:
CSofaBed() {
printf("CSofaBed()\r\n");
}
~CSofaBed() {
printf("~CSofaBed()\r\n");
}
};
int main(int argc, char* argv[])
{
//创建沙发床对象
CSofaBed sbObj;
//指针转换,子类对象转为父类指针
CSofa* pSofa = &sbObj;
CBed* pBed = &sbObj;
return 0;
}
运行结果:
为什么两个指针都是从沙发床对象sbObj上取地址,而最后结果不一样呢?
这是因为和内存的布局有关,指针在转换时会隐藏的指向父类对应的部分,从而使得 子类对象转为父类指针的方式可以将子类属性分别指向父类的对应部分
。
以上代码中,子类有8个字节大小,而转换的父类指针中有其对应的成员变量,只有4个字节大小。
4. 继承与组合
组合的方式:
利用类中包含多个成员对象,从而达到包含多个类的属性的目的
。
继承就是子类从父类继承东西下来,除了上面多重继承的方式,我们还可以通过组合的方式来实现沙发床。代码如下:
//使用组合
class CSofaBed2
{
public:
private:
CSofa m_sofa;
CBed m_bed;
};
5.学习视频地址:C++57个入门知识点_49 多重继承与组合