使用 new 和 without 实例化对象有什么区别

在 C + + 中,

Aside from dynamic memory allocation, is there a functional difference between the following two lines of code:

Time t (12, 0, 0); //t is a Time object


Time* t = new Time(12, 0, 0);//t is a pointer to a dynamically allocated Time object

当然,我假设已经定义了一个 Time (int,int,int) ctor。我还意识到,在第二种情况下,需要删除 t,因为它是在堆上分配的。还有别的区别吗?

52721 次浏览

我想你已经明白所有的区别了。假设您很清楚通过指针和通过变量访问 t 的成员的语法差异(好吧,指针也是一个变量,但我想您明白我的意思)。同时假设您知道在将 t 传递给函数时按值调用和按引用调用的区别。我想你也知道如果你把 t 赋值给另一个变量并通过另一个变量做出改变会发生什么。根据 t 是否为指针,结果将不同。

台词是:

Time t (12, 0, 0);

... 在本地作用域中分配一个类型为 Time的变量,即堆栈上的 一般来说,该变量在其作用域结束时将被销毁。

相比之下:

Time* t = new Time(12, 0, 0);

... 通过调用 ::operator new()Time::operator new()来分配一个内存块,然后调用 Time::Time(),将 this设置为该内存块中的一个地址(并且也作为 new的结果返回) ,然后将其存储在 t中。正如您所知道的,这是在堆上完成的 一般来说(默认情况下) ,并且需要您在程序的后面对它进行 delete,而 t中的指针是存储在堆栈上的 一般来说

N.B.: My use of generally here is speaking in terms of common implementations. The C++ standard does not distinguish stack and heap as a part of the machine, but rather in terms of their lifetime. Variables in local scope are said to have "automatic storage duration," and are thus destroyed at the end of local scope; and objects created with new are said to have "dynamic storage duration," and are destroyed only when deleted. In practical terms, this means that automatic variables are created and destroyed on the stack, and dynamic objects are stored on the heap, but this is not required by the language.

就构造函数而言,这两种形式在功能上是相同的: 它们只会导致在新分配的对象实例上调用构造函数。您似乎已经很好地理解了在分配模式和对象生命周期方面的差异。

在堆栈上分配对象和在堆上分配对象之间没有功能上的区别。两者都将调用对象的构造函数。

Incidentally I recommend you use boost's shared_ptr or scoped_ptr which is also functionally equivalent when allocating on the heap (with the additional usefulness of scoped_ptr constraining you from copying non-copyable pointers):

scoped_ptr<Time> t(new Time(12, 0, 0));

There is no other difference to what you know already.

假设您的代码正在使用默认运算符 new 的服务。

一个更明显的区别是在访问 t 的变量和方法时。

Time t (12, 0, 0);
t.GetTime();


Time* t = new Time(12, 0, 0);
t->GetTime();
void foo (Time t)
{
t = Time(12, 0, 0);
}


void bar (Time* t)
{
t = new Time(12, 0, 0);
}




int main(int argc, char *argv[])
{
Time t;
foo(t);//t is not (12,0,0),its value depends on your defined type Time's default constructor.


bar(&t);//t is (12,0,0)
return 0;
}
  • 使用新的: Call operator new function to get dynamic memory, and then to call the constuctor function.
  • 不要使用新的: 不会调用运算符 new 函数,只是直接调用构造函数。堆栈将直接使用,对 malloc 没有用处。