C++中函數返回臨時對象和本地對象的區別
在C++中如果函數返回值是對象的時候,那麼該直接返回臨時對象呢,還是先在函數體內構造好一個本地
對象,然後返回。如果可以直接返回臨時對象,那麼我們就返回臨時對象來代替返回本地對象,因爲這樣代碼
的效率會比返回本地對象的效率高。以下通過代碼說明兩者的區別 (更多講解在註釋中已說明):
1.返回本地對象代碼示例:
#include <iostream>
using namespace std;
class A {
public:
int m_k;
int m_t;
A(int k, int t) :m_k(k), m_t(t) {
cout << "construct...." << endl;
}
~A() {
cout << "destruct...." << endl;
}
A(A &a) {
cout << "copy construct..." << endl;
}
};
// 如果函數返回值是一個對象,要考慮return語句的效率
A getObj() {
/************** 返回本地對象 ****************/
/* 以下這種寫法實際上執行了三步:
1. 構造本地對象a
2. 調用拷貝構造,將本地對象a拷貝到外部存儲器
3. 調用析構函數析構本地對象a
*/
/******************************************/
A a(3, 4);
return a;
}
int main() {
getObj(); // 外部存儲單元
return 0;
}
運行結果:
2.返回臨時對象代碼示例:
#include <iostream>
using namespace std;
class A {
public:
int m_k;
int m_t;
A(int k, int t) :m_k(k), m_t(t) {
cout << "construct...." << endl;
}
~A() {
cout << "destruct...." << endl;
}
A(A &a) {
cout << "copy construct..." << endl;
}
};
// 如果函數返回值是一個對象,要考慮return語句的效率
A getObj() {
/*********** 直接返回臨時對象 *************/
// 編譯器直接把臨時對象創建並初始化在外部
// 存儲單元(主調函數的棧幀上)中,省去了拷
// 貝和析構的花費,提高了效率
/*****************************************/
return A(3, 4);
}
int main() {
getObj(); // 外部存儲單元
return 0;
}
運行結果:
所以總的來說返回臨時對象能減少多餘的拷貝構造函數和析構函數的調用,從而提高了效率。