Соответствуют ли скобки после имени типа с новым?

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

Test* test = new Test;

и

Test* test = new Test();

Ответ 1

Позвольте получить педантичность, потому что есть различия, которые могут фактически повлиять на поведение вашего кода. Из комментариев, сделанных в статье "Old New Thing" , говорится следующее:

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

  • В С++ 1998 существует 2 типа инициализации: ноль и значение по умолчанию
  • В С++ 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

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

  • new A - неопределенное значение
  • new A() - zero-initialize

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

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

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

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

В компиляторе, совместимом с С++ 03, все должно работать так:

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

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

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

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

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

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

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

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

Ответ 2

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

Если используется в struct/class с определяемым пользователем конструктором, нет никакой разницы. Если вызывается тривиальная структура/класс (например, 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; vs new Thingy(); в этом случае изменилось между С++ 98 и С++ 2003. См. Объяснение Майкла Барра о том, как и почему.

Ответ 3

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

Test t;      // create a Test called t

и

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

Это из-за базового правила С++ (и C): если что-то может быть объявлением, то это объявление.

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

Ответ 4

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

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

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

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

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

Ответ 5

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