------------------siwuxie095
多繼承 和 多重繼承,兩個詞差別不大,但是差之毫厘、謬以千里 …
多重繼承
如果有這樣三個類:人類、士兵類、步兵類,其中:士兵類繼承了人類,
步兵類繼承了士兵類,這三個類之間的關系稱之為 多重繼承

如果在繼承時,這三個類都使用了 public 公有繼承,那么它們也
存在着以下的關系:
士兵是一個人,步兵是一個士兵,步兵也是一個人

具體到代碼上,可以這樣來寫:

多繼承
如果有一個類,不僅繼承了工人類,還繼承了農民類,暫且把這個類
稱之為 農民工類
即 一個子類同時有兩個父類,或 一個派生類同時有兩個基類,這樣的
關系稱之為 多繼承

多繼承和多重繼承是完全不同的,在多繼承的關系下,如果農民工類
在繼承工人類和農民類時,都以 public 公有繼承的方式繼承,那么
它們還存在着這樣一種關系:
農民工是一個工人,農民工是一個農民,但工人和農民本身是平行的

具體到代碼上,可以這樣來寫:

注意:寫法上,中間要加逗號隔開,在繼承每一個類時,都要將繼承
方式寫出來,如果不寫,系統默認繼承方式為 private 私有繼承
程序 1:多重繼承
Person.h:
| #include <string> using namespace std;
class Person { public: Person(string name = "Jim"); ~Person(); void play(); protected: string m_strName; }; |
Person.cpp:
| #include "Person.h" #include <iostream> using namespace std;
Person::Person(string name) { m_strName = name; cout << "Person()" << endl; }
Person::~Person() { cout << "~Person()" << endl; }
void Person::play() { cout << "Person--play()" << endl; cout << m_strName << endl; } |
Soldier.h:
| #include "Person.h" class Soldier:public Person { public: Soldier(string name = "James", int age = 20); ~Soldier(); void work(); protected: int m_iAge; }; |
Soldier.cpp:
| #include "Soldier.h" #include <iostream> using namespace std;
Soldier::Soldier(string name, int age) { m_strName = name; m_iAge = age; cout << "Soldier()" << endl; }
Soldier::~Soldier() { cout << "~Soldier()" << endl; }
void Soldier::work() { cout << "Soldier--work()" << endl; cout << m_strName << "," << m_iAge << endl; } |
Infantry.h:
| #include "Soldier.h"
class Infantry:public Soldier { public: Infantry(string name = "Jack", int age = 30); ~Infantry(); void attack();
}; |
Infantry.cpp:
| #include "Infantry.h" #include <iostream> using namespace std;
Infantry::Infantry(string name, int age) { m_strName = name; m_iAge = age; cout << "Ifantry()" << endl; }
Infantry::~Infantry() { cout << "~Infantry()" << endl; }
void Infantry::attack() { cout << "Infantry--attack()" << endl; cout <<m_strName << "," << m_iAge << endl; } |
main.cpp:
| #include <stdlib.h> #include "Infantry.h" #include <iostream> using namespace std;
void test1(Person p) { p.play(); }
void test2(Person &p) { p.play(); }
void test3(Person *p) { p->play(); }
//無論繼承的層級有多少,只要保持着直接或間接的繼承關系, //子類都可以與自己的直接父類或間接父類稱為 is-a 關系 //並且能夠通過指針對直接子類或間接子類的對象進行相應的操作 int main(void) { Infantry infantry; cout << endl;
infantry.play(); infantry.work(); infantry.attack(); cout << endl;
test1(infantry); cout << endl; test2(infantry); cout << endl; test3(&infantry); system("pause"); return 0; } |
運行一覽:

程序 2:多繼承
Farmer.h:
| #include <string> using namespace std;
class Farmer { public: Farmer(string name = "Jack"); virtual ~Farmer();//虛析構函數 void sow(); protected: string m_strName; }; |
Farmer.cpp:
| #include "Farmer.h" #include <iostream> using namespace std;
Farmer::Farmer(string name) { m_strName = name; cout << "Farmer()" << endl; }
Farmer::~Farmer() { cout << "~Farmer()" << endl; }
void Farmer::sow() { cout << "Farmer--sow()" << endl; cout << m_strName << endl; } |
Worker.h:
| #include <string> using namespace std;
class Worker { public: Worker(string code = "001"); virtual ~Worker();//虛析構函數 void work(); protected: string m_strCode; }; |
Worker.cpp:
| #include "Worker.h" #include <iostream> using namespace std;
Worker::Worker(string code) { m_strCode = code; cout << "Worker()" << endl; }
Worker::~Worker() { cout << "~Worker()" << endl; }
void Worker::work() { cout << "Worker--work()" << endl; cout << m_strCode << endl; } |
MigrantWorker.h:
| #include "Farmer.h" #include "Worker.h"
class MigrantWorker :public Farmer, public Worker { public: MigrantWorker(string name, string code); virtual ~MigrantWorker(); }; |
MigrantWorker.cpp:
| #include "MigrantWorker.h" #include <iostream> using namespace std;
//使用初始化列表初始化 MigrantWorker::MigrantWorker(string name, string code) :Farmer(name), Worker(code) { cout << "MigrantWorker()" << endl; }
MigrantWorker::~MigrantWorker() { cout << "~MigrantWorker()" << endl; } |
main.cpp:
| #include <stdlib.h> #include "MigrantWorker.h" #include <iostream> using namespace std;
int main(void) { //從堆中實例化子類對象,先調用父類構造函數再調用子類構造函數 //調用父類構造函數的順序和初始化列表中的順序一樣 //析構函數的調用順序則相反 MigrantWorker *p = new MigrantWorker("Merry", "100"); cout << endl; p->sow(); p->work(); cout << endl; delete p; p = NULL; system("pause"); return 0; } |
運行一覽:

【made by siwuxie095】
