Когда использовать "новое", а когда нет, в С++?
Возможный дубликат:
Когда следует использовать новое ключевое слово в С++?
Когда я должен использовать "новый" оператор в С++? Я прихожу с фона С#/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;