不要返回局部變量的引用或指針董济,因?yàn)楹瘮?shù)返回時(shí),局部變量會(huì)被釋放班挖,引用或指針指向的內(nèi)容會(huì)失效衷模。
例如以下程序
#include <iostream>
using namespace std;
class A
{
public:
A(int a)
{
_num = a;
cout << "無(wú)參構(gòu)造函數(shù)" << endl;
}
A(const A& a)
{
this->_num = a._num;
cout << "拷貝構(gòu)造函數(shù)" << endl;
}
A& operator = (const A& a)
{
this->_num = a._num;
cout << "賦值運(yùn)算符重載" << endl;
return *this;
}
void print()
{
cout << this->_num << endl;
}
~A()
{
cout << "析構(gòu)函數(shù)" << endl;
}
private:
int _num;
};
- 返回局部變量
A boo(const A a)
{
cout << "A tmp = a" << endl;
A tmp = a;//調(diào)用拷貝構(gòu)造函數(shù)
cout << "return tmp" << endl;
return tmp;//外部會(huì)自動(dòng)定義一個(gè)臨時(shí)變量,以tmp初始化朋凉,所以調(diào)用拷貝構(gòu)造函數(shù)
}
int main()
{
cout << "A a" << endl;
A a(1);//調(diào)用無(wú)參構(gòu)造函數(shù)
cout << "A b(a)" << endl;
A b(a);//調(diào)用拷貝構(gòu)造函數(shù)
cout << "-----------------------------------------------" << endl;
b= boo(a);//當(dāng)把a(bǔ)值傳遞給形參時(shí)唠梨,會(huì)調(diào)用拷貝構(gòu)造函數(shù);返回時(shí)侥啤,會(huì)定義臨時(shí)變量以函數(shù)內(nèi)返回值初始化
b.print();
return 0;
}
運(yùn)行結(jié)果為:
A a
無(wú)參構(gòu)造函數(shù)
A b(a)
拷貝構(gòu)造函數(shù)
-----------------------------------------------
拷貝構(gòu)造函數(shù) //實(shí)參初始化形參当叭,調(diào)用拷貝構(gòu)造函數(shù)
A tmp = a
拷貝構(gòu)造函數(shù)
return tmp
拷貝構(gòu)造函數(shù) //局部變量tmp初始化內(nèi)存中臨時(shí)變量
析構(gòu)函數(shù) //析構(gòu)局部變量tmp
析構(gòu)函數(shù) //析構(gòu)局部變量a
賦值運(yùn)算符重載 //臨時(shí)變量賦值給b
析構(gòu)函數(shù) //析構(gòu)臨時(shí)變量
1
析構(gòu)函數(shù) //析構(gòu)main中的b
析構(gòu)函數(shù) //析構(gòu)main中的a
- 返回臨時(shí)變量的引用
A& boo(const A a)
{
cout << "A tmp = a" << endl;
A tmp = a;//調(diào)用拷貝構(gòu)造函數(shù)
cout << "return tmp" << endl;
return tmp;//外部會(huì)自動(dòng)定義一個(gè)臨時(shí)變量,以tmp初始化盖灸,所以調(diào)用拷貝構(gòu)造函數(shù)
}
int main()
{
cout << "A a" << endl;
A a(1);//調(diào)用無(wú)參構(gòu)造函數(shù)
cout << "A b(a)" << endl;
A b(a);//調(diào)用拷貝構(gòu)造函數(shù)
cout << "-----------------------------------------------" << endl;
b = boo(a);//當(dāng)把a(bǔ)值傳遞給形參時(shí)蚁鳖,會(huì)調(diào)用拷貝構(gòu)造函數(shù);返回時(shí)赁炎,會(huì)定義臨時(shí)變量以函數(shù)內(nèi)返回值初始化
b.print();
return 0;
}
運(yùn)行結(jié)果為:
A a
無(wú)參構(gòu)造函數(shù)
A b(a)
拷貝構(gòu)造函數(shù)
-----------------------------------------------
拷貝構(gòu)造函數(shù)
A tmp = a
拷貝構(gòu)造函數(shù)
return tmp //返回引用時(shí)不需要初始化臨時(shí)變量醉箕,只是一個(gè)別名
析構(gòu)函數(shù) //析構(gòu)局部變量tmp
析構(gòu)函數(shù) //析構(gòu)局部變量 a
賦值運(yùn)算符重載 //tmp的引用賦值給b
-858993460 //由于tmp已經(jīng)被析構(gòu),所以是錯(cuò)誤值
析構(gòu)函數(shù) //析構(gòu)b
析構(gòu)函數(shù) //析構(gòu)a
總結(jié)
返回局部變量與返回局部變量的引用有所不同
- 返回局部變量會(huì)先將返回值初始化一個(gè)臨時(shí)變量徙垫,函數(shù)返回后讥裤,局部變量被釋放,但臨時(shí)變量還存在姻报。根據(jù)需要訪問(wèn)或者不訪問(wèn)臨時(shí)變量己英,在下一條語(yǔ)句,臨時(shí)變量自動(dòng)銷毀吴旋。
- 而返回引用時(shí)损肛,該引用是局部變量的一個(gè)別名厢破,不會(huì)有臨時(shí)變量治拿,隨著函數(shù)返回后局部變量被析構(gòu),引用也失去意義劫谅。
- 所以不要返回局部變量的引用
引用
- http://bbs.csdn.net/topics/390153974
- C++ Primer