2012-11-16 62 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

相关问题