【问题标题】:When to use "new" and when not to, in C++? [duplicate]在 C++ 中何时使用“新”,何时不使用? [复制]
【发布时间】:2010-10-15 08:10:20
【问题描述】:

可能重复:
When should I use the new keyword in C++?

什么时候应该在 C++ 中使用“new”运算符?我来自 C#/Java 背景,实例化对象让我感到困惑。

如果我创建了一个名为“Point”的简单类,那么在创建点时我应该:

Point p1 = Point(0,0);

Point* p1 = new Point(0, 0);

谁能帮我澄清一下什么时候使用 new 运算符,什么时候不使用?

重复:

When should I use the new keyword in C++?

相关:

About constructors/destructors and new/delete operators in C++ for custom objects

Proper stack and heap usage in C++?

【问题讨论】:

  • 重复 - 数不胜数
  • 正如尼尔所说,这个问题已经被问过无数次了。

标签: c++ new-operator


【解决方案1】:

当你希望一个对象一直存在直到你delete它时,你应该使用new。如果您不使用new,那么当对象超出范围时将被销毁。这方面的一些例子是:

void foo()
{
  Point p = Point(0,0);
} // p is now destroyed.

for (...)
{
  Point p = Point(0,0);
} // p is destroyed after each loop

有些人会说new 的使用决定了你的对象是在堆上还是在栈上,但这仅适用于在函数中声明的变量。

在下面的示例中,“p”的位置将是其包含对象 Foo 的分配位置。我更喜欢称之为“就地”分配。

class Foo
{

  Point p;
}; // p will be automatically destroyed when foo is.

使用new 分配(和释放)对象比就地分配要昂贵得多,因此应将其使用限制在必要的地方。

何时通过new 分配的第二个示例是用于数组。您不能*在运行时更改就地数组或堆栈数组的大小,因此在需要未确定大小的数组时,必须通过 new 分配它。

例如

void foo(int size)
{
   Point* pointArray = new Point[size];
   ...
   delete [] pointArray;
}

(*先发制人的挑剔 - 是的,有一些扩展允许可变大小的堆栈分配)。

【讨论】:

  • +1 请记住,您需要手动删除 new'ed 指针 delete p1;
  • +1 不错。只要记住第一个可以写成点 p(0, 0);也。 = .. 语法可能会让他认为 p 是一个被赋值的指针。
  • @Andrew Grant 如果你必须使用新的使用shared_ptrunique_prt。在 c++11 STL 中引入的共享指针将自动记录删除。注意shared_ptr提供的数组默认删除器调用delete,而不是delete[],因此使用lambda函数std::shared_ptr<int> p(new int[10], [](int* p) { delete[] p; });std::shared_ptr<int> p(new int[10], std::default_delete<int[]>());或使用unique_ptr提供的帮助器调用delete[]std::unique_ptr<int,void(*)(int*)> p(new int[10], [](int* p) { delete[] p; });
  • 这个答案已有 10 多年的历史了。现在不应该是“你从不使用 `new',在 RAII 和智能指针之间永远不需要它”?
【解决方案2】:

查看 this questionthis question 以获得有关 C++ 对象实例化的一些好的答案。

这个基本思想是堆上实例化的对象(使用new)需要手动清理,栈上实例化的对象(不使用new)在超出范围时会自动清理。

void SomeFunc()
{
    Point p1 = Point(0,0);
} // p1 is automatically freed

void SomeFunc2()
{
    Point *p1 = new Point(0,0);
    delete p1; // p1 is leaked unless it gets deleted
}

【讨论】:

    【解决方案3】:

    当您希望在堆而不是堆栈上创建对象时,您应该使用 new。这允许通过指针的帮助从当前函数或过程之外访问对象。

    在 C++ 中查找指针和内存管理可能对您有用,因为这些是您在其他语言中不太可能遇到的。

    【讨论】:

    • New 不保证堆分配,简单地避免 new 并不能保证堆栈分配。
    【解决方案4】:

    New 总是用于分配动态内存,然后必须释放。

    通过执行第一个选项,当范围丢失时,该内存将自动释放。

    Point p1 = Point(0,0); //This is if you want to be safe and don't want to keep the memory outside this function.
    
    Point* p2 = new Point(0, 0); //This must be freed manually. with...
    delete p2;
    

    【讨论】:

      猜你喜欢
      • 2010-11-20
      • 1970-01-01
      • 2014-03-06
      • 2020-06-30
      • 2012-04-26
      • 2010-10-24
      • 2012-10-08
      • 1970-01-01
      • 2011-07-20
      相关资源
      最近更新 更多