C语言日记 36 类的组合

首先,在讲类的组合之前,我们先(重新)声明一下:

在类中,如果没有设置访问属性,默认该成员为私有成员

书P137:

如果声明组合类的对象时没有指定对象的初始值,自动调用无形参的构造函数,

构造内嵌对象时也对应调用内嵌对象的无形参的构造函数。

Q1:这里,对于“构造内嵌对象时也对应调用内嵌对象的无形参的构造函数”;他指的是什么时候(什么条件下)?

是唯独没有指定(内嵌)对象的初始值的时候,还是只是指所有对象全都没有初始值时(这么操作)?

在这里,反复阅读题干,我们应该可以发现(说):

题干中既然说了是“指定对象”,那么也就是说看具体对象内容而定

当非内嵌对象没有初值时,自动调用无形参的构造函数

当内嵌对象没有初值时,调用内嵌对象的无形参的构造函数

当所有对象全都没有初始值时:

非内嵌对象自动调用无形参的构造函数

内嵌对象自动调用内嵌对象的无形参的构造函数

析构函数的执行顺序与构造函数正好相反。    

Q2:他这里的顺序相反,指的是析构函数在消除清理内容和空间时,是先处理非内嵌对象再处理内嵌对象吗?

设计程序验证Q1,Q2:

例8-13 用组合类计算两点间的距离。

源程序:

#include<iostream>
using namespace std;
class Point
{
public:
	Point(int xx, int yy)
	{
		X = xx; Y = yy;
	}//构造函数
	Point(Point& p);
	int GetX(void)
	{
		return X;
	}//取X坐标

	int GetY(void)
	{
		return Y;
	}//取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);//构造函数
	double GetDis() { return dist; }
private:
	Point p1, p2;
	double dist;	//距离
};
Distance::Distance(Point a, Point b) :p1(a), p2(b)
//组合类的构造函数
{
	cout << "Distance 构造函数被调用" << endl;
	double x = double(p1.GetX() - p2.GetX());
	double y = double(p1.GetY() - p2.GetY());
	dist = sqrt(x * x + y * y);
}
void main()
{
	Point myp1(1, 1), myp2(4, 5);
	Distance myd(myp1, myp2);
	cout << "The distance is:" << myd.GetDis() << endl;
}

运行结果:

为什么(明明)有了“sqrt()函数”却不用在函数开头的头文件里面输入#include <math.h>?

详见:C语言日记 8 C++语句_宇 -Yu的博客-CSDN博客:#include <math.h>//可有可无
    

书P139:

不完全类型不能定义该类型的对象:

#include<iostream>
using namespace std;
class B;
class A
{
	int i;
	B b;
};
class B
{
	int i;
	A a;
};
int main()
{

}

只能用于: 

(1):定义(指向该类型的)

  • 指针
#include<iostream>
using namespace std;
class B;
class A
{
	int i;
	B *b;
};
class B
{
	int i;
	A a;
};
int main()
{

}
  • 引用  
#include<iostream>
using namespace std;
class B;
class A
{
	int i;
	B& b;
};
class B
{
	int i;
	A a;
};

int main()
{

}

但是在这里,我们还是需要注意:不完全类型不能在别的类里(面)定义该类型的对象:

#include<iostream>
using namespace std;
class B;
class A
{
	int i;
	B u;
	B& b=u;
};
class B
{
	int i;
	A a;
};

int main()
{

}

从这个里面(这个角度)说起来这个引用的作用意义又很奇怪:

引用只能在声明引用时赋初值(初始化)

而在类的引用里面如果我们要(想)初始化,只能将该类里面的不完全类型对象赋给该引用对象 

可是不完全类型又不能在别的类里(面)定义该类型的对象,这里面这不就是一个悖论吗

(2):声明<不是定义>(使用该类型作为)

  • 形参类型的函数
#include<iostream>
using namespace std;
class B;
class A
{
	int i;
	int f(B b);
};
int main()
{

}

 而不能:

#include<iostream>
using namespace std;
class B;
class A
{
	int i;
	int f(B b){}
};
int main()
{

}

  • 返回类型的函数              

对于这个其实我就有点不知从何写起了:

#include<iostream>
using namespace std;
class B;
class A
{
	int i;
	B f()
	{
		return  b;
	}

};
int main()
{

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值