注:部落格中內容主要來自《狄泰軟體學院》,部落格僅當私人筆記使用。
測試環境:ubuntu 10.10
gcc版本:4.4.5
一、有趣的問題
1)下面的程式輸出什麼?為什麼?
例項分析
23-1.cpp
#include class test
test()
void print()
};int main()
操作:
1) g++ 23-1.cpp -o 23-1.out編譯正常,列印結果:
mi = -1216950272
分析:
test(0);沒有起到任何作用,mi沒有被初始化為0。為什麼會這樣?
二、發生了什麼
1)程式意圖:
- 在test()中以0作為引數呼叫test(int i)
- 將成員變數mi的初始值設定為0
2)執行結果:
- 成員變數mi的值為隨機值
究竟哪個地方出了問題?
三、思考
1)建構函式是乙個特殊的函式
- 是否可以直接呼叫?
- 是否可以在建構函式中呼叫建構函式?
- 直接呼叫建構函式的行為是什麼?
四、答案
1)直接呼叫建構函式將產生乙個臨時物件(臨時物件產生的一種方式)
2)臨時物件的生命週期只有一條語句的時間
3)臨時物件的作用域只在一條語句中
4)臨時物件是c++中值得警惕的灰色地帶
程式設計實驗
解決方案——去掉了建構函式,用成員函式解決
23-2.cpp
#include class test
public:
test(int i)
test()
void print()
~test()
};int main()
操作:
1) g++ 23-2.cpp -o 23-2.out編譯正常,列印結果:
test()
mi = 0
main begin
test()
mi = 0
~test()
test(int i)
mi = 0 //應該列印10,列印0很奇怪
~test()
main end
~test()
分析:
test(10).print();應該列印10,但列印0。
五、編譯器的行為
現代c++編譯器在不影響最終執行結果的前提下,會盡力減少臨時物件的產生!!!
程式設計實驗
神秘的臨時物件
23-3.cpp
#include class test
test(const test& t) //拷貝建構函式
test()
void print()
~test()
};test func()
int main()
操作:
1) g++ 23-3.cpp -o 23-3.out編譯正常,列印結果:
test(int i): 10
test(int i): 20
mi = 10
mi = 20
~test()
~test()
分析:
test t = test(10);從結果等價test t = 10。因為編譯器杜絕了臨時物件產生,提高**執行速度。這種**書寫方式依賴編譯器優化,並不是好的編碼方式。
test tt = func();==> test tt = test(20); ==> test tt = 20;這裡也被編譯器優化了臨時物件。
小結1)直接呼叫建構函式將產生乙個臨時物件(產生臨時物件的方式,應杜絕)
2)臨時物件是效能的瓶頸,也是bug的**之一
3)現代c++編譯器會盡力避開臨時物件
4)實際工程開發中需要人為的避開臨時物件
C 23 神秘的臨時物件
class test test void print int main include class test test void print int main 輸出 mi 11341812 執行結果 究竟哪個地方出了問題?定義私有的的可復用普通成員函式 include class test publ...
物件和類 神秘的臨時物件
本文參照於狄泰軟體學院,唐佐林老師的 c 深度剖析教程 通過函式傳遞物件產生的臨時物件 c 中有這樣一種物件 它在 中看不到,但是確實存在。它就是臨時物件!臨時物件是由編譯器定義的乙個沒有命名的非堆物件。主要是為了提高程式的效能以及效率,因為臨時物件的構造與析構對系統效能而言絕不是微小的影響,所以我...
C 中神秘的臨時物件分析
include class test test void print intmain 1 程式意圖 在test 中以0作為引數呼叫test int i 將成員變數mi的值初始化設定為零 2 執行結果 成員變數mi的值為隨機值1 直接呼叫建構函式將產生乙個臨時物件 2 臨時物件的生命週期只有一條語句的...