构造函数,复制构造函数和析构函数

这些函数在网上很容易就可以查到定义和写法,这里就不赘述了。令人感兴趣的是这些函数什么时候执行, 特别是复制构造函数和析构函数。

用编写的一段(很丑的)代码来说明。

#include<iostream>
#include<cstdio>
#include<cmath>

class Point
{
private:
	/* data */
	double x, y ; 
	friend Point& __doa(Point *ths, const Point& p) ; 

public:
	Point(double x=0, double y=0)
	: x(x), y(y)
	{
		std::cout<<"Creating a Point...\n" ; 
	}
	Point (const Point& obj){
		*this = obj ; 
		std::cout<<"Copying a Point...\n" ; 
	}
	~Point(){
		std::cout<<"Deleting a Point...\n" ; 
	}

	double get_x() const {return x;}
	double get_y() const {return y;}
};

// Point&
// __doa(Point *ths, const Point& p ){
// 	ths->x = p.x ; 
// 	ths->y = p.y ;
// 	return *ths ; 
// }

// Point&
// Point::operator = (const Point& p){
// 	return __doa(this, p) ; 
// }


double dist(Point A, Point B) {
		// 返回A和B的euclid距离
		double dist_x = A.get_x() - B.get_x() ; 
		double dist_y = A.get_y() - B.get_y() ;
		return sqrt(dist_x*dist_x + dist_y*dist_y) ; 
}

class Circle
{
private:
	/* data */
	Point c ; 
	double r ; 
public:
	Circle(Point c, double r=0)
	: c(c), r(r) 
	{
		std::cout<<"Creating a Circle...\n" ; 
	}
	Circle(const Circle& obj){
		*this = obj ; 
		std::cout<<"Copying a Circle...\n" ; 
	}
	~Circle(){
		std::cout<<"Deleting a Circle...\n" ; 
	}
	Point get_c() const {return c ; }
	double get_r() const {return r; } 
};

bool is_intersect(Circle O1,Circle O2){
	std::cout<<"\n" ; 
	Point c1, c2 ; 
	c1 = O1.get_c() ; 
	c2 = O2.get_c() ; 
	return O1.get_r() +O2.get_r() > dist(c1, c2) ; 
}

int main(){
	Point A(1,0), B(0,1) ;
	std::cout<<"\n" ; 
	std::cout<<dist(A,B)<<"\n";  
	std::cout<<"\n" ; 
	Circle C1(Point(1,0), 2), C2(Point(4,0), 1.2);
	std::cout<<"\n" ; 
	std::cout<<is_intersect(C1, C2)<<"\n" ;  
	std::cout<<"\n" ; 
	C1.get_c() ; 
	std::cout<<"\n" ; 
	return 0 ; 
}

输出信息:

# 创建A和B
Creating a Point... 
Creating a Point...
# dist创建形参并且销毁
Copying a Point...
Copying a Point...
1.41421
Deleting a Point...
Deleting a Point...
#创建Circle的时候,首先创建临时的Point, 然后通过copy复制创建Circle的c, 创建Circle,最后删掉临时的Point
Creating a Point...
Copying a Point...
Creating a Circle...
Deleting a Point...
Creating a Point...
Copying a Point...
Creating a Circle...
Deleting a Point...
# is_intersect先创建形参Circle的c,然后通过copy复制创建形参
Creating a Point...
Copying a Circle...
Creating a Point...
Copying a Circle...
# 创建c1,c2, 使用函数get_c 会copy一个实例出来,然后返回,删掉。然后给dist传参,这时候要创建形参,用完删掉。删掉c1,c2. 最后删掉O1, O2(当然删掉Circle之后要把c也删掉). 
Creating a Point...
Creating a Point...
Copying a Point...
Deleting a Point...
Copying a Point...
Deleting a Point...
Copying a Point...
Copying a Point...
Deleting a Point...
Deleting a Point...
Deleting a Point...
Deleting a Point...
1
Deleting a Circle...
Deleting a Point...
Deleting a Circle...
Deleting a Point...
# 可以看到,调用get_c也会使用复制构造函数
Copying a Point...
Deleting a Point...
# 最后删掉main中创建的实例(按照创建时间倒序删除,看来是堆栈)
Deleting a Circle...
Deleting a Point...
Deleting a Circle...
Deleting a Point...
Deleting a Point...
Deleting a Point...

