码迷,mamicode.com
首页 > 其他好文 > 详细

引用与析构,通过引用减少临时变量

时间:2015-07-31 13:02:35      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:c++   复制构造函数   参数   临时变量   生命周期   

通过引用可以大大减少创建临时变量的次数,从而提高程序运行的效率。

本文探讨创建通过引用减少创建临时变量的次数,与临时变量的生命周期。


测试一:不使用引用并且返回的临时变量不用引用保存。


#include <cstdio>
#include <iostream>

using namespace std;


class Point{
private:
	static int count;
	int x;

public:
	Point() {
		printf("constructor called\n");
		x = ++Point::count;
	}

	Point(const Point &B){
		printf("copy constructor called\n");
		x  = ++Point::count;
	}


	~Point(){
		printf("xx %d\n",x);
	}

	Point XX(Point x)
	{
		//this->x = 0;

		return x;
	}

	void print()const{
		printf("%d\n", x);
	}


};

int Point::count = 0;

int main(){
	Point pt;
	Point pk;
	//Point &pz = 
	pt.XX(pk);
	//pz.print();
	pt.print();

	return 0;
}


运行截图

技术分享

通过以上输出,可以看出发生了4次析构,说明产生了两个临时变量。

3,4为临时变量。

第一个临时变量为3, 3为传递进来的参数调用了复制构造函数,

生命周期:在函数执行完成后即进行析构。

第二个临时变量为4, 4为返回的参数, 其调用了复制构造函数

生命周期:在完成对原有变量赋值(隐含复制操作)即进行析构。




测试二:不使用引用并且返回的临时变量并使用引用保存。

#include <cstdio>
#include <iostream>

using namespace std;


class Point{
private:
	static int count;
	int x;

public:
	Point() {
		printf("constructor called\n");
		x = ++Point::count;
	}

	Point(const Point &B){
		printf("copy constructor called\n");
		x = ++Point::count;
	}


	~Point(){
		printf("xx %d\n", x);
	}

	Point XX(Point x)
	{
		//this->x = 0;

		return x;
	}

	void print()const{
		printf("%d\n", x);
	}


};

int Point::count = 0;

int main(){
	Point pt;
	Point pk;
	Point &pz = pt.XX(pk);
	//pz.print();
	pt.print();

	printf("haha\n");

	return 0;
}



运行截

技术分享

通过以上输出,可以看出发生了4次析构,说明产生了两个临时变量。

3,4为临时变量。

第一个临时变量为3, 3为传递进来的参数调用了复制构造函数,

生命周期:在函数执行完成后即进行析构。

第二个临时变量为4, 4为返回的参数, 其调用了复制构造函数

生命周期:在完成对原有变量赋值(隐含复制操作)由于又使用了引用对其(临时变量)保存,故该临时变量生存周期同引用生存周期。

在函数最后进行析构,但由于声明变量的顺序与析构顺序相反,析构序号为4,2,1



测试三:对传进来的参数使用引用,返回值不使用引用,返回的临时变量(引用)使用引用保存。

#include <cstdio>
#include <iostream>

using namespace std;


class Point{
private:
	static int count;
	int x;

public:
	Point() {
		printf("constructor called\n");
		x = ++Point::count;
	}

	Point(const Point &B){
		printf("copy constructor called\n");
		x = ++Point::count;
	}


	~Point(){
		printf("xx %d\n", x);
	}

	Point XX(Point &x)
	{
		//this->x = 0;

		return x;
	}

	void print()const{
		printf("%d\n", x);
	}


};

int Point::count = 0;

int main(){
	Point pt;
	Point pk;
	Point &pz = pt.XX(pk);
	//pz.print();
	pt.print();

	printf("haha\n");

	return 0;
}

技术分享


通过以上输出,可以看出发生了3次析构,说明产生了一个临时变量。

3为临时变量。

第一个临时变量3, 3为返回的参数, 其调用了复制构造函数

生命周期:在完成对原有变量赋值(隐含复制操作)由于又使用了引用对其(临时变量)保存,故该临时变量生存周期同引用生存周期。

在函数最后进行析构,但由于声明变量的顺序与析构顺序相反,析构序号为3,2,1



测试四:对传进来的参数不使用引用,返回值使用引用,返回的临时变量(引用)使用引用保存。

#include <cstdio>
#include <iostream>

using namespace std;


class Point{
private:
	static int count;
	int x;

public:
	Point() {
		printf("constructor called\n");
		x = ++Point::count;
	}

	Point(const Point &B){
		printf("copy constructor called\n");
		x = ++Point::count;
	}


