C++:類的組合


在類中定義的數據成員一般都是基本數據類型或服復合數據類型。但是還可以根據需要使用
其他類的對象作為正在聲明的數據成員。復雜的對象還可以有比較簡單的對象一某種方式組合
而成,復雜對象和組成它的簡單對象之間的關系是組合關系。

在一個類中內嵌另一個類的對象作為數據成員,稱為類的組合。該內嵌對象稱為對象成員,也稱為
子對象。例如:

class A
{
       .......
};
class B
{
       A a; //類A的對象a為類B的對象成員
       public:
       ....
};

當創建類的對象時,如果這個類具有內嵌對象成員,那么內嵌對象成員也將被自動創建,因此,
在創建對象時既要對本類的基本數據成員初始化,又要對內嵌的對象成員進行初始化。含有對象
成員的類,其構造函數和不含對象成員的構造函數有所不同,例如有以下的類X:
class X{
              類名1 對象成員 1;
              類名2 對象成員 2;
              .................
             類名n 對象成員 n;
           };

一般來說,類X的構造函數的定義形式為:
X::X(形參表0):對象成員1(形參表1),對象成員2(形參表2),對象成員3(形參表3),....
{
      //類的構造函數體
}

其中,"對象成員1(形參表1),對象成員2(形參表2),對象成員3(形參表3),...."稱作初始化表,其作用
是對對象成員進行初始化。
當調用構造函數X::X()時,首先按各內嵌對象成員在類聲明中的順序依次調用他們的構造函數,對這些
對象初始化。最后在執行類X的構造函數體,初始化類X的其他成員。析構函數的調用順序與構造函數的
調用順序相反。

例:  對象成員的初始化

#include<iostream>
using namespace std;
class A{               //聲明類A 
  public:
    A(int x1,float y1)
    {
     x = x1;
     y = y1;
    }
    void show()
    {
     cout<<"x="<<x<<endl;
     cout<<"y="<<y<<endl;
    }
  private:
    int x;
    float y;    
}; 
class B{           //聲明類B 
  public:
    B(int x1,float y1,int z1):a(x1,y1)   //類B的構造函數,含有初始化列表,用與對內嵌對象a進行初始化 
    {
      z = z1;
    }  
   void show()
   {
     a.show();
     cout<<"z="<<z<<endl;
   }
    private:
     A a;      //類A的對象a為類B的對象成員 
     int z;
};
int main()
{
   B b(11,22,33);
   b.show();
   
   return 0;
}


需求:定義學生類和成績類,將student類的成員score作為成績類的一個對象 ,然后用初始化
列表進行初始化。
例 :對象成員的應用

#include<iostream>
#include<string>
using namespace std;
class Score{            //聲明類Score 
   public:
      Score(float m,float l,float E);
      void show();
    private:
      float math;
      float language;
      float English;   
};
Score::Score(float m,float l,float E)     //定義構造函數 
{
    math = m;
    language = l;
    English = E;
}
void Score::show()
{
   cout<<"數學的成績是:"<<math<<endl;
   cout<<"語文的成績是:"<<language<<endl;
   cout<<"英語的成績是:"<<English<<endl;
}
class Student{                     //聲明類student 
  public:
      Student(char* n,char* s,float m,float l,float E);   //聲明構造函數 
      ~Student();  //聲明析構函數 
      void show();
  private:
      char* name;     //學生姓名
      char* sno;      //學生學號 
      Score Sco;      //對象成員,是類Score的對象 
};
Student::Student(char* n,char* s,float m,float l,float E):Sco(m,l,E)  //定義構造函數  
{
      name = new char[strlen(n)+1];
      strcpy(name,n);
      sno = new char[strlen(n)+1];
      strcpy(sno,s);   
} 
Student::~Student()
{
      delete []name;
      delete []sno;
}
void Student::show()
{
     cout<<"學生的姓名是:"<<name<<endl;
     cout<<"學生的學號是:"<<sno<<endl;
     Sco.show();
}
int main()
{
  Student stu1("張三","1011",98.3,98.6,99.1); //定義類student的對象stu1,調用stu1的構造函數,
                                              //初始化對象stu1
  stu1.show();  //調用stu1的show(),顯示stu1的數據 
  cout<<endl;   
  
  Student stu2("李四","1012",98.8,98.5,99.5);
  stu2.show();
  cout<<endl;   
}

從上面的程序可以看出,類student的show函數中對於對象成員Sco的處理方式就是通過調用類Score的show函數
來實現的。

說明:
1、聲明含有對象的類,首先要創建對象成員。本例在聲明類Studet中,定義了對象成員Sco;
Score Sco;

2、在定義類Student的對象,調用構造函數進行初始化的同時,也要對對象成員進行初始化,因為它
屬於此類的成員。因此在寫類Student的構造函數時,也綴上了對象成員Sco要調用類Score的構造
函數。
Student::Student(char* n,char* s,float m,float l,float E):Sco(m,l,E){}
這時構造函數的調用順序是:先調用對象成員Sco的構造函數,對對象成員的數據成員進行初始化。
隨后再執行類Student的構造函數的函數體,對派生類數據成員進行初始化。

注意:在定義類Student的構造函數時,必須綴上對象成員的名字Sco,而不能綴上類名。。。

 


免責聲明!

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



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