關於匿名物件與臨時物件,這個概念不是絕對的,概念的區分往往十分拗口難記。要根據作用域,生存時間和用法來來決定;工作多年這些拗口的概念我從來沒有真的記住過,也沒有乙個部落格講清楚他們的區別。這裡我們參考《effective c++》中得稱謂,稱之為區域性物件。但是區域性也是有範圍得。下面論證。
1無名則無份-臨時物件臨時生存
2名正則言順-起個名字活得久
3非分之想-不要越界。
4編譯器的能力5原則
假設我們有這樣乙個類:
class下面我們將使用不同的方式來辯證的討論上面類在使用中構建物件的型別:test
~test()
test(
const test &one)
test &operator =(const test &one)
void distestval() const
const
void * getthis() const
private
:
intm_test;
};
臨時物件/匿名物件:
1)無名則無份:
int執行結果:main()
執行getchar()
匿名物件 的生命週期轉瞬即逝,其生存空間就是**所在的行,本質上匿名物件就是建構函式得呼叫,函式呼叫完成,其生命週期也就結束了。
看到了嗎,在這裡我們使用getchar來阻塞main函式的結束,test(2)這個物件在main函式還沒有結束時就析構了,其生命週期曇花一現,其生存空間就時**所在的行。如果我們構建乙個正常的物件於main函式中,其生命週期同main函式。但是匿名物件就不行。沒有名字便沒有生存的資格。當然我們很少使用這種匿名物件,但是,其可以發起函式呼叫。如果這個物件對外提供指標,由於其短暫的生命週期與生存空間,等到我們能用指標的時候,它卻已經失效了。
2)名正則言順:
如何延長乙個匿名物件的生命週期呢?他與常規物件的本質區別就是沒有乙個名字。所以給它取個名字吧。
int執行結果:main()
這裡我們給test(2)起了別名,當然它也沒有其他的名字,其宣告週期便同main了。其效果與test tobj(2)是一樣的,只不過其型別是cosnt test&的。
3)非分之想
按照上面的規則,在乙個作用域中,乙個匿名物件只要有名字,便可以活下來,那如果跨作用域呢?
consttest returntemp()
intmain()
執行結果:結果分析:以上**1處已經析構了,我們拿到了乙個已經析構物件的引用。2處用這個引用呼叫函式依然獲取到了「正確」值。
使用3處析構物件在4處拷貝構造了另乙個物件,函式呼叫結果也沒報錯。
匿名物件與臨時物件都是相對的概念,當這個無名物件產生於自己的作用域空間時,我們叫它匿名物件,一來沒有名字,而來確實構造了乙個物件。
臨時物件定義可以認為是從時間角度出發對乙個匿名物件的另一種稱謂。在乙個作用域內,匿名物件有名字了(const t &型別),不出作用域,其生命週期同作用域。
4)編譯器的能力問題:
以上用析構的對編譯器沒有報錯,執行結果也無異常,這真是令人恐怖的地方。試想你編寫過的程式,是不是執行的一段時間突然閃退,或者突然崩潰呢?
很多這種可怕的錯誤,編譯器是檢查不出來的,我在windows和linux使用qt-ide和 gcc,兩者編譯都沒有報錯。所以這種定時炸彈說不定什麼時候**了。
編譯器能力有限,不要指望編譯器能幫你把所有錯誤檢查出來,有時連警告也沒有!
5)原則:
就此不管臨時物件也罷,匿名物件也罷,你只要記住以下原則:
const t &能夠接受乙個臨時物件的引用而不是臨時物件!
函式棧上的物件一定不要返回指標或者引用。
很多時候,返回物件並沒有太多問題,至於效能問題,linux和windows平台都有rvo和nrvo機制。比你想象的效能好很多。關於返值優化這裡不展開討論。
《effective c++ 》第二版中文版 條款31
援引:區域性物件 ---
-- 顧名思義 ---- 僅僅是區域性的。也就是說,區域性物件是在被定義時建立,在離
開生命空間時被銷毀的。所謂生命空間,是指它們所在的函式體。當函式返回
時,程式的控制離開了這個空間,所以函式內部所有的區域性物件被自動銷毀。
因此,如果返回區域性物件的引用,那個區域性物件其實已經在函式呼叫者使用它
之前被銷毀了。
C 臨時匿名物件
匿名物件 臨時的物件,一般都是在構造完就被釋放掉了 有特殊情況,返回值優化 1.返回值優化 若是函式返回的匿名物件返回時候有同型別的新物件接上,則該匿名物件被轉化為新物件。1 include iostream 2 using namespace std 34 classa5 13 a a obj 1...
物件導向2 匿名物件
概念 沒有名字的物件,沒有被變數引用指向的物件空間。語法 new 類名 public class nimingdemo public class demo 自定義類作為引數型別使用 public class nimingdemo public class demo public static voi...
C 臨時物件
臨時物件的產生 1.用建構函式作為隱式型別轉換函式時。2.建立乙個沒有名字的物件時。直接寫下 ctempobj 輸出 init obj exit obj 不單調用了建構函式,還呼叫了析構函式.既然是物件也可以這樣使用 ctempobj fun 不過這樣使用可要小心了 new ctempobj fun...