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();
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.
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.
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.
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...
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.
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