Czy nawiasy po nazwie typu różnią się od new?

Jeśli 'Test' jest klasą zwykłą, czy jest jakaś różnica między:

Test* test = new Test;

I

Test* test = new Test();
Author: Paul Maserrat, 2009-03-06

5 answers

Bądźmy pedantyczni, ponieważ istnieją różnice, które mogą mieć wpływ na zachowanie Twojego kodu. Wiele z poniższych uwag pochodzi z komentarzy do artykułu "stara nowa rzecz" .

Czasami pamięć zwracana przez nowy operator zostanie zainicjowana, a czasami nie będzie zależeć od tego, czy nowy typ jest POD (zwykłe stare dane) , czy jest to klasa, która zawiera członków POD i używa generowanego kompilatora domyślnego konstruktor.

  • W C++1998 istnieją 2 rodzaje inicjalizacji: zero i default
  • W C++2003 dodano trzeci typ inicjalizacji, inicjalizacja wartości.

Zakładać:

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

W kompilatorze C++98 powinno wystąpić:

  • new A - wartość nieokreślona
  • new A() - zero-inicjalizacja

  • new B - default construct (B::M is uninitialized)

  • new B() - default construct (B:: M jest niezinicjalizowane)

  • new C - default construct (C::M is zero-initialized)

  • new C() - default construct (C::M is zero-initialized)

W kompilatorze zgodnym z C++03 rzeczy powinny działać tak:

  • new A - wartość nieokreślona
  • new A() - value-initialize A, która jest zerową inicjalizacją, ponieważ jest POD.

  • new B - default-initializes (leaves B:: m niezinicjalizowane)

  • new B() - wartość-inicjalizuje B, które zero-inicjalizuje wszystkie pola, ponieważ jego domyślny ctor jest generowany przez kompilator w przeciwieństwie do zdefiniowanego przez użytkownika.

  • new C - default-inicjalizuje C, który wywołuje domyślny ctor.

  • new C() - value-inicjalizuje C, który wywołuje domyślny ctor.

Więc we wszystkich wersjach C++ jest różnica między new A i new A() Ponieważ A jest POD.

I jest różnica w zachowanie pomiędzy C++98 i C++03 Dla Przypadku new B().

Jest to jeden z zakurzonych zakątków C++, który może doprowadzić cię do szaleństwa. Podczas konstruowania obiektu, czasami chcesz / potrzebujesz paren, czasami absolutnie nie możesz ich mieć, a czasami to nie ma znaczenia.

 870
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-18 10:56:13

new Thing(); jest jednoznaczne, że chcesz wywoływać konstruktor, podczas gdy new Thing; jest brane, aby sugerować, że nie masz nic przeciwko, jeśli konstruktor nie jest wywoływany.

Jeśli jest używana w strukturze / klasie z konstruktorem zdefiniowanym przez użytkownika, nie ma żadnej różnicy. Jeśli wywołana jest trywialna struktura / Klasa (np. struct Thing { int i; };), to {[2] } jest jak malloc(sizeof(Thing));, podczas gdy {[1] } jest jak calloc(sizeof(Thing)); - otrzymuje zero inicjalizacji.

The gotcha lies in-between:

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

Zachowanie new Thingy; vs new Thingy(); w tym przypadku zmienione pomiędzy C++98 a C++2003. Zobacz Wyjaśnienie Michaela Burra, jak i dlaczego.

 51
Author: kfsone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-25 22:12:22

Nie, są takie same. Ale jest różnica między:

Test t;      // create a Test called t

I

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

Jest to spowodowane podstawową regułą C++ (i C): Jeśli coś może być deklaracją, to jest deklaracją.

Edit: Re problemy z inicjalizacją dotyczące danych POD i nie - pod, chociaż zgadzam się ze wszystkim, co zostało powiedziane, chciałbym tylko zaznaczyć, że te kwestie mają zastosowanie tylko wtedy, gdy rzecz jest nowa lub w inny sposób skonstruowana nie ma konstruktor zdefiniowany przez użytkownika. Jeśli istnieje taki konstruktor, zostanie on użyty. Dla 99,99% rozsądnie zaprojektowanych klas będzie taki konstruktor, więc problemy mogą być ignorowane.

 19
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-06 21:23:19

Ogólnie mamy default-initialization w pierwszym przypadku I value-initialization w drugim przypadku.

Na przykład: w przypadku int (Typ POD):

  • int* test = new int - mamy dowolną inicjalizację i wartość * test może być dowolna.

  • int* test = new int() - *test będzie miał wartość 0.

Następne zachowanie zależy od Twojego testu typu. Mamy defferent przypadki: Test mają defult konstruktor, Test mają wygenerowany konstruktor domyślny, Test zawierają pod member, non POD członek...

 16
Author: bayda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-25 22:10:45

Zakładając, że Test jest klasą ze zdefiniowanym konstruktorem, nie ma różnicy. Ta ostatnia forma sprawia, że nieco jaśniej jest, że konstruktor testowy działa, ale to wszystko.

 10
Author: Evan Shaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-06 19:59:52