2012-11-16 60 views
2

我有一個問題:爲什麼C++實例在通過Objective-c類調用時自動調用構造函數和析構函數?

我沒有明確「new」和「delete」我的C++實例,但是它會自動調用「new」和「delete」的時候,Objective-C類初始化。任何想法?

class myCppTestClass 
{ 
public: 
    myCppTestClass() 
    { 
     NSLog(@"MyCpp constructor"); 
    } 

    ~myCppTestClass() 
    { 
     NSLog(@"MyCpp destructor"); 
    } 
}; 



@interface MyTestClass : NSObject 
{ 
    myCppTestClass myCppInstance; 
} 

@end 


@implementation MyTestClass 


@end 

我這樣稱呼它:

NSLog(@"Create an object."); 
MyTestClass *objcObject = [[MyTestClass alloc] init]; 
NSLog(@"Object created"); 
[objcObject release]; 
objcObject = nil; 
NSLog(@"Object released."); 

然後我運行它,日誌是這樣的:

2012-11-16 12:01:18.747 iOSVersion[87248:f803] Create an object. 
2012-11-16 12:01:18.749 iOSVersion[87248:f803] MyCpp constructor 
2012-11-16 12:01:18.750 iOSVersion[87248:f803] Object created 
2012-11-16 12:01:18.751 iOSVersion[87248:f803] MyCpp destructor 
2012-11-16 12:01:18.752 iOSVersion[87248:f803] Object released. 

這不是自動引用Counnting,因爲它是封閉, 有任何想法嗎?非常感謝。

同樣,如果MyTestClass是這樣的,構造函數和析構函數不會被調用:

@interface MyTestClass : NSObject 
{ 
    myCppTestClass * myCppInstance; 
} 

和日誌:

2012-11-16 12:22:38.710 iOSVersion[87428:f803] Create an object. 
2012-11-16 12:22:38.711 iOSVersion[87428:f803] Object created 
2012-11-16 12:22:38.712 iOSVersion[87428:f803] Object released. 
+1

它的時候都沒有指針或引用C++對象是如何工作的。 –

+0

你的意思是'myCppTestClass myCppInstance;'? – lijinma

+1

是的,變量聲明通過一些運行時嚮導來分配對象時調用缺省構造函數。 –

回答

4

語言不newdelete你,但它調用構造函數和析構函數。這是C++的標準行爲:當您直接或間接創建對象時,包含對象的構造函數會被調用;同樣,當包含對象被釋放時,所有包含的實例的析構函數也會被調用。

+0

感謝您的回答,但如果我的聲明是這樣的:'myCppTestClass * myCppInstance;',構造函數和析構函數將不會被調用。 – lijinma

+1

@lijinma這是因爲在這種情況下,你不聲明一個對象:相反,你聲明一個指針。初始化僅針對對象而不針對指針自動進行。當你使用指針時,你需要手動調用'new'和'delete'。 – dasblinkenlight

+0

很酷,你真的解決了我的問題,非常感謝。 – lijinma

1

newdelete在C++中不用於創建對象,它們用於在新鮮分配的RAM區域中創建對象。 myCppInstance的數據未分配到堆上,它實際上是MyTestClass的一部分。當你的代碼創建一個MyTestClass對象時,它將包含一個已經構建的myCppTestClass

同樣,如果您創建了一個myCppTestClass變量,那麼該類的數據基本上在堆棧上免費分配。它在聲明範圍的末尾釋放(即使有例外)。

隨着newdelete,你得到一個指向一個對象的指針,你負責管理它的生命週期。如果你剛剛開始學習C++,你可能想完全避免它們。在現代C++中,最好使用make_shared而不是new,而「從不」使用delete

*除非你使用放置新

+0

謝謝你,馬修,但如果我的聲明是這樣的:myCppTestClass * myCppInstance ;,構造函數和析構函數將不會被調用..我不知道,爲什麼? – lijinma

+0

因爲在這種情況下,你沒有定義一個'myCppTestClass'實例,所以你正在定義一個名爲'myCppInstance'的變量,它實際上是一個指向一些(尚未確定)'myCppTestClass'對象(實例)的指針。當你將類型從'myCppTestClass'改成'myCppTestClass *'時,你應該把這個變量重命名爲'myCppInstancePointer'。您可以使用'new'在堆上創建一個對象,然後將該對象的值分配給您的指針變量。 – Cogwheel

+0

s /該對象的值/該對象的地址/ – Cogwheel

相關問題