欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來到入門教程網(wǎng)!

C語言

當前位置:主頁 > 軟件編程 > C語言 >

深入解析C++中派生類的構(gòu)造函數(shù)

來源:本站原創(chuàng)|時間:2020-01-10|欄目:C語言|點擊: 次

基類的構(gòu)造函數(shù)不能被繼承,在聲明派生類時,對繼承過來的成員變量的初始化工作也要由派生類的構(gòu)造函數(shù)來完成。所以在設計派生類的構(gòu)造函數(shù)時,不僅要考慮派生類新增的成員變量,還要考慮基類的成員變量,要讓它們都被初始化。

解決這個問題的思路是:在執(zhí)行派生類的構(gòu)造函數(shù)時,調(diào)用基類的構(gòu)造函數(shù)。

下面的例子展示了如何在派生類的構(gòu)造函數(shù)中調(diào)用基類的構(gòu)造函數(shù)。

#include<iostream>
using namespace std;
//基類
class People{
protected:
  char *name;
  int age;
public:
  People(char*, int);
};
People::People(char *name, int age): name(name), age(age){}
//派生類
class Student: public People{
private:
  float score;
public:
  Student(char*, int, float);
  void display();
};
//調(diào)用了基類的構(gòu)造函數(shù)
Student::Student(char *name, int age, float score): People(name, age){
  this->score = score;
}
void Student::display(){
  cout<<name<<"的年齡是"<<age<<",成績是"<<score<<endl;
}
int main(){
  Student stu("小明", 16, 90.5);
  stu.display();
  return 0;
}

運行結(jié)果為:
小明的年齡是16,成績是90.5

請注意代碼第23行:

Student::Student(char *name, int age, float score): People(name, age)


這是派生類 Student 的構(gòu)造函數(shù)的寫法。冒號前面是派生類構(gòu)造函數(shù)的頭部,這和我們以前介紹的構(gòu)造函數(shù)的形式一樣,但它的形參列表包括了初始化基類和派生類的成員變量所需的數(shù)據(jù);冒號后面是對基類構(gòu)造函數(shù)的調(diào)用,這和普通構(gòu)造函數(shù)的參數(shù)初始化表非常類似。

實際上,你可以將對基類構(gòu)造函數(shù)的調(diào)用和參數(shù)初始化表放在一起,如下所示:

Student::Student(char *name, int age, float score): People(name, age), score(score){}


基類構(gòu)造函數(shù)和初始化表用逗號隔開。

需要注意的是:冒號后面是對基類構(gòu)造函數(shù)的調(diào)用,而不是聲明,所以括號里的參數(shù)是實參,它們不但可以是派生類構(gòu)造函數(shù)總參數(shù)表中的參數(shù),還可以是局部變量、常量等。如下所示:

Student::Student(char *name, int age, float score): People("李磊", 20)


基類構(gòu)造函數(shù)調(diào)用規(guī)則

事實上,通過派生類創(chuàng)建對象時必須要調(diào)用基類的構(gòu)造函數(shù),這是語法規(guī)定。也就是說,定義派生類構(gòu)造函數(shù)時最好指明基類構(gòu)造函數(shù);如果不指明,就調(diào)用基類的默認構(gòu)造函數(shù)(不帶參數(shù)的構(gòu)造函數(shù));如果沒有默認構(gòu)造函數(shù),那么編譯失敗。

請看下面的例子:

#include<iostream>
using namespace std;
//基類
class People{
protected:
  char *name;
  int age;
public:
  People();
  People(char*, int);
};
People::People(){
  this->name = "xxx";
  this->age = 0;
}
People::People(char *name, int age): name(name), age(age){}
//派生類
class Student: public People{
private:
  float score;
public:
  Student();
  Student(char*, int, float);
  void display();
};
Student::Student(){
  this->score = 0.0;
}
Student::Student(char *name, int age, float score): People(name, age){
  this->score = score;
}
void Student::display(){
  cout<<name<<"的年齡是"<<age<<",成績是"<<score<<endl;
}
int main(){
  Student stu1;
  stu1.display();
  Student stu2("小明", 16, 90.5);
  stu2.display();
  return 0;
}

運行結(jié)果:

xxx的年齡是0,成績是0
小明的年齡是16,成績是90.5


 

創(chuàng)建對象 stu1 時,執(zhí)行派生類的構(gòu)造函數(shù) Student::Student(),它并沒有指明要調(diào)用基類的哪一個構(gòu)造函數(shù),從運行結(jié)果可以很明顯地看出來,系統(tǒng)默認調(diào)用了不帶參數(shù)的構(gòu)造函數(shù),也就是 People::People()。