从上面的输出信息可以发现这么几点:

  1. 构造使用了自底向上的顺序, 而析构使用了自顶向下的顺序。 比如给函数is_intersect传递形参的时候, 需要先创建一个Point, 也就是c. 因为copy函数是将所有的属性进行复制, 而没有Point这个属性的话是无法进行的。
  2. 传递形参, 创建返回值的时候, 经常使用到复制构造函数。 比如像dist函数传递形参的过程中。 还有get_c函数返回对象c, 即使只有简单的一条语句, 也创建了一个新的对象。
  3. 从函数中退出的时候, 本地产生的对象都会被析构, 释放内存。

下面的代码段是给函数尽可能加上引用之后的形式, 为了进行比较, 也输出了相应的信息。

#include<iostream>
#include<cstdio>
#include<cmath>

class Point
{
private:
	/* data */
	double x, y ; 

public:
	Point(const double& x=0, const double& y=0)
	: x(x), y(y)
	{
		std::cout<<"Creating a Point...\n" ; 
	}
	Point (const Point& obj){
		*this = obj ; 
		std::cout<<"Copying a Point...\n" ; 
	}
	~Point(){
		std::cout<<"Deleting a Point...\n" ; 
	}

	double get_x() const {return x;}
	double get_y() const {return y;}
};



double dist(const Point& A,const Point& B) {
		// 返回A和B的euclid距离
		double dist_x = A.get_x() - B.get_x() ; 
		double dist_y = A.get_y() - B.get_y() ;
		return sqrt(dist_x*dist_x + dist_y*dist_y) ; 
}

class Circle
{
private:
	/* data */
	Point c ; 
	double r ; 
public:
	Circle(const Point& c, const double& r=0)
	: c(c), r(r) 
	{
		std::cout<<"Creating a Circle...\n" ; 
	}
	Circle(const Circle& obj){
		*this = obj ; 
		std::cout<<"Copying a Circle...\n" ; 
	}
	~Circle(){
		std::cout<<"Deleting a Circle...\n" ; 
	}
	Point get_c() const {return c ; }
	double get_r() const {return r; } 
};

bool is_intersect(const Circle& O1,const Circle& O2){
	std::cout<<"\n" ; 
	return O1.get_r() +O2.get_r() > dist(O1.get_c(), O2.get_c()) ; 
}

int main(){
	Point A(1,0), B(0,1) ;
	std::cout<<"\n" ; 
	std::cout<<dist(A,B)<<"\n";  
	std::cout<<"\n" ; 
	Circle C1(Point(1,0), 2), C2(Point(4,0), 1.2);
	std::cout<<"\n" ; 
	std::cout<<is_intersect(C1, C2)<<"\n" ;  
	std::cout<<"\n" ; 
	C1.get_c() ; 
	std::cout<<"\n" ; 
	return 0 ; 
}
Creating a Point...
Creating a Point...

1.41421

Creating a Point...
Copying a Point...
Creating a Circle...
Deleting a Point...
Creating a Point...
Copying a Point...
Creating a Circle...
Deleting a Point...


Copying a Point...
Copying a Point...
Deleting a Point...
Deleting a Point...
1

Copying a Point...
Deleting a Point...

Deleting a Circle...
Deleting a Point...
Deleting a Circle...
Deleting a Point...
Deleting a Point...
Deleting a Point...

传递引用可以减少很多不必要的构造, 节省内存空间, 同时也提高效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值