Wenn ich nur einige ausgewählte Werte einer C ++ - Struktur initialisieren müsste, wäre dies richtig:
struct foo {
foo() : a(true), b(true) {}
bool a;
bool b;
bool c;
} bar;
Bin ich davon ausgehen , korrigiere ich mit einem enden würde struct
Element namens bar
mit Elementen bar.a = true
, bar.b = true
und eine nicht definierte bar.c
?
bar
ist eine Variable.typedef struct foo {} bar;
.bar
ist die Struktur, was istfoo
? Entspricht dies dem Definieren einerfoo
Struktur und dem separaten Deklarieren einer neuen Variablenbar
als Typfoo
?struct foo {//something};
foo bar;
Antworten:
Ja.
bar.a
undbar.b
werden auf true gesetzt, sind aberbar.c
undefiniert. Bestimmte Compiler setzen es jedoch auf false.Sehen Sie hier ein Live-Beispiel: struct demo
Gemäß C ++ Standard Abschnitt 8.5.12:
Für primitive integrierte Datentypen ( bool , char, wchar_t, short, int, long, float, double, long double) erhalten nur globale Variablen (alle statischen Speichervariablen) den Standardwert Null, wenn sie nicht explizit initialisiert werden.
Wenn Sie nicht wirklich möchten, dass undefined
bar.c
mit beginnt, sollten Sie es auch so initialisieren, wie Sie es fürbar.a
und getan habenbar.b
.quelle
Sie müssen nicht einmal einen Konstruktor definieren
struct foo { bool a = true; bool b = true; bool c; } bar;
Zur Verdeutlichung: Diese werden als Klammer- oder Gleichheitsinitialisierer bezeichnet (da Sie anstelle des Gleichheitszeichens auch die Klammerinitialisierung verwenden können). Dies gilt nicht nur für Aggregate: Sie können dies in normalen Klassendefinitionen verwenden. Dies wurde in C ++ 11 hinzugefügt.
quelle
c++
bedeutet das Tag C ++ 11. Leute können gerne C ++ 98 oder C ++ 03 sagen, wenn sie eine alte Version diskutieren wollen. Und irgendwann im nächsten Jahr wird sich das nacktec++
Tag wieder ändern und C ++ 14 bedeuten.std::is_pod<T>::value
) macht und in diesem Sinne dem Schreiben eines nicht standardmäßigen Konstruktors entspricht, der dieselben Werte in einer Initialisiererliste festlegt.Sie können dies mit einem Konstruktor wie dem folgenden tun:
struct Date { int day; int month; int year; Date() { day=0; month=0; year=0; } };
oder so:
struct Date { int day; int month; int year; Date():day(0), month(0), year(0){} };
In Ihrem Fall ist bar.c undefiniert und sein Wert hängt vom Compiler ab (während a und b auf true gesetzt wurden).
quelle
int
die Mitglieder anstelle von s benutzerdefinierte Klassen wären , die die Definition von trivial erfüllen müssten (z. B. kein nicht standardmäßiger Konstruktor), wäre dies ein Grund, im Body zuzuweisen, anstatt in der Init-Liste zu konstruieren. Die Anzahl der Szenarien, in denen dies nützlich ist, ist jedoch vermutlich eine winzige Minderheit. Daher sollten Init-Listen definitiv die Standardempfehlung sein - mit den seltenen Ausnahmen, die im Gegensatz zu hier sorgfältig qualifiziert und gerechtfertigt sind.default
Ctors unangemessen sind und deren Standardlayout Nichtkonstruktoren ausschließtdefault
, muss die Initialisierung auf eine andere Weise durchgeführt werden, sei esoperator=
oder eine Init-Funktion oder was auch immer. Es ist sinnvoll, diese "Initialisierung" im Konstruktor des Elternteils durchzuführen, dh in seinem Körper zuzuweisen.operator=
Dies entspricht der In-Body-Zuordnung von Grundelementen wie in der Post. Überdenken oder tangential vielleicht, aber wahr ;-)Eine explizite Standardinitialisierung kann helfen:
struct foo { bool a {}; bool b {}; bool c {}; } bar;
Verhalten
bool a {}
ist das gleiche wiebool b = bool();
und zurückfalse
.quelle