组合类理解初记
我们将现实世界中的事物抽象成类时,可能会形成很复杂的类。为了简洁开发,我们会将其中相对独立的部分抽象成一个个简单的类,这些简单的类又可以分为一些更简单的类,最后,由这些简单的类再组成我们需要的类。
类的组合,其实就是在一个类中内嵌了其他类的对象做为组合类的成员的情况。一般简单类的数据成员是简单数据类型和自定义数据类型的。现在我了解到,类的数据成员也可以是类类型的。
如果一个类中内嵌了其他类的对象,那么创建这个类的对象时,其内嵌对象也会被自动创建。构造这个类的对象时,要首先对内嵌对象初始化,再初始化组合类的对象。也就是说,先调用内嵌对象的类的构造函数,再调用组合类的构造函数。组合类生命周期结束时,调用析构函数的顺序与调用构造函数的顺序相反。即先调用组合类的析构函数,再调用内嵌对象的类的析构函数。
组合类的构造函数通常定义为:
类名::类名(形参列表):内嵌对象1(形参列表),内嵌对象2(形参列表),。。。
{
类的初始化
}
其中“内嵌对象1(形参列表),内嵌对象2(形参列表),。。。”完成了内嵌对象的初始化。
简单的例子:
计算两点间距的类的构造函数定义为:
Distance::Distance(Point a, Point b):p1(a),p2(b){不必初始化数据成员p1和p2了。其他操作。}
分析:构造Distance对象时,先调用Point类的拷贝构造函数,将已经存在的Point类对象,做为实参,分别传递给形参a和b,再调用Point类的拷贝构造函数,将传入的参数分别拷贝给内嵌对象p1和p2。之后,才调用Distance类的构造函数。
其实一般的数据成员也可以这样初始化,具体做法是将内嵌对象名换成数据成员名,后面的形参列表,是用来初始化成员的变量形参。比如:
Point::Point(int xx, int yy):X(xx),Y(yy){可以不用再初始化数据成员X和Y了。其他操作。}
分析:构造Point对象时,调用Point类的构造函数Point(int xx, int yy),将实参传入形参xx,yy,而后用xx,yy分别初始化Point类数据成员X,Y。
以上例子中的Point类的构造函数定义为:Point::Point(int xx, int yy){X=xx; Y=yy;}。拷贝构造函数定义为Point::Point(Point &p){X=p.X; Y=p.Y;}。
C++中,使用一个类之前,必须先定义该类。有一种特殊情况:两个类相互包含。也就是类A中内嵌了类B的对象,而类B中也内嵌了类A的对象。这种情况发生时,一定有一个类在使用之前没有被定义。这时,C++允许前向引用声明。前向引用声明,是在引用没有被定义的类之前,对该类进行声明。相当于先生成一个代表该类的标识符,声明这个标识符是一个类的标识符。