#include<iostream>
using namespace std;
//基類People
class People{
protected:
char *m_name;
int m_age;
public:
People(char*, int);
};
People::People(char *name, int age): m_name(name), m_age(age){}
//派生類Student
class Student: public People{
private:
float m_score;
public:
Student(char *name, int age, float score);
void display();
};
//People(name, age)就是調用基類的構造函數
Student::Student(char *name, int age, float score): People(name, age), m_score(score){ }
void Student::display(){
cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<"。"<<endl;
}
int main(){
Student stu("小明", 16, 90.5);
stu.display();
return 0;
}
運行結果為:
Student::Student(char *name, int age, float score): People(name, age), m_score(score){ }
People(name, age)就是調用基類的構造函數,並將 name 和 age 作為實參傳遞給它,m_score(score)是派生類的參數初始化表,它們之間以逗號,隔開。
Student::Student(char *name, int age, float score): m_score(score), People(name, age){ }
但是不管它們的順序如何,派生類構造函數總是先調用基類構造函數再執行其他代碼(包括參數初始化表以及函數體中的代碼),總體上看和下面的形式類似:
Student::Student(char *name, int age, float score){
People(name, age);
m_score = score;
}
當然這段代碼只是為了方便大家理解,實際上這樣寫是錯誤的,因為基類構造函數不會被繼承,不能當做普通的成員函數來調用。換句話說,只能將基類構造函數的調用放在函數頭部,不能放在函數體中。
Student::Student(char *name, int age, float score): People("小明", 16), m_score(score){ }
A --> B --> C
那麼創建 C 類對象時構造函數的執行順序為:A類構造函數 --> B類構造函數 --> C類構造函數
構造函數的調用順序是按照繼承的層次自頂向下、從基類再到派生類的。
#include <iostream>
using namespace std;
//基類People
class People{
public:
People(); //基類默認構造函數
People(char *name, int age);
protected:
char *m_name;
int m_age;
};
People::People(): m_name("xxx"), m_age(0){ }
People::People(char *name, int age): m_name(name), m_age(age){}
//派生類Student
class Student: public People{
public:
Student();
Student(char*, int, float);
public:
void display();
private:
float m_score;
};
Student::Student(): m_score(0.0){ } //派生類默認構造函數
Student::Student(char *name, int age, float score): People(name, age), m_score(score){ }
void Student::display(){
cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<"。"<<endl;
}
int main(){
Student stu1;
stu1.display();
Student stu2("小明", 16, 90.5);
stu2.display();
return 0;
}
運行結果:Student::Student(),它並沒有指明要調用基類的哪一個構造函數,從運行結果可以很明顯地看出來,系統默認調用了不帶參數的構造函數,也就是People::People()。Student::Student(char *name, int age, float score),它指明了基類的構造函數。People(name, age)去掉,也會調用默認構造函數,第 37 行的輸出結果將變為: