2 編譯器會減少臨時物件
3 小結
首先,我們先看一段**,我們使用帶引數的建構函式實現不帶引數的建構函式
#include
class
test
test()
~test()
void
print()
private
:int x;};
intmain()
不帶引數的構造函式呼叫了帶引數的建構函式,將 x 初始化為 0。
編譯執行:
$ g++ 15-1.cpp -o 15-1
$ ./15-1
~test()
x = 21928
~test()
我們可以看到,類的成員變數 x 並沒有被初始化為 0,而是隨機值。並且呼叫了兩次析構函式。這是為什麼呢?
解析:那對於上面的**,如果初始化工作非常複雜,我們又想實現**復用,應該怎麼辦呢?
一般我們會宣告乙個私有的成員函式完成初始化,讓構造函式呼叫它。
#include
class
test
test()
~test()
void
print()
private
:int x;
void
init
(int i)};
intmain()
定義私有初始化函式 init(),然後不同的構造函式呼叫初始化函式。
$ g++ 15-2.cpp -o 15-2
$ ./15-2
x = 0
~test()
建構函式可能會非常大,減少臨時物件可以減少呼叫建構函式,提高效率。
下面看一示例:
// 15-3.cpp
#include
class
test
test()
:x(0
)test
(const test& t)
void
print()
~test()
private
:int x;};
test func()
intmain()
上面的**很簡單,主要是為了說明現代的 c++ 編譯器盡力減少臨時物件的產生。
第 36 行,直接使用 test(10) 將產生乙個臨時物件,再賦值給 t 又會呼叫拷貝建構函式。
函式 func() 產生乙個臨時物件並返回,將返回物件賦值給 tt,也將呼叫拷貝建構函式。
但是,實際上 g++ 編譯器經過優化,這裡避免了臨時物件的產生,也不會呼叫拷貝建構函式。所以:
第 36 行等價於 test t = 10;
第 37 行等價於 test tt = 20;
$ g++ 15-3.cpp -o 15-3
$ ./15-3
test(int):10
test(int):20
x = 10
x = 20
~test()
~test()
1、直接呼叫建構函式將產生乙個臨時物件
2、臨時物件是效能瓶頸,也是 bug **,現在 c++ 編譯器會盡力避開臨時物件
避免產生臨時 隱式 物件
產生乙個物件,如果這個物件很大並且這個物件是在乙個迴圈裡面產生的,是特別耗資源的,因為編譯器要找到一塊合適的記憶體,如果沒有合適的還要整理磁碟碎片並合併為一塊合適的物件儲存區。因此,在程式設計中一定要小心的產生臨時物件。臨時物件在c 語言中的特徵是未出現在源 中,從堆疊中產生的未命名物件。這裡需要特...
解析區域性物件與臨時物件
沒有名字的物件就是臨時物件,它存在於完整的表示式的生存其間。也就是說,當表示式計算結束後就會被釋放。乙個例外是,當臨時物件被引用時,它的生存期將延長到與這個引用的生存期一樣長。區域性物件就是可見區域在乙個函式範圍的物件。區域性物件有兩種,靜態區域性物件的生存期起於所在函式第一次被呼叫,結束於main...
C 臨時物件
臨時物件的產生 1.用建構函式作為隱式型別轉換函式時。2.建立乙個沒有名字的物件時。直接寫下 ctempobj 輸出 init obj exit obj 不單調用了建構函式,還呼叫了析構函式.既然是物件也可以這樣使用 ctempobj fun 不過這樣使用可要小心了 new ctempobj fun...