一、概念
多重繼承:當B類從A類派生,C類從B類派生,此時稱爲多重繼承
多繼承:多繼承是指一個子類繼承多個父類。多繼承對父類的個數沒有限制,繼承方式可以是公共繼承、保護繼承和私有繼承。若不寫繼承方式,默認是private繼承。
二、代碼演示
多重繼承
#include<iostream>
#include<string>
using namespace std;
/*多重繼承:
1.Person類,數據成員:m_strName 成員函數:構造、析構、pay()
2.Soldier類,數據成員:m_iAge 成員函數:構造、析構、work()
3.Infantry類,數據成員:無 成員函數:構造、析構、attack()
4.定義函數test1(Person p) test2(Person &p) test3(Person *p)
*/
//虛析構函數 當存在繼承關係的時候,使用父類的指針去指向堆中的子類的對象
//並且還需要父類的指針去釋放這塊內存的時候就需要虛析構函數
class Person
{
public:
Person(string name = "v")
{
m_strName = name;
cout<<"Person()"<<endl;
}
virtual ~Person()
{
cout<<"~Person()"<<endl;
}
void play()
{
cout<<"Person--play()"<<endl;
cout<<m_strName<<endl;
}
protected:
string m_strName;
};
class Soldier:public Person
{
public:
Soldier(string name = "wls",int age = 20)
{
m_strName = name;
m_iAge = age;
cout<<"Soldier"<<endl;
}
virtual ~Soldier()
{
cout<<"~Soldier"<<endl;
}
void work()
{
cout<<m_strName<<endl;
cout<<m_iAge<<endl;
cout<<"Soldier--work()"<<endl;
}
protected:
int m_iAge;
};
class Infantry:public Soldier
{
public:
Infantry(string name = "Jack",int age = 30)
{
m_strName = name;
m_iAge = age;
cout<<"Infantry()"<<endl;
}
~Infantry()
{
cout<<"~Infantry()"<<endl;
}
void attack()
{
cout<<m_strName<<endl;
cout<<m_iAge<<endl;
cout<<"Soldier--work()"<<endl;
}
};
void test1(Person p)//參數是對象p,傳值的時候先實例化一個臨時對象p,所以執行完後要銷燬
{
p.play();
}
void test2(Person &p)//使用基類的引用也可以接收基類的對象和派生類的對象
{
p.play();
}
void test3(Person *p)//參數是一個基類的指針
{
p->play();
}
int main(void)
{
Infantry infantry;
test1(infantry);
test2(infantry);
test3(&infantry);
/***********************************************************
無論繼承的層級有多少層,他們只要保持着直接或者間接的繼承關係,
那麼子類都可以與自己的直接父類或者間接父類稱之爲“is a”的關係,
並且能通過父類的指針對直接子類或者間接子類的對象進行相應的操作
************************************************************/
return 0;
}
運行結果:
(1)當實例化子類時,會首先依次調用所有基類的構造函數,最後調用該子類的構造函數;銷燬該子類時,則相反,先調用該子類的析構函數,再依次調用所有基類的析構函數。
(2)無論繼承的層級有多少層,只要它們保持着直接或間接的繼承關係,那麼子類都可以與其直接父類或間接父類構成 is a的關係,並且能夠通過父類的指針對直接子類或間接子類進行相應的操作。
多繼承
#include<iostream>
#include<string>
using namespace std;
/*
多繼承
1.Famer類,數據成員:m_strName,成員函數:構造、析構、sow()
2.Worker類,數據成員:m_strCode,成員函數:構造、析構、carry()
3.MigrantWorker類,數據成員:無,成員函數:構造、析構
*/
class Farmer
{
public:
Farmer(string name)
{
m_strName = name;
cout<<"Farmer()"<<endl;
}
~Farmer()
{
cout<<"~Farmer()"<<endl;
}
void sow()
{
cout<<m_strName<<endl;
cout<<"Farmer--sow()"<<endl;
}
protected:
string m_strName;
};
class Worker
{
public:
Worker(string code)
{
m_strCode = code;
cout<<"Worker()"<<endl;
}
~Worker()
{
cout<<"~Worker()"<<endl;
}
void carry()
{
cout<<m_strCode<<endl;
cout<<"Worker--carry()"<<endl;
}
protected:
string m_strCode;
};
class MigrantWorker:public Farmer,public Worker//多繼承
{
public:
MigrantWorker(string name,string code):Farmer(name),Worker(code)//多繼承
{
cout<<"MigrantWorker()"<<endl;
}
~MigrantWorker()
{
cout<<"~MigrantWorker()"<<endl;
}
};
int main(void)
{
MigrantWorker *p = new MigrantWorker("Merry","100");
p->sow();
p->carry();
delete p;
p = NULL;
return 0;
}
運行結果:
由輸出結果可以看出,在多繼承中,子類可以調用多個父類的成員函數,在實例化子類時,先根據繼承的順序依次調用父類的構造函數,然後再調用該子類自己的構造函數。