类的组合
定义:类中的成员是另一个类的对象(用已经存在的类成员去组装新的类
class line //定义一个线类
{
private:point p1; point p2;//线段端点,这两个点是类p,所以这里实现了类的组合
组合类的初始化
:组合类没有权利访问对象内部的私有成员
(一个类的私有成员只有类的内部函数可以访问,这也是为何要复制构造函数的原因)
组合类构造函数参数表不仅要给出本类基本成员的初始化,还要对组合对象进行初始化
对象成员用自己所属类造函数初始化,但他们要参数,所以组合类的构造函数传参数给他们
这样声明:
类名::类名(对象成员所需的形参,本类成员形参):
对象1(参数),对象2(参数)…{}
1成员初始化顺序按照在类中定义的顺序,先定义先初始化
private:point p1; point p2;
2成员对象调用的顺序也是按照他们在类中声明的数据来的
3如果有的对象在初始化列表没列出来,就调用他自己所属类的默认构造函数(无参数那个)来初始化
如果部件对象没有默认构造函数,也就是部件对象的初始化必须要参数,那组合类的构造函数就必须给他传参数,不然会报错。
所以,在写类的时候,为了让他更多场合被使用,应该给他多写一个默认构造函数
放例子:构造组合类的对象
#include<iostream>
#include<cmath>
using namespace std;
class point//定义一个点类
{
public:
point(float xx, float yy);
point(const point& p);
float getX() { return x; }
float getY() { return y; }
private:
float x,y;
};
point::point(float xx, float yy) :x(xx), y(yy) {}//构造函数
point::point(const point& p)//复制构造函数
{
x = p.x;
y = p.y;
cout << "point复制构造函数被调用" << endl;
}
class line //定义一个线类
{
private:point p1; point p2;//线段端点,这两个点是类p,所以这里实现了类的组合
double len;
public:
line(point xp1, point xp2);
line(const line&S);//不用const,因为我们要修改
double Getlen() { return len; }
};
line::line(point xp1, point xp2) ://构造函数
p1(xp1), p2(xp2)//这里又是赋值,所以又要进行复制构造
//除了实行赋值,还进行其他功能如下
{
cout << "line构造函数被调用" << endl;
double x = double(p1.getX()- p2.getX());
double y = double(p1.getY()- p2.getY());
len = sqrt(x * x + y * y);//算出线段长度
}
line::line(const line&S)://线的复制构造函数
p1(S.p1), p2(S.p2)//在这里也会用到点的复制构造函数
{
cout << "line复制构造函数被调用" << endl;
len = S.len;//把len也拷贝过去;
}
int main()
{
point myp1(1, 1), myp2(4, 5);//建立两个点
line line1(myp1, myp2);//建立一个line对象 myp1要先复制构造,赋值给xp2
line line2(line1);//用line复制构造函数建立一个新对象,此时会调用线的复制构造函数
cout << "线段1的长度为" << line1.Getlen() << endl;
cout<<"线段2的长度为"<< line2.Getlen() << endl;
return 0;
}
类对象每次赋值给另一个对象都要进行复制构造