Подтвердить что ты не робот

Новый vs * new в С++

Я делаю это:

MyClass myObject = *new MyClass();

Но многие люди говорят, что я должен это сделать:

MyClass *myObject = new MyClass();

Есть ли разница в производительности. Или логическая причина использовать второй метод? Я просто предпочитаю использовать первый метод, чтобы избавиться от путаницы указателя.

4b9b3361

Ответ 1

Оба не одинаковы!
Сначала вы получаете поведение Undefined [Ref 1:] или утечку памяти, а вторая - нет, если вы позже вызываете delete.

MyClass myObject = *new MyClass();

Выделяет объект типа MyClass на freestore, а затем копирует этот объект в myObject. Вы теряете указатель на динамически выделенный объект и, следовательно, никогда не сможете его освободить. Если деструктор MyClass имеет побочные эффекты, и ваша программа зависит от этих побочных эффектов, тогда он дает вам Undefined поведение, если нет, то то, что у вас есть, - простая простая утечка памяти.

MyClass *myObject = new MyClass();

Выделяет объект типа MyClass на freestore и точки myObject на адрес, где размещается динамически выделенный объект. У вас все еще есть указатель на объект, который вы можете освободить, вызывая delete позже.


Если у вас вопрос, что это лучший способ сделать это,
Ответ заключается в том, чтобы вообще не использовать динамически выделенный объект:

MyClass obj;

Хорошее чтение:

Почему программисты на C++ минимизируют использование "нового" ?


[Ссылка 1:]
С++ 11 Стандарт: 3.8.4:

Программа может завершить время жизни любого объекта, повторно используя хранилище, которое занимает объект, или явно вызвав деструктор для объекта типа класса с нетривиальным деструктором. Для объекта типа класса с нетривиальным деструктором программа не требует прямого вызова деструктора до того, как хранилище, которое объект занимает, повторно используется или освобождается; однако, если нет явного обращения к деструктор или если исключение-выражение (5.3.5) не используется для освобождения хранилища, деструктор не должен быть неявно вызван, и любая программа, зависящая от побочных эффектов, создаваемых деструктором, имеет поведение Undefined.

Ответ 2

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

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

Второй случай использует меньше памяти, быстрее и не теряет память. В первом случае говорится: "Я не понимаю С++".

Ответ 3

Первый - это вздор.

MyClass myObject = *new MyClass();

Часть после = выделяет память и создает новый объект MyClass. Первая часть создает новый объект MyClass, вызывая конструктор копирования с объектом RHS MyClass. Затем память, выделенная в RHS, протекает, потому что у вас нет сохраненного указателя для ее удаления.

Вышеуказанное утверждение такое же, как и запись.

MyClass myObject;

Далее

Leak memory equal to size of MyClass.

Прежде всего, решите, хотите ли вы объект в стеке или в куче.

Если вам нужен объект в стеке, сделайте

MyClass myObject;

Это создает объект MyClass - он хорошо подходит для большинства целей.

Если вам нужен объект в куче, тогда сделайте

MyClass *myObject = new MyClass();

Первый способ - выделение в стеке более эффективно. Вы назначаете кучу по другим причинам.

  • Во время компиляции вы не знаете, сколько объектов вам нужно создать.
  • Использовать классы полиморфно.