和有什么区别
Kwadrat* k1 = new Kwadrat(1,2,3);
k1->field = 0;
Kwadrat k2(1,2,3);
k2.field = 0;
第一个是指向分配内存的指针,第二个是对象(它在哪里,在系统堆栈上?)为什么第二个更糟?我们什么时候用第一个,什么时候用第二个?
和有什么区别
Kwadrat* k1 = new Kwadrat(1,2,3);
k1->field = 0;
Kwadrat k2(1,2,3);
k2.field = 0;
第一个是指向分配内存的指针,第二个是对象(它在哪里,在系统堆栈上?)为什么第二个更糟?我们什么时候用第一个,什么时候用第二个?
堆上的动态分配(使用new
):
Kwadrat* k1 = new Kwadrat(1,2,3);
在堆栈上创建对象(不使用new
):
Kwadrat k2(1,2,3);
查看这个 Stack Overflow 问题,了解有关堆栈和堆的扩展讨论。Brian R. Bondy 的回答很好地比较了两者,而Jeff Hill 的回答为您提供了更多细节。
对于一个危险的小总结:
delete
使用您创建的对象new
,否则您的代码将遭受内存泄漏使用 new在堆上动态创建一个对象,这意味着即使指针 (k1*) 超出范围,它也会持续存在。
这可能很方便,但是如果它超出范围并且您没有在它周围保留指针的副本,则会永久丢失并导致内存泄漏。这意味着只要程序执行,您就会失去该资源使用的空间。这是使用 new 动态分配内存的缺点,您必须跟踪它并使用 delete 运算符手动释放它,这需要额外的工作。
以另一种方式执行此操作会创建一个堆栈对象,该对象一旦离开范围就会被销毁,这通常是可取的。
通常,当使用 new 动态创建内存时,人们通过将动态创建的对象包装在另一个对象中来获得这种类似堆栈的功能,当它超出范围时会销毁它。这种模式称为资源获取即初始化 (RAII)。这对于引用计数最有用,因此您的对象仍然可以在范围之外持久化,但是当不再引用它们时将被销毁。
new 在堆上分配一个对象。您的第二个示例在堆栈上分配内存。一旦分配 k2 的函数返回,内存将不再有效(当然首先调用 k2 的析构函数)。如果您希望对象比创建它的函数寿命更长,则需要使用 new。
new
允许您为请求的分配指定存储。分配 vianew/new[]
通常在堆上(例如 wrapping malloc
),但最终由实现定义。同样,在某些情况下,编译器可能有足够的信息来绕过它。
它在哪里,在系统堆栈上?
从技术上讲,您通常会将 C++ 编写到抽象机器的规范中。
但通常,是的 - 对象是在线程的堆栈上分配的。
为什么第二个更糟糕?什么时候用第一个,什么时候用第二个?
第二个应该是您的默认值,因为它非常清楚,编译器会为您管理其生命周期和分配,而且速度也非常快。一些例外情况包括:
简而言之,可能出错的情况要少得多(使用第二个),并且通过通用系统分配器创建分配所花费的时间要少得多。