標籤:
匿名對象:臨時的對象,一般都是在構造完就被釋放掉了(有特殊情況,傳回值最佳化)
1. 傳回值最佳化:若是函數返回的匿名對象返回時候有同類型的新對象接上,則該匿名對象被轉化為新對象。
#include "iostream"using namespace std;class A{public: A (int _a=0, int _b=0) { this->a1 = _a; this->b1 = _b; cout << "construct function called!" << endl; } A (A &obj) { cout << "copy_constructor function called!" << endl; } ~A() { cout << "objext destory function called!" << endl; }protected:private: int a1; int b1;};// 函數傳回值產生匿名對象A g(){ A a2(10,19); return a2;}// 測試一: 匿名對象用來初始化一個新對象。void Test1(){ A a1 = g();}// 測試二: 用等號初始化一個新對象void Test2(){ A a3; a3 = g();}int main(){ Test1(); Test2(); return 0;}
Test1結果:調用了兩次建構函式,兩次解構函式
construct function called!構造a2
copy_constructor function called!構造匿名a2的匿名對象
objext destory function called!析構局部變數a2
objext destory function called!析構a1(其實就是a2的匿名對象)
**********************************************************/
Test2結果:調用了三次建構函式三次解構函式
construct function called!構造a3
construct function called!構造a2
copy_constructor function called!構造匿名a2的匿名對象
objext destory function called!析構局部變數a2
objext destory function called!析構a2的匿名對象
**********************************************************/
2.沒有對象名:普通情況,構造完成之後就直接被析構
#include "iostream"using namespace std;class A{public: A (int _a=0, int _b=0) { this->a1 = _a; this->b1 = _b; cout << "construct function called!" << endl; } A (A &obj) { cout << "copy_constructor function called!" << endl; } ~A() { cout << "objext destory function called!" << endl; } void printf() { cout << this->a1 << " " << this->b1 << endl; }protected:private: int a1; int b1;};int main(){ A(10, 10).printf(); cout << "在此處列印之前,匿名對象就已經被析構!" << endl; return 0;}
需要注意的點:
1. 所有形參都提供了預設的實參的建構函式也定義了預設建構函式,而這樣的建構函式形參列表是有形參的(有參建構函式的形參有初始值的話,就相當於寫了預設建構函式)
2. 匿名對象是否被析構看傳回值是否有對象來接上
3. 拷貝建構函式的三種應用情境:
<1> a1 = a2 (區分兩種不同的情況: A aa; A bb = aa;會 //bb = aa; 不會 ):一個對象初始化另一個對象時
<2> func(A a1):當對象作為函數參數時
<3> A a2 = func():當函數傳回值為對象時(涉及到匿名對象的問題)
4. 特別注意:等號操作和對象的初始化是兩個不同的概念
C++臨時匿名對象