	~Point(){
		printf("xx %d\n", x);
	}

	Point& XX(Point x)
	{
		//this->x = 0;

		return x;
	}

	void print()const{
		printf("%d\n", x);
	}


};

int Point::count = 0;

int main(){
	Point pt;
	Point pk;
	Point &pz = pt.XX(pk);
	//pz.print();
	pt.print();

	printf("haha\n");

	return 0;
}

技术分享

通过以上输出,可以看出发生了3次析构,说明产生了一个临时变量。

3为临时变量。

第一个临时变量3, 3为传递进去的对象, 其调用了复制构造函数

生命周期:在函数调用的时候使用了复制构造函数,函数执行完成后立即进行析构。




测试五:对传进来的参数使用引用,返回值使用引用,返回的临时变量(引用)使用引用保存。

#include <cstdio>
#include <iostream>

using namespace std;


class Point{
private:
	static int count;
	int x;

public:
	Point() {
		printf("constructor called\n");
		x = ++Point::count;
	}

	Point(const Point &B){
		printf("copy constructor called\n");
		x = ++Point::count;
	}


	~Point(){
		printf("xx %d\n", x);
	}

	Point& XX(Point &x)
	{
		//this->x = 0;

		return x;
	}

	void print()const{
		printf("%d\n", x);
	}


};

int Point::count = 0;

int main(){
	Point pt;
	Point pk;
	Point &pz = pt.XX(pk);
	//pz.print();
	pt.print();

	printf("haha\n");

	return 0;
}

技术分享

通过以上输出,可以看出发生了2次析构,说明没产生临时变量。



测试六:对传进来的参数不使用引用,返回值使用引用,返回的临时变量(引用)使用引用保存。

#include <cstdio>
#include <iostream>

using namespace std;


class Point{
private:
	static int count;
	int x;

public:
	Point() {
		printf("constructor called\n");
		x = ++Point::count;
	}

	Point(const Point &B){
		printf("copy constructor called\n");
		x = ++Point::count;
	}


	~Point(){
		printf("xx %d\n", x);
	}

	Point& XX(Point x)
	{
		//this->x = 0;

		return x;
	}

	void print()const{
		printf("%d\n", x);
	}


};

int Point::count = 0;

int main(){
	Point pt;
	Point pk;
	Point &pz = pt.XX(pk);
	pz.print();
	pt.print();

	printf("haha\n");

	return 0;
}

技术分享

通过以上输出,可以看出发生了3次析构,说明产生了一个临时变量。

3为临时变量。

第一个临时变量3, 3为传递进去的对象, 其调用了复制构造函数

生命周期:在函数调用的时候使用了复制构造函数,函数执行完成后立即进行析构。而我使用一个引用对返回的临时变量进行了保存,但在完成

赋值之后

Point &pz = pt.XX(pk);

即这条语句之后,该临时变量进行了析构,之后调用的print 函数打出了被释放后的内存区域,需要十分注意



测试七:对传进来的参数使用引用,返回值不使用引用,返回的临时变量(引用)使用引用保存。

#include <cstdio>
#include <iostream>

using namespace std;


class Point{
private:
	static int count;
	int x;

public:
	Point() {
		printf("constructor called\n");
		x = ++Point::count;
	}

	Point(const Point &B){
		printf("copy constructor called\n");
		x = ++Point::count;
	}


	~Point(){
		printf("xx %d\n", x);
	}

	Point XX(Point &x)
	{
		//this->x = 0;

		return x;
	}

	void print()const{
		printf("%d\n", x);
	}


};

int Point::count = 0;

int main(){
	Point pt;
	Point pk;
	Point &pz = pt.XX(pk);
	pz.print();
	pt.print();

	printf("haha\n");

	return 0;
}
技术分享

通过测试1-6,我们不难发现由于返回的对象为赋值的对象,该临时对象的生命周期为引用的生命周期,所以在pritnf("haha\n");

后进行释放,即main结束时进行释放。




通过以上测试,可以看出

1.若函数传递的参数为对象,且需要返回该对象。

应该在函数传递参数以及函数返回时都使用引用,这样会减少两次临时变量的产生。(测试一~测试五)


2.若对参数调用复制构造函数,返回使用引用,在赋值完成之后,该复制构造函数产生的临时变量的内存空间就被回收(见测试六)

版权声明:本文为博主原创文章,未经博主允许不得转载。

引用与析构,通过引用减少临时变量

标签:c++   复制构造函数   参数   临时变量   生命周期   

原文地址:http://blog.csdn.net/u010003835/article/details/47166449

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!