C++筆記 第二十三課 神祕的臨時物件--C++中的灰色地帶---bug重要來源---狄泰學院
阿新 • • 發佈:2018-11-07
如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習C++編譯環境:Linux
第二十三課 神祕的臨時物件–C++中的灰色地帶
1.有趣的問題
下面的程式輸出什麼?為什麼?
23-1 有趣的問題
程式就為上方程式
2.發生了什麼?
程式意圖:
在Test()中以0作為引數呼叫Test(int i)
將成員變數mi的初始值設定為0
執行結果:
成員變數mi的值為隨機值
究竟哪個地方出了問題? 臨時物件的出現
3.思考
建構函式是一個特殊的函式
是否可以直接呼叫?
是否可以在建構函式中呼叫建構函式?
直接呼叫建構函式的行為是什麼?
4.答案
直接呼叫建構函式將產生一個臨時物件
臨時物件的生命週期只有一條語句的時間
臨時物件的作用域只在一條語句中
臨時物件是C++中值得警惕的灰色地帶
23-2 解決方案
#include <stdio.h> class Test { int mi; void init(int i) { mi = i; } public: Test(int i) { init(i); } Test() { init(0); } void print() { printf("mi = %d\n", mi); } }; int main() { Test t; t.print(); return 0; }
5.編譯器的行為
現代C++編譯器在不影響最終執行結果的前提下,會盡力減少臨時物件的產生!!!
23-3神祕的臨時物件
#include <stdio.h> class Test { int mi; public: Test(int i) { printf("Test(int i) : %d\n", i); mi = i; } Test(const Test& t) { printf("Test(const Test& t) : %d\n", t.mi); mi = t.mi; } Test() { printf("Test()\n"); mi = 0; } int print() { printf("mi = %d\n", mi); } ~Test() { printf("~Test()\n"); } }; Test func() { return Test(20); } int main() { Test t = Test(10); //預計執行過程: 1.生成臨時物件 2.用臨時物件初始化t物件 //==>呼叫拷貝建構函式,實際執行過程:==> Test t = 10; //Test tt = func(); ==> Test tt = Test(20); ==> Test tt = 20; t.print(); tt.print(); return 0; }
小結
直接呼叫建構函式將產生一個臨時物件
臨時物件是效能的瓶頸,也是bug的來源之一
現代C++編譯器會盡力避開臨時物件
實際工程開發中需要人為的避開臨時物件