中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

神秘的臨時對象(十八)

發布時間:2020-06-16 03:08:56 來源:網絡 閱讀:680 作者:上帝之子521 欄目:編程語言

        我們在程序中不可避免的會遇到臨時變量,那么在 C++ 中也會不可避免的會遇到臨時對象。我們以代碼為例來進行分析

#include <stdio.h>

class Test
{
private:
    int mi;
public:
    Test(int i)
    {
        mi = i;
    }
    
    Test()
    {
        Test(0);
    }
    
    void print()
    {
        printf("mi = %d\n", mi);
    }
};

int main()
{
    Test t;
    
    t.print();
    
    return 0;
}

        我們這段代碼是想要在 Test() 中以 0 作為參數調用 Test(int i),然后將成員變量 mi 初始化為 0,最后想要打印它的值。我們來看看編譯結果

神秘的臨時對象(十八)

        我們看到打印的是一個隨機數,并不是我們所期望的 0。那這到底是怎么回事呢?那么我們想下:構造函數既然是一個特殊的函數。那么它是否可以直接調用呢?是否可以在構造函數中調用構造函數呢?直接調用構造函數的行為是什么?我們就直接說答案了。直接調用構造函數將產生一個臨時對象,臨時對象的生命周期只有一條語句的時間,臨時對象的作用域只在一條語句中,臨時對象是 C++ 中值得警惕的灰色地帶!上面那個程序也就是說第 15 行的調用的構造函數會產生臨時對象,它的生命周期只有那一行的時間,所以在后面我們打印出來的才會是一個隨機值。

        下面我們在上面程序的基礎上進行修改,代碼如下

#include <stdio.h>

class Test
{
private:
    int mi;
    
    void init(int i)
    {
        mi = i;
    }
public:
    Test()
    {
        init(0);
    }
    
    void print()
    {
        printf("mi = %d\n", mi);
    }
};

int main()
{
    Test t;
    
    t.print();
    
    return 0;
}

        我們再次編譯看看結果

神秘的臨時對象(十八)

        這次我們看到它按照我們所想要的初始化為 0 了。現代的 C++ 編譯器在不影響最終執行結果的前提下,會盡力減少臨時對象的產生!!!

        我們再來看一個示例代碼

#include <stdio.h>

class Test
{
private:
    int mi;
public:
    Test(int i)
    {
        mi = i;
        printf("Test(int i): %d\n", mi);
    }
    Test(const Test& obj)
    {
        mi = obj.mi;
        printf("Test(const Test& obj): %d\n", mi);
    }
    Test()
    {
        mi = 0;
        printf("Test()\n");
    }
    void print()
    {
        printf("mi = %d\n", mi);
    }
    ~Test()
    {
        printf("~Test()\n");
    }
};

Test func()
{
    return Test(50);
}

int main()
{
    Test t = Test(10);
    Test tt = func();
    
    t.print();
    tt.print();
    
    return 0;
}

        我們看到在第 40 行定義了 Test 對象 t,并將它初始化為 10。按照我們想的它在這塊先是生成一個臨時對象初始化為 10 并將這個臨時對象賦值給對象 t。所以這塊可能會牽扯到拷貝構造函數。第 41 行也是這樣的,先是在 func 函數中生成一個臨時對象 Test(50),并將它賦值給對象 tt。所以也會牽扯到拷貝構造函數。那么我們來編譯下看看結果

神秘的臨時對象(十八)

        我們看到并沒有打印出拷貝構造函數的身影。再回想下我們之前講的,現代編譯器已經大大優化了,盡量會避免臨時對象的產生。那么第 40 行將會等價于 Test t(10),第 41 行將會等價于 Test tt = Test(50) ==> Test tt(50);所以這樣也就能解釋清楚了,它確實沒牽扯到拷貝構造函數。我們得隨時注意 C++ 中的臨時對象,因為它將會導致一些莫名其妙的結果。通過對臨時對象的學習,總結如下:1、直接調用構造函數將產生一個臨時對象,臨時對象是性能的瓶頸,也是 bug 的來源之一;2、現代 C++ 編譯器會盡力避開臨時對象,實際工程開發中需要人為的避開臨時對象。


        歡迎大家一起來學習 C++ 語言,可以加我QQ:243343083

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

连城县| 沁阳市| 故城县| 岳阳县| 隆安县| 淅川县| 石门县| 昌邑市| 阳朔县| 建昌县| 民和| 微山县| 榆树市| 秦安县| 泸定县| 垣曲县| 南华县| 旌德县| 宁南县| 宜宾县| 雅安市| 乌兰县| 邯郸县| 绩溪县| 铜山县| 江山市| 浦江县| 灯塔市| 固阳县| 克什克腾旗| 肥东县| 新闻| 奈曼旗| 哈巴河县| 柯坪县| 乐至县| 南陵县| 太保市| 屯留县| 浏阳市| 桃园市|