1、什么是类的组合,为什么要类组合? 比如计算机,它分为硬件和软件,其中硬件又有cpu、显卡、内存等,软件分为系统和用户软件。如果直接声明计算机类,这样相对复杂,我们可以将硬件和软件声明为单独的类,这样计算机类由硬件类和软件类组成。这样处理起来就相对方便了。 类组合其实就是在一个类中嵌入其他类对象作为成员,创建该类对象时,其所包含的类对象自动创建。类对象是组合类的一部分,所以在构造时除了对组合类数据成员进行初始化,同时也要将其对象成员初始化。(以前的简单类我们知道有数据成员,现在的数据成员有类类型的) 组合类对象构造函数定义(不是声明):内嵌对象1(形参表),内嵌对象2(形参表),….为形参初始化列表,如类名::类名(形参表):内嵌对象1(形参表),内嵌对象2(形参表),…. { 类初始化 }
Point(int xx,int yy):X(xx),Y(yy){}
但声明一个组合类对象时,除了自身的构造函数调用外,还有内嵌对象的构造函数。那么顺序是怎样的呢?如下示例:
#include <iostream> #include<math.h> using namespace std; class Point { public: Point(int xx,int yy){X=xx;Y=yy; cout<<"Point构造函数调用"<<endl;} Point(Point& p); int GetX(){return X;} int GetY(){return Y;} private: int X,Y; }; Point::Point(Point& p) { X=p.X; Y=p.Y; cout<<"Point拷贝构造函数调用"<<endl; } class Distance { public: Distance(Point a,Point b); //声明 int GetDis(){return dis;} private: double dis; Point p1; Point p2; }; Distance::Distance(Point a,Point b):p1(a),p2(b) { //共调用了4次Point拷贝构造,Distanc构造函数形参和实参结合时2次 //传入值初始化内嵌对象时调用两次 int x=p1.GetX()-p2.GetX(); int y=p1.GetY()-p2.GetY(); dis=sqrt(x*x+y*y);
<span style="white-space:pre"> </span>cout<<"Distance构造调用"<<endl; } int main() { Point mp1(1,2),mp2(3,4); Distance d(mp1,mp2); cout<<d.GetDis()<<endl; return 0; }
输出结果为: Point构造函数调用 Point构造函数调用 Point拷贝构造函数调用 Point拷贝构造函数调用 Point拷贝构造函数调用 Point拷贝构造函数调用 //共调用4次
2<pre name="code" class="cpp">Distance构造调用
调用顺序为:
按照内嵌对象在组合类中的出现顺序中依次调用其内嵌对象的构造函数,再执行本类构造函数的的函数体。
另一种情况是两个类相互包含时,这时我们要用到前向声明。即在引用没有定义的类之前对该类进行声明。如class B; //前向声明 class A { public: voidfun(B b); //用到B类 }; class B {……B的定义};