Вопрос

Если «Тест» — обычный класс, есть ли разница между:

Test* test = new Test;

и

Test* test = new Test();
Это было полезно?

Решение

Давайте будем педантичны, поскольку существуют различия, которые могут реально повлиять на поведение вашего кода.Большая часть нижеследующего взята из комментариев, сделанных Статья «Старая новая вещь».

Иногда память, возвращаемая новым оператором, будет инициализирована, а иногда — нет, в зависимости от того, является ли тип, который вы создаете, новым. POD (простые старые данные), или если это класс, который содержит члены POD и использует конструктор по умолчанию, созданный компилятором.

  • В C++1998 существует два типа инициализации:ноль и по умолчанию
  • В C++2003 был добавлен третий тип инициализации — инициализация значений.

Предполагать:

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

В компиляторе C++98 должно произойти следующее:

  • new A - неопределенное значение
  • new A() - инициализация нулями

  • new B - конструкция по умолчанию (B::m не инициализирован)

  • new B() - конструкция по умолчанию (B::m не инициализирован)

  • new C - конструкция по умолчанию (C::m инициализируется нулем)

  • new C() - конструкция по умолчанию (C::m инициализируется нулем)

В компиляторе, совместимом с C++03, все должно работать следующим образом:

  • new A - неопределенное значение
  • new A() - инициализация значения A, что означает инициализацию нулями, поскольку это POD.

  • new B - инициализируется по умолчанию (оставляет B::m неинициализированным)

  • new B() - инициализирует значением B, который инициализирует нулями все поля, поскольку его вектор по умолчанию генерируется компилятором, а не определяется пользователем.

  • new C - default-инициализирует C, который вызывает ctor по умолчанию.

  • new C() - инициализирует значением C, который вызывает ctor по умолчанию.

Итак, во всех версиях C++ есть разница между new A и new A() потому что A — это POD.

И в этом случае есть разница в поведении между C++98 и C++03. new B().

Это один из пыльных уголков C++, который может свести вас с ума.При создании объекта иногда вам нужны круглые скобки, иногда вы их совершенно не можете иметь, а иногда это не имеет значения.

Другие советы

new Thing(); ясно, что вы хотите, чтобы вызывался конструктор, тогда как new Thing; подразумевает, что вы не возражаете, если конструктор не вызывается.

Если используется в структуре/классе с пользовательским конструктором, разницы нет.Если вызывается тривиальная структура/класс (например, struct Thing { int i; };) затем new Thing; как malloc(sizeof(Thing)); тогда как new Thing(); как calloc(sizeof(Thing)); - он инициализируется нулем.

Ошибка находится посередине:

struct Thingy {
  ~Thingy(); // No-longer a trivial class
  virtual WaxOn();
  int i;
};

Поведение new Thingy; против new Thingy(); в этом случае изменилось между C++98 и C++2003.См. объяснение Майкла Берра о том, как и почему.

Нет, они одинаковы.Но есть разница между:

Test t;      // create a Test called t

и

Test t();   // declare a function called t which returns a Test

Это связано с основным правилом C++ (и C):Если что-то может быть декларацией, то это декларация.

Редактировать: Что касается проблем инициализации, касающихся данных POD и не-POD, хотя я согласен со всем, что было сказано, я просто хотел бы отметить, что эти проблемы применимы только в том случае, если создаваемая или иным образом создаваемая вещь не имеет пользователя. определенный конструктор.Если есть такой конструктор, он будет использован.Для 99,99% разумно спроектированных классов будет такой конструктор, поэтому проблемы можно игнорировать.

В общем, у нас есть инициализация по умолчанию в первом случае и инициализация значения во втором случае.

Например:в случае с int (тип POD):

  • int* test = new int — инициализация у нас любая и значение *test может быть любым.

  • int* test = new int() - *test будет иметь 0 значение.

следующее поведение зависело от вашего типа Test.У нас есть разные случаи:Тест имеет конструктор по умолчанию, Тест сгенерировал конструктор по умолчанию, Тест содержит член POD, не член POD...

Если предположить, что Test — это класс с определенным конструктором, разницы нет.Последняя форма проясняет, что конструктор Test запущен, но это все.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top