类的组合:
新类中的数据成员是另一个类的对象,可称这种成员是新建类的子对象或对象成员。
可以在已有的抽象的基础上实现更复杂的抽象。
新类的定义格式可表述为:
class X
{
类名1 成员1;
类名2 成员2;
........
类名N 成员N;
..........
};
对象成员的初始化:
在构造类X的对象过程中:
系统首先调用其子对象的构造函数,初始化子对象;然后才执行类X自己的构造函数的函数体以完成初始化本类中的非对象成员。
对于同一类中的不同的子对象,系统按照它们在类中的说明顺序调用相应的构造函数进行初始化,而不是按照初始化表的顺序进行初始化。
类的组合举例:
class Part
{
public:
Part();
Part(int i);
~Part();
void Print();
private:
int val;
};
class Whole
{
public:
Whole();
Whole(int i,int j,int k);
~Whole();
void Print();
private:
Part one;
Part two;
int date;
};
Whole::Whole()
{
date=0;
}
Whole::Whole(int i,int j,int k):two(i),one(j),date(k)
{}
//其他函数的实现略
实现不同类对象的包含,还可以用指向类对象的指针。
不直接以对象作为类的成员,而是以指向对象的指针作为类的成员,也是实现包含关系的常用方法。这种情形下,由于对象指针是类的一般数据成员,所以不必如对象成员那样,在构造函数说明中加入成员初始化符表,而是直接在构造函数内进行初始化即可。
以下是在网上搜到的一个类的组合的小程序,运行了一下,加深理解:
#include<iostream> #include<cmath> using namespace std; class Point { private: float x,y; public: Point(float xx,float yy); Point(Point &p); float GetX(void); float GetY(void); ~Point(); }; Point::Point(float xx,float yy) { cout<<"Point 构造函数"<<endl; x=xx;y=yy; } Point::Point(Point &p) { cout<<"Point 拷贝构造函数"<<endl; x=p.x;y=p.y; } float Point::GetX(void) {return x;} float Point::GetY(void) {return y;}
Point::~Point()
{}; class Dist { private: Point p1,p2; double dist; public: Dist(Point a,Point b); double GetD(void) {return dist;} }; Dist::Dist(Point a,Point b):p1(a),p2(b) { double x=double(p1.GetX()-p2.GetX()); double y=double(p1.GetX()-p2.GetX()); dist=sqrt(x*x+y*y); cout<<"Distance构造函数"<<endl; } void main() { Point myp1(1,2),myp2(4,5); Dist myd(myp1,myp2); cout<<"the distance is:"<<myd.GetD()<<endl; }
程序运行结果:
在上述程序中,我在类Point中写了析构函数,可是编译时出现了错误,后来发现是少了析构函数的实现代码,加上后,编译通过,结果如上图。