C++基類和派生類的構造函數


派生類不能繼承基類的構造函數,若想通過派生類來對基類的private的變量成員進行初始化則需要:

  通過派生類的構造函數來調用基類的構造函數完成基類成員變量的初始化.

看下面的例子:

#include <iostream>
#include<string>

using namespace std;

class People {
private:
    char *m_name;
    int m_age;

public:
    People(char*, int);
};

People::People(char* name,int age):m_name(name),m_age(age){}

class Student : public People {

//此處的public是將其基類:People 的成員以其在People內的級別於Student中繼承,
//即成員在基類中是什么級別就以什么級別被派生類繼承.protected則是將public級別的成員改為protected被派生類繼承,private則是
//全變成private被派生類繼承


private:
    float m_score;

public:
    Student(char* name, int age, float score);
    //void display();
};

Student::Student(char*name,int age,float score):People(name,age),m_score(score){    
    cout << " 姓名: " << name << "   年齡: " << age << "   成績: " << score << endl;
}        //在此處調用基類的構造函數,可調換基類構造函數的順序,當然相應的形參位置也要變.

/*void Student::display() {
    cout <<" 姓名: "<< m_name << "   年齡: " << m_age << "   成績: " << m_score << endl;
}*/

int main()
{
    Student *pstu = new Student("Chan",21,99);
    //pstu->display();
    return 0;
}

錯誤用法:

Student::Student(char *name, int age, float score){
    People(name, age);
    m_score = score;
} //error

因為派生類沒有繼承基類的構造函數,所以不能調用基類的構造函數.

 

 

構造函數調用順序:

  先是調用基類的構造函數,然后再調用派生類的構造函數,多繼承亦然.

注意事項:多繼承如 A -- B -- C    只能直接調用基類構造函數,不能間接調用基類構造函數,即B可調用A,但C不可調用A.

/*C++ 這樣規定是有道理的,因為我們在 C 中調用了 B 的構造函數,B 又調用了 A 的構造函數,相當於 C 間接地(或者說隱式地)調用了 A 的構造函數,如果再在 C 中顯式地調用 A 的構造函數,那么 A 的構造函數就被調用了兩次,相應地,初始化工作也做了兩次,這不僅是多余的,還會浪費CPU時間以及內存,毫無益處,所以 C++ 禁止在 C 中顯式地調用 A 的構造函數。 */

 

 

通過派生類創建對象時必須要調用基類的構造函數,這是語法規定。換句話說,定義派生類構造函數時最好指明基類構造函數;如果不指明,就調用基類的默認構造函數(不帶參數的構造函數);如果沒有默認構造函數,那么編譯失敗。

請看下面的例子:

#include<iostream>
#include<string>

using namespace std;

class People {
private:
    char* m_name;
    int m_age;

public:
    People();
    People(char*, int);
};

People::People(char* name, int age) :m_name(name), m_age(age) {};
People::People() :m_name("xxxx"), m_age(00) {};

class Student : public People {
private:
    float m_score;

public:
    Student();
    Student(char *name, int age, float score);
};

Student::Student() :People(), m_score(0) {
    cout << "姓名:xxxx" << "   年齡:00" << "   成績:0" << endl;
};

Student::Student(char* name, int age, float score) :People(name, age), m_score(score) {
    cout << "姓名:" <<name<< "   年齡:" <<age<< "   成績:" <<score<< endl;
};

int main() {
    Student *pstu = new Student;
    Student *pstu1 = new Student("陳東",16,88.5);
    return 0;
}

如果將People(name, age)去掉,也會調用默認構造函數.(上面代碼執行后看不出來,需修改People類的private為protected,再在student類中寫void  display())

1 void Student::display(){
2     cout<<m_name<<"的年齡是"<<m_age<<",成績是"<<m_score<<""<<endl;
3 }

 

附:https://blog.csdn.net/qq_23996069/article/details/89344816

轉載來源:http://c.biancheng.net/view/2276.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM