计算机硬件可构成计算机硬件类。计算机硬件类的数据成员有型号、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 作为其成员。