类的组合
类之间的静态关系有两种:组合关系和继承关系。组合关系是对象间 “is a part of” (是一部分)关系的抽象。例如小明是三年级一班的一员,将对象间的这种关系抽象出来,就是学生与班级类之间的关系。
组合
组合可以在已有类的基础上实现更大力度的抽象,例如计算机系统是由主机,显示器,键盘构成。在C++中,一个类内嵌其他类的对象作为成员,他们之间的关系是一种包含与被包含的关系,就是类的组合。例如:
Class A{
...
};
Class B{
private:
A a; //B类中嵌入A类的对象
public:
...
};
当创建类的对象时,如果这个类有内嵌对象成员,那么各个内嵌对象将首先被自动创建。
类名::类名(对象成员所需的形参 基本数据类型所需形参):内嵌对象1(参数表),内嵌对象2(参数表),...//初始化列表
{
类的初始化程序体
}
其中内嵌对象的初始化必须写在初始化列表中,而基本类型数据成员的初始化既可以写在函数体中,也可以采用初始化列表的方式。
因此,Point类的构造函数可以有两种实现方式
(1)Point::Point(int X,int Y){x = X;y = Y;}
(2)Point::Point(int X,int Y):x(X),y(Y){ };
组合类构造函数的调用次序如下:
(1) 调用内嵌对象的构造函数,调用次序与这些内嵌对象在类中的声明次序一致。若组合类调用默认构造函数(即无形参的),则内嵌对象的初始化也将调用相应的默认构造函数。注意:与构造函数初始化列表中的次序无关!
(2) 执行本类构造函数的函数体。
(3) 析构函数调用次序与构造函数正好相反。
组合类中构造函数的调用次序:
#include <iostream>
#include <cmath>
using namespace std;
class Point{
public:
Point(int X,int Y){
x = X;
y = Y;
cout<<"Point类带参构造函数调用完毕"<<x<<ends<<y<<endl;
}
~Point(){
cout<<"Point类析构函数调用完毕"<<x<<ends<<y<<endl;
}
Point(Point &P){
x = P.x;
y = P.y;
cout<<"Point类拷贝构造函数调用完毕"<<x<<ends<<y<<endl;
}
int getX(){
return x;
}
int getY(){
return y;
}
private:
int x,y;
};
class Line{
private:
Point p1,p2;
double dist;
public:
Line(Point P1,Point P2);//组合类构造函数
Line(Line &L); //组合类拷贝构造函数
~Line(){
cout<<"Line类析构函数被调用"<<endl;
}
double getDist(){
return dist;
}
}
Line::Line(Point P1,Point p2):p1(P1),p2(P2)
{
cout<<"Line构造函数被调用"<<endl;
double dx = double(p1.getX() - p2.getX());
double dy = double(p1.getY() - p2.getY());
dist = sqrt(dx*dx + dy*dy);
}
Line::Line(Line &L):p1(L.p1),p2(L.p2){
cout<<" Line类拷贝构造函数被调用"<<endl;
dist = L.dist;
}
int main()
{
Point myp1(1,1),myp2(4,5);
Line myL(myp1,myp2);
cout<<"the distance is:"<<myL.getDist()<<endl;
Line youL(myL);
cout<<"the distance is:"<<youL.getDist()<<endl;
return 1;
}
运行结果如下: