C++栈变量和堆变量

14

当你在 C++ 中创建一个存储在堆栈中的新对象时(我大多数情况下看到的方式),你会这样做:

CDPlayer player;

当你在堆上创建一个对象时,你会调用 new

CDPlayer* player = new CDPlayer();

但是当你这样做时:

CDPlayer player=CDPlayer();

它创建了一个基于栈的对象,但是和上面的例子有什么区别呢?


2个回答

26
重要的区别在于PODs(基本上是所有内置类型,如intbooldouble等以及仅由其他PODs构建的类C结构和联合),其中有默认初始化值初始化之间的区别。对于PODs来说,简单的

T obj;

如果使用 T() ,对象将被默认初始化,而使用obj 则会使对象未初始化。

T obj = T();

这是一种确保对象被正确初始化的好方法。

在模板代码中特别有用,其中T可能是POD或非POD类型。当您知道T不是POD类型时,T obj;就足够了。

补充:您也可以编写

T* ptr = new T; // note the missing ()

(如果T是POD,则避免分配对象的初始化)。

2
用户定义的类型也可以是POD(平凡标量型),在这种情况下,如果没有进行显式初始化,它们将表现得像内置类型一样。 - Konrad Rudolph
@Konrad:你说得对,区别在于POD和非POD!感谢你指出这一点,我已经相应地修改了我的答案。 - sbi
在C++0x中,您可以使用T obj{};确保正确的初始化。 - fredoverflow
2
还有一些其他的区别... T obj = T() 要求复制构造函数可用(即使编译器将省略复制)。 - David Rodríguez - dribeas
@FredOverflow:这不是声明一个函数吗? - sbi
@David:是的,没错。不过,我不确定这是否足够相关,可以将其添加到我的答案中。 - sbi

9

When you create a new object in C++ that lives on the stack, (…) you do this:

CDPlayer player;

不一定在堆栈上:以这种方式声明的变量具有自动存储。它们实际上去哪里取决于情况。它可能在堆栈上(特别是当声明在方法内部时),但也可能在其他地方。

考虑声明在类内部的情况:

class foo {
    int x;
};

现在,x的存储位置与类实例的存储位置相同。如果它存储在堆上,那么x也是如此。
foo* pf = new foo(); // pf.x lives on the heap.
foo f; // f.x lives where f lives, which has (once again) automatic storage.

4
@Tony: 这个回答真的回答了问题吗?它更像是一个补充性评论... 它根本没有涉及你的第一段代码和第三段代码之间的区别,因为其他答案已经做过了。 - Konrad Rudolph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接