創(chuàng)建對象 stu2 時,執(zhí)行派生類的構(gòu)造函數(shù) Student::Student(char *name, int age, float score),它指明了基類的構(gòu)造函數(shù)。

在第31行代碼中,如果將 People(name, age) 去掉,也會調(diào)用默認構(gòu)造函數(shù),stu2.display() 的輸出結(jié)果將變?yōu)椋?br /> xxx的年齡是0,成績是90.5

如果將基類 People 中不帶參數(shù)的構(gòu)造函數(shù)刪除,那么會發(fā)生編譯錯誤,因為創(chuàng)建對象 stu1 時沒有調(diào)用基類構(gòu)造函數(shù)。

總結(jié):如果基類有默認構(gòu)造函數(shù),那么在派生類構(gòu)造函數(shù)中可以不指明,系統(tǒng)會默認調(diào)用;如果沒有,那么必須要指明,否則系統(tǒng)不知道如何調(diào)用基類的構(gòu)造函數(shù)。
構(gòu)造函數(shù)的調(diào)用順序

為了搞清這個問題,我們不妨先來看一個例子:

#include<iostream>
using namespace std;
//基類
class People{
protected:
  char *name;
  int age;
public:
  People();
  People(char*, int);
};
People::People(): name("xxx"), age(0){
  cout<<"PeoPle::People()"<<endl;
}
People::People(char *name, int age): name(name), age(age){
  cout<<"PeoPle::People(char *, int)"<<endl;
}
//派生類
class Student: public People{
private:
  float score;
public:
  Student();
  Student(char*, int, float);
};
Student::Student(): score(0.0){
  cout<<"Student::Student()"<<endl;
}
Student::Student(char *name, int age, float score): People(name, age), score(score){
  cout<<"Student::Student(char*, int, float)"<<endl;
}
int main(){
  Student stu1;
  cout<<"--------------------"<<endl;
  Student stu2("小明", 16, 90.5);
  return 0;
}

運行結(jié)果:

PeoPle::People()
Student::Student()
--------------------
PeoPle::People(char *, int)
Student::Student(char*, int, float)

從運行結(jié)果可以清楚地看到,當創(chuàng)建派生類對象時,先調(diào)用基類構(gòu)造函數(shù),再調(diào)用派生類構(gòu)造函數(shù)。如果繼承關系有好幾層的話,例如:
A --> B --> C
那么則創(chuàng)建C類對象時,構(gòu)造函數(shù)的執(zhí)行順序為:
A類構(gòu)造函數(shù) --> B類構(gòu)造函數(shù) --> C類構(gòu)造函數(shù)
構(gòu)造函數(shù)的調(diào)用順序是按照繼承的層次自頂向下、從基類再到派生類的。

C++有子對象的派生類的構(gòu)造函數(shù)
類的數(shù)據(jù)成員不但可以是標準型(如int、char)或系統(tǒng)提供的類型(如string),還可以包含類對象,如可以在聲明一個類時包含這樣的數(shù)據(jù)成員:

  Student s1; //Student是已聲明的類名,s1是Student類的對象


這時,s1就是類對象中的內(nèi)嵌對象,稱為子對象(subobject),即對象中的對象。


那么,在對數(shù)據(jù)成員初始化時怎樣對子對象初始化呢?請仔細分析下面程序,特別注意派生類構(gòu)造函數(shù)的寫法。

[例] 包含子對象的派生類的構(gòu)造函數(shù)。為了簡化程序以易于閱讀,這里設基類Student的數(shù)據(jù)成員只有兩個,即num和name。

#include <iostream>
#include <string>
using namespace std;
class Student//聲明基類
{
public: //公用部分
  Student(int n, string nam ) //基類構(gòu)造函數(shù),與例11.5相同
  {
   num=n;
   name=nam;
  }
  void display( ) //成員函數(shù),輸出基類數(shù)據(jù)成員
  {
   cout<<"num:"<<num<<endl<<"name:"<<name<<endl;
  }
protected: //保護部分
  int num;
  string name;
};
class Student1: public Student //聲明公用派生類Student1
{
public:
  Student1(int n, string nam,int n1, string nam1,int a, string ad):Student(n,nam),monitor(n1,nam1) //派生類構(gòu)造函數(shù)
  {
   age=a;
   addr=ad;
  }
  void show( )
  {
   cout<<"This student is:"<<endl;
   display(); //輸出num和name
   cout<<"age: "<<age<<endl; //輸出age
   cout<<"address: "<<addr<<endl<<endl; //輸出addr
  }
  void show_monitor( ) //成員函數(shù),輸出子對象
  {
   cout<<endl<<"Class monitor is:"<<endl;
   monitor.display( ); //調(diào)用基類成員函數(shù)
  }
private: //派生類的私有數(shù)據(jù)
  Student monitor; //定義子對象(班長)
  int age;
  string addr;
};
int main( )
{
  Student1 stud1(10010,"Wang-li",10001,"Li-sun",19,"115 Beijing Road,Shanghai");
  stud1.show( ); //輸出學生的數(shù)據(jù)
  stud1.show_monitor(); //輸出子對象的數(shù)據(jù)
  return 0;
}

