1. 程式人生 > >Cpp下匿名對象探究

Cpp下匿名對象探究

str printf 對象 ostream 新的 tar 對象分配 ted end

先來看看一段代碼:

#include "iostream"
using namespace std;

class ABCD
{
public:
    ABCD(int a, int b, int c)
    {
        this->a = a;
        this->b = b;
        this->c = c;
        printf("ABCD() construct, a:%d,b:%d,c:%d  \n", this->a, this->b, this->c);
    }
    
~ABCD() { printf("~ABCD() construct,a:%d,b:%d,c:%d \n", this->a, this->b, this->c); } int getA() { return this->a; } protected: private: int a; int b; int c; }; int run3() { printf("run3 start..\n"); ABCD(400, 500, 600
); printf("run3 end\n"); return 0; } int main() { run3(); system("pause"); return 0; }

我們下斷點來一步一步調試:

技術分享

我們F11,進入下一步:

技術分享

打印出如下:

技術分享

我們繼續往下走:

調用ABCD類的構造函數,完成對象的初始化工作

技術分享

繼續往下走,我們會發現:

技術分享

跟進:

技術分享

析構完成後:

技術分享

輸出結果:

技術分享

繼續往下走,程序執行完畢。

從上面我們可以分析出,匿名對象如果沒有完成賦值,也就是沒有與一個對象進行綁定,那麽匿名對象的構造執行完畢後,會馬上執行析構函數,回收對象分配的內存空間。

有了上面的基礎,我們來看看匿名對象的一個經典案例:

#include "iostream"
using namespace std;

//構造中調用構造是危險的行為
class MyTest
{
public:
    MyTest(int a, int b, int c)
    {
        this->a = a;
        this->b = b;
        this->c = c;
    }
    MyTest(int a, int b)
    {
        this->a = a;
        this->b = b;

        MyTest(a, b, 100); //產生新的匿名對象
    }
    ~MyTest()
    {
        printf("MyTest~:%d, %d, %d\n", a, b, c);
    }
protected:
private:
    int a;
    int b;
    int c;

public:
    int getC() const { return c; }
    void setC(int val) { c = val; }
};

int main()
{
    MyTest t1(1, 2);
    printf("c:%d", t1.getC()); //請問c的值是?  輸出一個垃圾值
    system("pause");
    return 0;
}

上面函數執行結果如下:

技術分享

可以看出,c的輸出結果為一個垃圾值,那麽為什麽會出現這種情況呢?下面我們來分析一下上面的代碼:

技術分享


我們跟進:

技術分享

完成對象的初始化,接著我們繼續執行MyTest(1,2,100);,註意,這裏會產生一個匿名對象,我們上面說過,當匿名對象沒有進行綁定操作,會自動進行析構。所以當我們執行完上面代碼後,會馬上調用析構函數,回收匿名對象的內存空間。

技術分享

完成對匿名函數的析構,也就是說此時匿名對象內存空間已經被回收,那麽c對應值此時是系統隨機分配的,所以最終的輸出結果是一個垃圾值。

Cpp下匿名對象探究