您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“C++中的臨時(shí)對(duì)象舉例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“C++中的臨時(shí)對(duì)象舉例分析”吧!
一、以值的方式給函數(shù)傳參
1、按值傳遞
按值傳遞時(shí),首先將需要傳給函數(shù)的參數(shù),調(diào)用拷貝構(gòu)造函數(shù)創(chuàng)建一個(gè)副本,所有在函數(shù)里的操作都是針對(duì)這個(gè)副本,也正是因?yàn)檫@個(gè)原因,在函數(shù)體力對(duì)該副本進(jìn)行任何操作都不會(huì)影響原參數(shù)。
2、按引用傳遞
引用則不然,它是對(duì)象本身,只是一個(gè)別名而已??梢詤⒖贾羔樅鸵檬裁磿r(shí)候用?來理解引用。
3、例子
#include <iostream>
using namespace std;
class TempObj {
public:
TempObj(int m = 0, int n = 0);
TempObj(TempObj& to)
{
cout << "Copy Constructor" << endl;
m_Number = to.m_Number;
m_Size = to.m_Size;
}
~TempObj()
{
cout << "Deconstructor" << endl;
}
int GetSum(TempObj ts);
public:
int m_Number;
int m_Size;
};
TempObj::TempObj(int m,int n)
{
cout << "Default constructor" << endl;
m_Number = m;
m_Size = n;
cout << "m_Number=" << m_Number <<" "<< "m_Size=" << m_Size << endl;
}
int TempObj::GetSum(TempObj ts)
{
int tmp = ts.m_Number + ts.m_Size;
ts.m_Number = 1000;
return tmp;
}
void main()
{
TempObj tm(10,20);
cout << "sum=" << tm.GetSum(tm) << endl;
cout << "tm.m_Number=" << tm.m_Number << endl;
}
運(yùn)行結(jié)果:
這里寫圖片描述
通過以上程序可以看到調(diào)用了拷貝構(gòu)造函數(shù),這是tm在傳給GetSum函數(shù)做參數(shù)時(shí)調(diào)用的。此時(shí)調(diào)用拷貝構(gòu)造函數(shù)創(chuàng)建了一個(gè)副本,為GetSum函數(shù)體內(nèi)使用。通過運(yùn)行結(jié)果可以看到,在GetSum函數(shù)體內(nèi)對(duì)tm副本進(jìn)行的修改并沒有影響到tm本身。
可以按照如下方式修改,函數(shù)聲明和定義都需要改:
int GetSum(TempObj& ts);
int TempObj::GetSum(TempObj& ts)
{
int tmp = ts.m_Number + ts.m_Size;
ts.m_Number = 1000;//此時(shí)通過ts這個(gè)引用對(duì)象本身
return tmp;
}
運(yùn)行結(jié)果:
這里寫圖片描述
通過傳遞常量引用,減少了一次臨時(shí)對(duì)象的創(chuàng)建。這個(gè)改動(dòng)也許很小,但對(duì)多繼承的對(duì)象來說在構(gòu)建時(shí)要遞歸調(diào)用所有基類的構(gòu)造函數(shù),這對(duì)于性能來說是個(gè)很大的消耗。
二、類型轉(zhuǎn)換生成的臨時(shí)對(duì)象
#include <iostream>
using namespace std;
class TempObj {
public:
TempObj(int m = 0, int n = 0);
TempObj(TempObj& to)
{
cout << "Copy Constructor" << endl;
m_Number = to.m_Number;
m_Size = to.m_Size;
}
~TempObj()
{
//cout << "Deconstructor" << endl;
}
int GetSum(TempObj &ts);
public:
int m_Number;
int m_Size;
};
TempObj::TempObj(int m,int n)
{
cout << "Default constructor" << endl;
m_Number = m;
m_Size = n;
cout << "m_Number=" << m_Number <<" "<< "m_Size=" << m_Size << endl;
}
int TempObj::GetSum(TempObj &ts)
{
int tmp = ts.m_Number + ts.m_Size;
ts.m_Number = 1000;
return tmp;
}
void main()
{
TempObj tm(10,20),sum;
sum = 1000;
cout << "sum=" << tm.GetSum(sum) << endl;
}
運(yùn)行結(jié)果:
這里寫圖片描述
main函數(shù)創(chuàng)建了兩個(gè)對(duì)象,但輸出卻調(diào)用了三次構(gòu)造函數(shù)。關(guān)鍵在sum = 1000;本身1000和sum類型不符,但編譯器為了通過編譯以1000為參數(shù)調(diào)用構(gòu)造函數(shù)創(chuàng)建了一個(gè)臨時(shí)對(duì)象。
解決辦法:
void main()
{
TempObj tm(10,20);
TempObj sum = 1000;
cout << "sum=" << tm.GetSum(sum) << endl;
}
輸出結(jié)果:
這里寫圖片描述
此時(shí),“=”號(hào)由原本的賦值變成了構(gòu)造。對(duì)sum的構(gòu)造推遲了,當(dāng)定義TempObj sum時(shí),在main的棧中為sum對(duì)象創(chuàng)建了一個(gè)預(yù)留空間,而我們用1000調(diào)用構(gòu)造函數(shù)時(shí),此時(shí)的構(gòu)造函數(shù)是在sum預(yù)留的空間中進(jìn)行的,因此減少了一次臨時(shí)對(duì)象的創(chuàng)建。
三、函數(shù)返回一個(gè)對(duì)象
當(dāng)函數(shù)需要返回一個(gè)對(duì)象,它會(huì)在棧中創(chuàng)建一個(gè)臨時(shí)對(duì)象,存儲(chǔ)函數(shù)的返回值。
#include <iostream>
using namespace std;
class TempObj {
public:
TempObj(int m = 0);//default constructor
TempObj(TempObj& to)
{
cout << "copy constructor" << endl;
m_Number = to.m_Number;
}
TempObj& operator=(TempObj& to)
{
cout << "operator=(TempObj& to)" << endl;
m_Number = to.m_Number;
return *this;
}
~TempObj()
{
}
public:
int m_Number;
};
TempObj::TempObj(int m)
{
cout << "default constructor" << endl;
m_Number = m;
cout << "m_Number=" << m_Number << endl;
}
TempObj Double(TempObj& to)
{
TempObj tmp;
tmp.m_Number = to.m_Number*2;
return tmp;
}
void main()
{
TempObj tm(10), sum;
cout << endl;
sum = Double(tm);
cout << endl;
cout << "sum.m_Number=" << sum.m_Number << endl;
}
運(yùn)行結(jié)果:
這里寫圖片描述
分析:
上述代碼sum = Double(tm);這條語句生成了兩個(gè)對(duì)象。第一,顯示創(chuàng)建了一個(gè)tmp臨時(shí)對(duì)象(TempObj tmp;);其次,將temp對(duì)象返回,返回過程中調(diào)用了拷貝構(gòu)造函數(shù)創(chuàng)建一個(gè)返回對(duì)象(return tmp;);第三,將返回結(jié)果通過調(diào)用賦值運(yùn)算符重載函數(shù)賦值給sum(sum = Double(tm);),該步驟沒有創(chuàng)建對(duì)象。可參考C++賦值運(yùn)算符重載函數(shù)和拷貝構(gòu)造函數(shù)進(jìn)行理解。
注意,第二步創(chuàng)建的返回對(duì)象是難以避免的,此處如果是返回引用,在函數(shù)里創(chuàng)建的局部對(duì)象,在返回時(shí)就被銷毀了,這時(shí)若再引用該對(duì)象就會(huì)產(chǎn)生未知錯(cuò)誤。
可以直接操作返回對(duì)象,具體如下:
TempObj Double(TempObj& to)
{
return to.m_Number*2;
}
也可以結(jié)合上面講到的類型轉(zhuǎn)換生成臨時(shí)對(duì)象解決辦法進(jìn)行優(yōu)化,具體修改如下:
#include <iostream>
using namespace std;
class TempObj {
public:
TempObj(int m = 0);//default constructor
TempObj(TempObj& to)
{
cout << "copy constructor" << endl;
m_Number = to.m_Number;
}
TempObj& operator=(TempObj& to)
{
cout << "operator=(TempObj& to)" << endl;
m_Number = to.m_Number;
return *this;
}
~TempObj()
{
}
public:
int m_Number;
};
TempObj::TempObj(int m)
{
cout << "default constructor" << endl;
m_Number = m;
cout << "m_Number=" << m_Number << endl;
}
TempObj Double(TempObj& to)
{
return to.m_Number*2;
}
void main()
{
TempObj tm(10);
cout << endl;
TempObj sum = Double(tm);
cout << endl;
cout << "sum.m_Number=" << sum.m_Number << endl;
}
運(yùn)行結(jié)果如下:
這里寫圖片描述
分析發(fā)現(xiàn)減少了一次構(gòu)造函數(shù)調(diào)用tmp,一次拷貝構(gòu)造函數(shù)(tmp拷貝給返回對(duì)象)調(diào)用和一次賦值運(yùn)算符重載函數(shù)調(diào)用。這是因?yàn)榉祷貙?duì)象直接使用編譯器為sum預(yù)留的空間,所以減少了返回臨時(shí)對(duì)象的生成,返回對(duì)象即是sum,返回對(duì)象的創(chuàng)建即是sum對(duì)象的創(chuàng)建。
到此,相信大家對(duì)“C++中的臨時(shí)對(duì)象舉例分析”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。