2013-07-10 17 views
-2

對於下面的代碼,爲什麼「A關閉:3」打印兩次?C++析構函數是如何執行的?

#include <stdio.h> 

class A 
{ 
public: 
    int a; 

    A(int n) 
    { 
    a = n; 
    printf("This is A: %d.\n", a); 
    } 

    A() 
    { 
    a = 0; 
    printf("This is A: %d.\n", a); 
    } 

    ~A() 
    { 
    printf("A is closed: %d.\n", a); 
    } 
}; 


class B 
{ 
public: 
    A a; 

    B() 
    { 
    a = A(3); 
    } 
}; 


void f() 
{ 
    B b; 
} 


int main() 
{ 
    f(); 
    return 0; 
} 

輸出:

This is A: 0. 
This is A: 3. 
A is closed: 3. 
A is closed: 3. 
+0

這是_got_是一個騙局:/但我找不到它 –

回答

2

如果你希望它恰好一次打印,請允許我向您介紹initializer lists

class B { 
    public: 
     A a; 

     B() : a(3) { 
     } 
}; 

目前,在你的代碼,它打印兩次,因爲當創建B時,其所有成員都被構造,然後構造函數B被調用。它正在打印一次來構造A a,然後在您將a設置爲A(3)時再次打印。初始化程序列表允許您指定在構造函數運行之前應如何構建每個成員。

附加提示:成員初始化的順序僅受它們在struct/class中的出現順序影響,並且與初始化程序列表中的順序無關。

+0

我不問爲什麼「這是A:0」。和「這是A:3」。被打印。我在問爲什麼「A已關閉:3.」印兩次。它應該是「A關閉:3」,然後「A關閉:0」,對吧? – user180574

+0

這是因爲被分配給'a'的A(3)'在'B()'執行結束時被破壞了,因爲它是一個臨時變量。當B被銷燬並且其成員'A'的析構函數被調用時,出現「A關閉:3」的第二個打印。 –

+0

然後按順序,不應該是「這是A:0」,「A是封閉的:3」,「這是A:3」,「A是封閉的:3」? – user180574

0

因爲之前b分配了新的值爲a,它已經有一個值(存在一個實例)。 您正在使用默認賦值運算符,該運算符僅將temp A(3)實例的副本複製到B的成員中,並且現在必須銷燬該副本。

當f返回它創建的B實例會被銷燬,並反過來破壞其成員a。