[CPP]大一学生学习C++的笔记(2)

[CPP]C++学习之路——类的组合、组合类的构造函数

前言

如果我们要解决一个很复杂的问题,一个有效的方法就是将其拆分成简单问题的组合,当我们解决了简单问题后,复杂问题也就迎刃而解了。

我们同样可以对于复杂的类进行分解,将其分解为简单类的对象的组合。

类的组合

类的组合描述的就是一个类内嵌其他类的对象作为成员的情况,它们之间的关系是一种包含与被包含的关系。

eg:
假设我们需要一个线段(Line)类,其中包含两个点(Point)类的对象p1,p2,代码如下。

#include <iostream>
#include <cmath>
using namespace std;

//Point类定义
class Point {
	public:
		Point(int xx = 0, int yy = 0) {
			x = xx;
			y = yy;
		}
		Point(Point &p);
		int getX() {
			return x;
		}
		int getY() {
			return y;
		}
	private:
		int x, y;
};
//Point类的复制构造函数
Point::Point(Point &p) {
	x = p.x;
	y = p.y;
	cout << "Call the copy constructor of Point" << endl;
}

//组合类
class Line {
	public:
		Line(Point xp1, Point xp2);
		Line(Line &l);
		double getLen() {
			return len;
		}
	private:
		Point p1, p2;
		double len;
};
组合类的构造函数

我们还没有写Line类的构造函数,因为这里出现了一个问题…

创建一个类的对象时,如果这个对象有内嵌对象成员,那么我们既要对本类的基本数据成员进行初始化,又要对内嵌对象成员进行初始化。这时,理解这些对象的构造函数的顺序就至关重要。

Line类的构造函数与我们平时写构造函数的思路差不多,不过有一些细节需要注意。

//组合类的构造函数
Line::Line(Point xp1, Point xp2): p1(xp1), p2(xp2) {
	cout << "Calling constructor of Line" << endl;
	double x = static_cast<double> (p1.getX() - p2.getX() );
	double y = static_cast<double> (p1.getY() - p2.getY() );
	len = sqrt(x * x + y * y);
}

我们先回忆一下曾经写的Clock类的构造函数:

Clock::Clock(int newH,int newM,int newS):hour(newH),minute(newM),second(newS){}
......
//执行
Clock(12,12,12);

我们首先将实参赋给形参,再把形参的值通过初始化列表赋给该对象的hour、minute、second

对Line类的构造函数来说,也是同样的道理。

Point myp1(1,1),myp2(4,5);
//执行
Line line(myp1,myp2);

建立Line类的对象line时,同样是先形实结合,将实参赋给形参。

复制构造函数在有一种情况下会被调用,即函数的形参是类的对象,调用函数进行形实结合时。

所以这里进行形实结合时需要调用两次Point类的复制构造函数。

接下来到了初始化列表的环节了,xp1和xp2分别是部件对象初始化时所需要的参数,p1和p2是Line类的私有成员。

我们使用初始化列表将xp1赋给p1,将xp2赋给p2,此时又要调用两次Point类的复制构造函数。

这里还有个小细节,初始化列表里p1p2出现的顺序对执行顺序没有影响,因为定义的时候先写的p1后写的p2,所以先初始化p1。

接下来,终于到了Line类的构造函数内部了,执行它的语句就好。

组合类的复制构造函数
//组合类的复制构造函数
Line::Line(Line &l): p1(l.p1), p2(l.p2) {
	cout << "Calling the copy constructor of Line" << endl;
	len=l.len;
}
//执行
Line line2(line);

执行时将l作为对象line的别名(引用),然后是初始化列表,将line的p1传给新的Line类的对象的p1,将line的p2传给新的Line类的对象的p2。
这里又调用了两次Point类的复制构造函数。

随后进到组合类的复制构造函数内部,执行语句。

小结
//主函数
int main() {
	Point myp1(1, 1), myp2(4, 5);
	Line line(myp1, myp2);
	Line line2(line);
	cout << "The length of the line is:";
	cout << line.getLen() << endl;
	return 0;
}

我们运行一下,看看运行结果是否真如我们分析的那样。

Call the copy constructor of Point	//形实结合
Call the copy constructor of Point	//形实结合
Call the copy constructor of Point	//初始化列表
Call the copy constructor of Point	//初始化列表
Calling constructor of Line
Call the copy constructor of Point	//初始化列表
Call the copy constructor of Point	//初始化列表
Calling the copy constructor of Line
The length of the line is:5

看来真是如此。

Ok,that’s it.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值