運行時的輸出如下:

This student is:
num: 10010
name: Wang-li
age: 19
address:115 Beijing Road,Shanghai
Class monitor is:
num:10001
name:Li-sun

請注意在派生類Student1中有一個數(shù)據(jù)成員:

  Student monitor;  //定義子對象 monitor(班長)

“班長”的類型不是簡單類型(如int、char、float等),它是Student類的對象。我們知道, 應當在建立對象時對它的數(shù)據(jù)成員初始化。那么怎樣對子對象初始化呢?顯然不能在聲明派生類時對它初始化(如Student monitor(10001, "Li-fun");),因為類是抽象類型,只是一個模型,是不能有具體的數(shù)據(jù)的,而且每一個派生類對象的子對象一般是不相同的(例如學生A、B、C的班長是A,而學生D、E、F的班長是F)。因此子對象的初始化是在建立派生類時通過調(diào)用派生類構(gòu)造函數(shù)來實現(xiàn)的。

派生類構(gòu)造函數(shù)的任務應該包括3個部分:

  1. 對基類數(shù)據(jù)成員初始化;
  2. 對子對象數(shù)據(jù)成員初始化;
  3. 對派生類數(shù)據(jù)成員初始化。

程序中派生類構(gòu)造函數(shù)首部如下:

  Student1(int n, string nam,int n1, string nam1,int a, string ad):
    Student(n,nam),monitor(n1,nam1)


在上面的構(gòu)造函數(shù)中有6個形參,前兩個作為基類構(gòu)造函數(shù)的參數(shù),第3、第4個作為子對象構(gòu)造函數(shù)的參數(shù),第5、第6個是用作派生類數(shù)據(jù)成員初始化的。

歸納起來,定義派生類構(gòu)造函數(shù)的一般形式為: 派生類構(gòu)造函數(shù)名(總參數(shù)表列): 基類構(gòu)造函數(shù)名(參數(shù)表列), 子對象名(參數(shù)表列)
{
派生類中新增數(shù)成員據(jù)成員初始化語句
}

執(zhí)行派生類構(gòu)造函數(shù)的順序是:
調(diào)用基類構(gòu)造函數(shù),對基類數(shù)據(jù)成員初始化;
調(diào)用子對象構(gòu)造函數(shù),對子對象數(shù)據(jù)成員初始化;
再執(zhí)行派生類構(gòu)造函數(shù)本身,對派生類數(shù)據(jù)成員初始化。

派生類構(gòu)造函數(shù)的總參數(shù)表列中的參數(shù),應當包括基類構(gòu)造函數(shù)和子對象的參數(shù)表列中的參數(shù)。基類構(gòu)造函數(shù)和子對象的次序可以是任意的,如上面的派生類構(gòu)造函數(shù)首部可以寫成

  Student1(int n, string nam,int n1, string nam1,int a, string ad): monitor(n1,nam1),Student(n,nam)


編譯系統(tǒng)是根據(jù)相同的參數(shù)名(而不是根據(jù)參數(shù)的順序)來確立它們的傳遞關系的。但是習慣上一般先寫基類構(gòu)造函數(shù)。

如果有多個子對象,派生類構(gòu)造函數(shù)的寫法依此類推,應列出每一個子對象名及其參數(shù)表列。

上一篇:詳解C++編程中的單目運算符重載與雙目運算符重載

欄    目:C語言

下一篇:詳解C++編程中的輸入輸相關的類和對象

本文標題:深入解析C++中派生類的構(gòu)造函數(shù)

本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2702.html

網(wǎng)頁制作CMS教程網(wǎng)絡編程軟件編程腳本語言數(shù)據(jù)庫服務器

如果侵犯了您的權(quán)利,請與我們聯(lián)系,我們將在24小時內(nèi)進行處理、任何非本站因素導致的法律后果,本站均不負任何責任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有