2017-07-02 62 views
2

这是一个基本的例子在堆或堆栈中创建构造函数的区别是什么?

myclass * abc = new myclass() 

myclass abc 

的区别是什么?在这两种情况下,堆栈中创建的对象是abc?如果对象是在堆中创建的,有什么不同?

从答案,我采取这一(请编辑如果不正确):如果我们要当它是出于没有删除类的变量

  1. 构造函数初始化类(成员)

  2. 范围,我们应该把对象创造堆起来。

+5

你的意思是除了对象存储在不同的地方?而且你需要一个指向堆分配对象的指针?也许你可以详细阐述什么是困扰你或者你在想什么? –

+0

而且你需要(手动)管理使用'new'分配的对象的销毁(而另一个会在其生命周期结束时自动销毁) – UnholySheep

+0

我的意思是在这两个代码中,对象abc是在堆栈右侧创建的?如何在堆中创建构造函数可以影响代码? –

回答

5

尽管在例abc是在自动存储器(通常称为“堆”)是不相同的种类的对象:

  • 在第一个例子abc是一个指针,它被存储在堆栈中。但是,存在存储在动态存储器(通常称为“堆”)中的myclass类型的第二个对象。对象指针abc指向堆中的对象。
  • 在第二个示例中abc的类型为myclass。这是创建的唯一对象。这两种方法之间

主要区别在于,在动态存储器中创建一个对象可以“活得比”在其内部的被创建它的功能。当指针abc超出范围时,其堆对象保持活动状态。例如,您可以在不进行复制的情况下从函数中返回它。

+0

@StelTeam你将通过一个指针访问你的对象,这是一种不同的语法。您需要通过调用delete来手动删除对象。 – dasblinkenlight

+0

谢谢你的帮助我如此多 –

+0

和1件事情如果指针超出范围,那么我如何访问该对象? –

1

myclass * abc = new myclass();中,您创建了一个指向栈上myclass的指针和堆上myclass的实例。在myclass abc;中,您将在堆栈上创建myclass的实例。

有很多不同之处,但最直接的一点是当堆留在当前离开当前上下文(例如从函数返回)时释放堆栈。因此,在第一个示例中,myclass的实例将保留在内存中,直到您手动释放它为止;而在第二个选项中,当您退出其写入的函数或代码块时,它将自动清除。

1

从构造函数调用的角度来看,两者基本没有区别。在这两种情况下,都会调用类的默认构造函数来构建对象。只是在myclass * abc = new myclass()的情况下,new运算符返回一个指向新创建对象的指针。

但是,主要区别在于堆栈内存和堆(动态)内存的概念。表达式myclass * abc = new myclass()为堆中新创建的对象分配内存,而myclass abc从堆中分配内存。这种差异的一个含义是,您对堆中请求的内存负责,并且您必须自己释放它,而对于在堆栈中分配的变量,编译器会为您执行内存删除工作。考虑下面的简单函数:

void fo() 
{ 
    myclass * abc1 = new myclass(); 
    myclass abc2; 

    // Use the declared variables. 

    // At the end, is everything OK? 
} 

在此功能的情况下,当函数返回,abc2的存储器自动由编译器释放。编译器还会删除abc1指针,但不会执行关于此指针指向的内存的任何操作。这个微妙的特点导致notorious memory在这个函数泄漏。的fo地址这个错误以下修改后的版本:

void fo() 
{ 
    myclass * abc1 = new myclass(); 
    myclass abc2; 

    // At the end, manually free the memory that abc1 points to if it is not needed anymore 
    delete abc1 
} 

维基百科有一个very nice article关于堆和栈内存,让更多关于他们的信息,并提供更多的细节的概念。

+1

非常好谢谢你 –