类的组合(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 作为其成员。

猜你喜欢

转载自blog.csdn.net/aaqian1/article/details/84494415
c29
今日推荐