1. 程式人生 > >類的組合(C++學習筆記 29)

類的組合(C++學習筆記 29)

計算機硬體可構成計算機硬體類。計算機硬體類的資料成員有型號、CPU引數、記憶體引數、硬碟引數、廠家等。其中的資料成員“ 廠家 ”又是計算機公司類的物件。這樣,計算機硬體類的資料成員中就可以有計算機公司類的物件,或者反過來說,計算機公司類的物件又是計算機硬體類的一個數據成員。這樣,當生成一個計算機硬體類物件時,其中就巢狀著一個計算機公司類物件。

類的組合: 在一個類中內嵌另一個類的物件作為資料成員。該內嵌物件稱為物件成員,也稱為子物件。例如:

class A{
	//···
};
class B{
		A a;  //類 A 的物件 a 為類 B 的物件成員
	public
: //······ };

  當建立類的物件時(如建立類 B 的物件),如果這個類具有內嵌的物件成員(如內嵌的物件成員 a),那麼物件成員也將被自動建立。因此,在建立物件時,既要對本類的基本資料成員初始化,又要對內嵌的物件成員進行初始化。含有物件成員的類,其建構函式和不含物件成員的建構函式有所不同。例如有以下的類 X:

class X{
	類名1 物件成員1;
	類名2 物件成員2;
	···
	類名3 物件成員n;
};

一般來說,類 X 的建構函式的定義形式為:

X::X(形參表0):物件成員1(形參表1),物件成員2(形參表2),···
{
	//類 X 的建構函式體
}

  其中,“ 物件成員1(形參表1),物件成員2(形參表2),··· ” 稱作初始化表,其作用是對物件成員進行初始化。
  當呼叫建構函式 X::X( )時,首先按個內嵌物件成員在類宣告中的順序依次呼叫它們的建構函式,對這些物件初始化,最後再執行類 X 的建構函式體,初始化類 X 中的其他成員,解構函式的呼叫順序與建構函式的呼叫順序相反。

例 1:物件成員的初始化。

#include<iostream>
using namespace std;
class A{
	public:
		A(int x1,float y1){
			x=x1;
			y=y1;
		}
void show(){ cout<<"\n x="<<x<<" y="<<y; } private: int x; float y; }; class B{ public: B(int x1,float y1,int z1):a(x1,y1){ z=z1; } void show(){ a.show(); cout<<" z="<<z; } private: A a; //類 A 的物件 a 為類 B 的物件成員 int z; }; int main(){ B b(11,22,33); b.show(); return 0; }

例 2:物件成員的應用。

每個學生的學習成績應該含有多門課的成績。考慮到所有學習成績的性質和處理都是一致的,所以學習成績也可以單獨作為一個類(成績類),而把類 Student 中的成員 score 作為成績類的一個物件。這樣,一個學生類中就巢狀著一個成績類物件。

#include<iostream>
#include<string.h>
using namespace std;
class Score{
	public:
		Score(float c=0,float e=0,float m=0);
		void show();
	private:
		float computer;
		float english;
		float mathematics;
};
Score::Score(float c,float e,float m){
	computer=c;
	english=e;
	mathematics=m;
}
void Score::show(){
	cout<<"\n 計算機成績:"<<computer;
	cout<<"\n 英語成績:"<<english;
	cout<<"\n 數學成績:"<<mathematics;
}
class Student{
	private:
		char *name;
		char *stu_no;
		Score score1;  //物件成員,是類Score的物件
	public:
		Student(char *name1,char *stu_no1,float s1,float s2,float s3):score1(s1,s2,s3){  //建構函式 
			name=new char[strlen(name1)+1];
			strcpy(name,name1);
			stu_no=new char[strlen(stu_no1)];
			strcpy(stu_no,stu_no1);
		}
	    ~Student(){
	    	delete []name;
	    	delete []stu_no;
		}
		void show(){
			cout<<"\n 姓名:"<<name;
			cout<<"\n 學號:"<<stu_no;
			score1.show();
		}
};
int main(){
	Student stu1("哈利波特","01",90,88,90);
	stu1.show();
	cout<<endl;
	Student stu2("羅恩","02",88,88,90);
	stu2.show();
	cout<<endl;
	Student stu3("赫敏","03",99,97,99);
	stu3.show();
	cout<<endl;
}

執行結果:
在這裡插入圖片描述
使用String類來使該程式簡潔一點,把Student類改一下:

class Student{
	private:
		string name;
		string stu_no;
		Score score1;  //物件成員,是類Score的物件
	public:
		Student(string name1,string stu_no1,float s1,float s2,float s3):score1(s1,s2,s3){  //建構函式 
			name=name1;
			stu_no=stu_no1;
		}
		void show(){
			cout<<"\n 姓名:"<<name;
			cout<<"\n 學號:"<<stu_no;
			score1.show();
		}
};

說明:
(1)宣告一個含有物件的類,首先要建立物件成員。如本例在宣告類 Student 中,定義了物件成員 score1:Score score1;
(2)在定義類 Student 的物件,呼叫建構函式進行初始化的同時,也要對物件成員進行初始化,因為它也是屬於此類的成員。因此在寫類 Student 的建構函式時,也綴上了物件成員 score1 要呼叫的類 Score 的建構函式:

Student(char *name1,char *stu_no1,float s1,float s2,float s3):score1(s1,s2,s3){
      //建構函式 
}

  這時建構函式的呼叫順序是:先呼叫物件成員 score1 的建構函式,對物件成員的資料成員進行初始化。隨後再執行類 Student 建構函式的函式體,對派生類資料成員進行初始化。
  注意:在定義類 Student 的建構函式時,必須綴上物件成員的名字 score1,而不能綴上類名,若寫成:

Student(char *name1,char *stu_no1,float s1,float s2,float s3):Score(s1,s2,s3){
      //建構函式 
}

是不允許的,因為在類 Student 中是類 Score 的物件 score1 作為成員,而不是類 Score 作為其成員。