1. 程式人生 > >C++基本函數的調用優化(構造、拷貝構造、賦值)

C++基本函數的調用優化(構造、拷貝構造、賦值)

tor ostream 結束 一個 space copy 總結 clas 但是

合理的函數可提升時間和空間的利用率

//Test1.h
#include<iostream>
using namespace std;
struct ST
{
private:
	int a;
	short b;
public:
	ST(int a=0, short b=0):a(a),b(b)
	{
		this->a = a;
		this->b = b;
		cout<<"Object was Built. "<<this<<endl;
	}
	~ST()
	{
		cout<<"Object was Free. "<<this<<endl;
	}
	ST(const ST &t);
	ST& operator=(const ST &t);
	int Get_a();
};
ST::ST(const ST &t)
{
	this->a = t.a;
	this->b = t.b;
	cout<<"Object was Copy. "<<this<<endl;
}
ST& ST::operator=(const ST &t)
{
	cout<<"Assign:"<<this<<" = "<<&t<<endl;
	if(this != &t)
	{
		this->a = t.a;
		this->b = t.b;
	}
	return *this;
}
int ST::Get_a()
{
	return this->a;
}

 

#include<iostream>
#include"Test1.h"
using namespace std;
ST fun(ST t)
{
int value = t.Get_a();
ST tmp(value);
return tmp;
} void main() { ST t(12,13); ST t1(t); ST t2; t2 = fun(t); }

運行結果及分析①

技術分享圖片

1:對象t的構造和析構

2:對象t1的拷貝構造與析構

3:t2的構造與析構

ST fun(ST t)
{
	int value = t.Get_a();
	ST tmp(value);
	return tmp;
}

4:fun()函數的參數為對象,調用拷貝構造函數創建臨時對象,其在fun函數結束後被析構掉

5:fun()函數內使用ST實例化類tmp,其在函數結束後被析構掉

6:函數返回時調用拷貝構造函數創建一個臨時對象,該對象在完成賦值後才被析構掉,所以6並不是tmp,這個臨時對象可以生存到函數結束

運行結果及分析②

ST fun(ST t)
{
	int value = t.Get_a();
	return ST (value);
}

改變的代碼僅有fun()函數變化

技術分享圖片

1,2,3,4與相同,不再贅述

這裏的改變是不再創造有名對象,而是直接返回一個無名臨時對象,將①的5,6合二為一,所以返回時僅需要使用構造函數構造一個無名臨時對象,

在賦值後被析構掉。省掉了①中的拷貝構造。

運行結果及分析③

ST fun(ST &t)
{
	int value = t.Get_a();
	return ST(value);
}

與②相比,只改變了參數

技術分享圖片

1,2,3同上

當使用引用傳遞參數時,就不需要使用拷貝構造函數創建臨時對象,將②的4省掉,③的4與②的4作用相同

運行結果及分析④

ST fun(ST &t)
{
int value = t.Get_a();
return ST(value);
}
void main() { ST t(12,13); ST t1(t); ST t2 = fun(t); }

這裏與③的不同是將主函數修改

主函數內st2從先使用構造函數初始化,再賦值,變成了直接使用賦值為其初始化

技術分享圖片

在前面我們知道

ST t(1,2);

ST st;

st = t;

ST t(1,2);

ST st = t;

實例化st 的不同是 前者先構造再拷貝構造,後者只需要拷貝構造。

所以,主函數使用了上例子後者的寫法,可以直接省去t2的構造,直接拷貝構造,但是關鍵問題就在這裏,

由於fun()函數返回的對象是一個無名的臨時對象,所以編譯器直接讓其初始化t2,而省去拷貝構造的過程。

 總結

  1.從②我們可以知道,函數使用無名臨時對象作為返回值,比在函數內創建有名臨時對象更快,更節省空間,提升效率。

   2.從③我們可以看出來在函數參數為對象時,使用引用可以省掉拷貝構造。

   3.從④可以知道,在使用對象對對象進行賦值時,直接使用拷貝構造時最快的方法。這同時也說明了,無名的臨時對象有時候可以被當作中間變量,而不需要從頭進行拷貝構造工作。

C++基本函數的調用優化(構造、拷貝構造、賦值)