Когда использовать "новое", а когда нет, в С++?

Возможный дубликат:
Когда следует использовать новое ключевое слово в С++?

Когда я должен использовать "новый" оператор в С++? Я прихожу с фона С#/Java, и объекты-экземпляры меня путают.

Если я создал простой класс под названием "Точка", когда я создаю точку, я должен:

Point p1 = Point(0,0);

или

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

Может ли кто-нибудь уточнить для меня, когда использовать нового оператора, а когда нет?

Дубликат:

Когда следует использовать новое ключевое слово в С++?

Связанный:

О конструкторах/деструкторах и операциях new/delete в С++ для пользовательских объектов

Правильное использование стека и кучи в С++?

Ответ 1

Вы должны использовать new, если хотите, чтобы объект оставался на месте, пока вы не delete его. Если вы не используете 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 - для массивов. Вы не можете * изменить размер массива на месте или стека во время выполнения, поэтому, когда вам нужен массив неопределенного размера, он должен быть назначен через новый.

например.

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

(* pre-emptive nitpicking - да, есть расширения, которые позволяют распределять стеки по размеру).

Ответ 2

Взгляните на этот вопрос и на этот вопрос для получения хороших ответов на экземпляр объекта С++.

Эта основная идея заключается в том, что объекты, созданные экземпляром кучи (с использованием нового), должны быть очищены вручную, те, которые создаются в стеке (без новых), автоматически очищаются, когда они выходят за рамки.

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

Вы должны использовать новое, если хотите, чтобы объект был создан в куче вместо стека. Это позволяет получить доступ к объекту из-за пределов текущей функции или процедуры с помощью указателей.

Возможно, вам будет полезно искать указатели и управление памятью на С++, поскольку эти вещи вряд ли встречаются на других языках.

Ответ 4

Новый всегда используется для выделения динамической памяти, которая затем должна быть освобождена.

Выполняя первый вариант, эта память будет автоматически освобождена, когда объем потерян.

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;