Frage

Wenn ‚Test‘ eine gewöhnliche Klasse ist, gibt es einen Unterschied zwischen:

Test* test = new Test;

und

Test* test = new Test();
War es hilfreich?

Lösung

Lassen Sie uns pedantisch bekommen, denn es gibt Unterschiede, die tatsächlich Ihr Code das Verhalten beeinflussen können. Ein großer Teil der folgenden von Kommentaren auf ein "Old New Thing genommen "Artikel .

Manchmal ist der Speicher durch den neuen Betreiber zurückgegeben werden initialisiert, und manchmal wird es nicht abhängig davon, ob der Typ Sie newing vorhast ist ein pOD (plain old data) , oder wenn es eine Klasse, die pOD Mitglieder enthält und einen Compiler generierte Standardkonstruktors verwenden.

  • In C ++ 1998 gibt es zwei Arten der Initialisierung: Null und default
  • In C ++ 2003 eine dritte Art der Initialisierung Wert Initialisierung hinzugefügt wurde.

Angenommen:

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

In einem C ++ 98-Compiler sollten Folgendes auftreten:

  • new A - unbestimmter Wert
  • new A() - Null initialisieren

  • new B - default Konstrukt (B :: m ist nicht initialisierten)

  • new B() - default Konstrukt (B :: m ist nicht initialisierten)

  • new C - default Konstrukt (C :: m Null initialisiert)

  • new C() - default Konstrukt (C :: m Null initialisiert)

In einem C ++ 03 konformen Compiler, Dinge sollen wie so funktionieren:

  • new A - unbestimmter Wert
  • new A() - Wert initialisieren A, die Null-Initialisierung, da es einen POD ist

  • .
  • new B - default-initialisiert (Blätter B :: m nicht initialisierten)

  • new B() - Wert initialisiert B, die alle Felder seit seinem Standard Ctor Null initialisiert Compiler als benutzerdefinierten Gegensatz erzeugt

  • .
  • new C - default-initialisiert C, die den Standard-Ctor ruft

  • .
  • new C() -. Wert initialisiert C, die den Standard-Ctor ruft

So in allen Versionen von C ++ gibt es einen Unterschied zwischen new A und new A() weil A ein POD ist.

Und es gibt einen Unterschied im Verhalten zwischen C ++ 98 und C ++ 03 für den Fall new B().

Dies ist eine der staubigen Ecken von C ++, die Sie verrückt machen kann. Wenn ein Objekt konstruieren, manchmal möchten Sie / die Pars benötigen, manchmal absolut Sie können sie nicht haben, und manchmal spielt es keine Rolle.

Andere Tipps

new Thing(); ist explizit, dass Sie ein Konstruktor während new Thing; genannt wollen genommen wird Ihnen nichts ausmacht, implizieren, wenn der Konstruktor wird nicht aufgerufen.

Wenn auf einer Struktur / Klasse mit einem benutzerdefinierten Konstruktor verwendet wird, gibt es keinen Unterschied. Wenn auf eine triviale Struktur / Klasse aufgerufen (z struct Thing { int i; };), dann ist new Thing; wie malloc(sizeof(Thing)); während new Thing(); wie calloc(sizeof(Thing)); ist - es wird Null initialisiert

.

Die Gotcha liegen in-zwischen:

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

Das Verhalten von new Thingy; vs new Thingy(); in diesem Fall geändert zwischen C ++ 98 und C ++ 2003. Siehe Michael Burr Erklärung dafür, wie und warum.

Nein, sie sind die gleichen. Aber es gibt einen Unterschied zwischen:

Test t;      // create a Test called t

und

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

Dies ist wegen der grundlegenden C ++ (und C) Regel. Wenn etwas möglicherweise eine Erklärung sein kann, dann ist es eine Erklärung

Edit: Re die Initialisierung Fragen im Zusammenhang mit POD und nicht-POD-Daten, während ich mit allem einverstanden, dass gesagt worden ist, möchte ich nur darauf hinweisen, dass diese Fragen nur, wenn die Sache gelten Wesen new'd oder auf andere Weise konstruiert keinen benutzerdefinierten Konstruktor. Wenn es eine solche Konstruktor ist es verwendet wird. Für 99,99% vernünftig dort entworfen Klassen wird ein solcher Konstruktor, und so können die Probleme ignoriert werden.

Im Allgemeinen wir default-Initialisierung im ersten Fall und Mehrwert-Initialisierung im zweiten Fall haben.

Zum Beispiel: falls mit int (POD-Typ):

  • int* test = new int - wir haben keine Initialisierung und den Wert von * Test kann beliebig sein

  • .
  • int* test = new int() - * Test 0 Wert

  • .

nächstes Verhalten abhängig von Ihrer Art der Prüfung. Wir haben defferent Fälle: Test defult Konstruktor haben, haben Test-generierten Standardkonstruktors, Test enthalten POD Mitglied, nicht POD Mitglied ...

Unter der Annahme, dass Testen eine Klasse mit einem definierten Konstruktor ist, gibt es keinen Unterschied. Letztere Form macht es ein wenig klarer, dass Test-Konstruktor ausgeführt wird, aber das ist es.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top