1. 程式人生 > >C++筆記 第二十三課 神祕的臨時物件--C++中的灰色地帶---bug重要來源---狄泰學院

C++筆記 第二十三課 神祕的臨時物件--C++中的灰色地帶---bug重要來源---狄泰學院

如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習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++編譯器會盡力避開臨時物件
實際工程開發中需要人為的避開臨時物件