臨時性物件 Temporary Objects

2021-06-14 10:23:47 字數 2144 閱讀 3417

對於乙個下面這樣的程式片段:

ta,

b;tc

=a+b

;

死板一點來講,它應當產生乙個臨時物件用來儲存a+b的結果,然後以臨時對 象作為初值呼叫拷貝建構函式初始化物件c。而實際上編譯器更願意直接呼叫 拷貝建構函式的方式將a+b的值放到c中,這樣就不需要臨時物件,和它的構造 函式和拷貝建構函式的呼叫了。

更進一步,如果operator +的定義符合nrv優化的條件,那麼nrv優化的開啟, 將使得拷貝建構函式的呼叫和named object的析構函式都免了。期間詳情可 以參見」nrv優化」。也就是說對於上面那種情形在我們的**中是不產生 臨時物件的。但是對於乙個情況非常類似的賦值操作語句c = a+b,卻有很 大的差別,那個臨時變數是不能省的

不能忽略臨時物件,反而導致如下過程:

// pseudo c++ code  

// t temp = a + b;

ttemp;a

.operator+(

temp,b

);// @1 [^注1]

// c = temp c.

operator=(

temp

);// @2

temp.t

::~t

();

在**@1處,表明以拷貝建構函式或nrv方式將結果儲存的臨時物件中。為什 麼不能省略那個臨時物件,比如直接這樣:

c.t

::~t

();c.t

::t(a

+b);

這不是更高效,更簡潔的方式嗎?不行,其原因在於,拷貝建構函式、析構 函式以及賦值操作符都可以由使用者提供,沒有人能保證,析構函式加拷貝 建構函式的組合和賦值操作符具有相同的含義。所以:t c=a+b總是比c = a + b更有效率。

對於乙個沒有出現目標物件的表示式a + b,那麼產生乙個臨時物件來儲存 運算結果,則是非常必要的。

很多時候,產生臨時物件是必不可少的,但是何時摧毀乙個臨時物件才是最 佳行為呢?過早或過晚都不太適合,過早有可能使得程式錯誤,過晚的話又 使得資源沒有得到及時**。對於下面的程式:

strings1(

"hello "

),s2

("world "

),s3

("by adoo"

);std

::cout

s3<<

std::

endl

;

顯然儲存s1+s2結果的臨時物件,如果在與s3進行加法之前析構,將會帶來 **煩。於是c++標準中有一條:

完整的表示式,是指涵括的表示式中最外圍的那個。我們再看上面那個字元 串相加的表示式,當計算完成,而cout還未呼叫,此時我們析構掉儲存最終 結果的臨時物件,豈不悲劇。其實上面的規定還有兩個例外:

凡含有表示式執行結果的臨時性物件,應該儲存到object的初始化操作 完成為止。

如果臨時性物件被繫結與乙個引用,臨時物件將殘留,直至被初始化的 引用的生命結束,或直到臨時物件的生命週期結束——視哪一種情況先達 到,對應於這種情況:

::

strings1(

"hello "

);::

string&s

=s1+"world"

;

侯捷認為此處為 lippman 的錯誤,他認為應該為temp.operator + ( a, b )但我以為是侯捷並沒有理解lippman的意思,回 顧一下,《深度探索物件模型》2.3講到的返回值初始化(return value initialization)——返回值將作為乙個額外的引數提供給函式,來傳回函式內 部的值,也就是說對於乙個 operator + 操作符t t::operator+ (const t& right)將轉化為void t::operator+ (t &result ,const t& right)所以temp=a+ba.operator+( temp, b )還是temp.operator+( a, b )自然不言而喻。

第六章 臨時性物件

1.是否會產生乙個臨時物件,視編譯器的進取性和 操作發生時的語境而定。c 標準中指出編譯器對臨時性物件有完全的自由度。2.在新開闢的記憶體上以拷貝的方式構造物件時,幾乎所有編譯器都不會產生乙個臨時性物件。t c a b 其中加法運算子形式如下 t operator const t const t 或...

C 物件模型 臨時性物件 第六章

如果有乙個函式,形式如下 t operator const t const t 以及兩個t objects,a和b,那麼 a b 可能會導致乙個臨時性物件,以放置傳回的物件.是否會導致乙個臨時性物件,視編譯器的進取性 aggressiveness 以及上述操作發生時的程式上下關係 program c...

匿名物件?臨時物件?

關於匿名物件與臨時物件,這個概念不是絕對的,概念的區分往往十分拗口難記。要根據作用域,生存時間和用法來來決定 工作多年這些拗口的概念我從來沒有真的記住過,也沒有乙個部落格講清楚他們的區別。這裡我們參考 effective c 中得稱謂,稱之為區域性物件。但是區域性也是有範圍得。下面論證。1無名則無份...