Was bedeuten die folgenden Ausdrücke in C++: Zero-, Default- und Value-Initialisierung?

Lesezeit: 4 Minuten

Was bedeuten die folgenden Ausdrucke in C Zero Default und
Rechnung

Was bedeuten die folgenden Ausdrücke in C++:

  • Null-Initialisierung,

  • Standard-Initialisierung und

  • Wert-Initialisierung

Was sollte ein C++-Entwickler darüber wissen?

  • Dies ist verwandt (aber nicht identisch mit) stackoverflow.com/questions/620137/…

    – Steve Jessop

    7. Dezember 2010 um 17:20 Uhr

  • Es gibt mehr! Die vollständige Liste der Initialisierungen: Value, Direct, Copy, List (C++11 New Intro), Aggregat, Reference, Zero, Constant und Default; en.cppreference.com/w/cpp/language/initialization listet sie alle mit Beispielen auf 🙂

    – legends2k

    7. Mai 2013 um 14:29 Uhr

C++03-Standard 8.5/5:

Zu Null initialisieren ein Objekt vom Typ T bedeutet:
— wenn T ein Skalartyp ist (3.9), wird das Objekt auf den Wert 0 (Null) gesetzt, der in T umgewandelt wird;
— wenn T ein Klassentyp ist, der nicht gewerkschaftlich ist, wird jedes nichtstatische Datenelement und jedes Unterobjekt der Basisklasse mit null initialisiert;
— Wenn T ein Union-Typ ist, wird das erste benannte Datenelement des Objekts mit Null initialisiert;
— Wenn T ein Array-Typ ist, wird jedes Element mit Null initialisiert;
— Wenn T ein Referenztyp ist, wird keine Initialisierung durchgeführt.

Zu default-initialize ein Objekt vom Typ T bedeutet:
— wenn T ein Nicht-POD-Klassentyp ist (Klausel 9), wird der Standardkonstruktor für T aufgerufen (und die Initialisierung ist falsch formatiert, wenn T keinen zugänglichen Standardkonstruktor hat);
— wenn T ein Array-Typ ist, wird jedes Element standardmäßig initialisiert;
— andernfalls wird das Objekt mit Null initialisiert.

Zu Wert initialisieren ein Objekt vom Typ T bedeutet:
— wenn T ein Klassentyp (Klausel 9) mit einem vom Benutzer deklarierten Konstruktor (12.1) ist, dann wird der Standardkonstruktor für T aufgerufen (und die Initialisierung ist schlecht formatiert, wenn T keinen zugänglichen Standardkonstruktor hat);
— Wenn T ein nicht gewerkschaftlicher Klassentyp ohne einen vom Benutzer deklarierten Konstruktor ist, dann wird jeder nicht statische Datenmember und jede Basisklassenkomponente von T mit einem Wert initialisiert;
— Wenn T ein Array-Typ ist, wird jedes Element mit einem Wert initialisiert;
— andernfalls wird das Objekt mit Null initialisiert

Ein Programm, das eine Standardinitialisierung oder Wertinitialisierung einer Entität des Referenztyps aufruft, ist falsch formatiert. Wenn T ein CV-qualifizierter Typ ist, wird die CV-unqualifizierte Version von T für diese Definitionen von Nullinitialisierung, Standardinitialisierung und Wertinitialisierung verwendet.

  • Dies könnte für C++11 veraltet sein. cpreference.com gibt an, dass die Standardinitialisierung nicht Member mit Null initialisieren (nur Wertinitialisierung tut dies).

    – Alexej Scholik

    9. Juli 2013 um 12:05 Uhr

  • @android wirft einen wichtigen Punkt auf, den ich an anderer Stelle nicht beantwortet sehe, also habe ich eine neue Frage gestellt. stackoverflow.com/questions/22233148/…

    – Adrian McCarthy

    6. März 2014 um 18:40 Uhr

1647209407 435 Was bedeuten die folgenden Ausdrucke in C Zero Default und
Michael Burr

Zu beachten ist, dass die „Wertinitialisierung“ im C++ 2003-Standard neu ist – sie existiert nicht im ursprünglichen Standard von 1998 (ich denke, dies könnte der einzige Unterschied sein, der mehr als eine Klarstellung ist). Siehe die Antwort von Kirill V. Lyadvinsky für die Definitionen direkt aus dem Standard.

Siehe diese vorherige Antwort zum Verhalten von operator new Einzelheiten zum unterschiedlichen Verhalten dieser Art der Initialisierung und wann sie eintreten (und wann sie sich von C++98 zu C++03 unterscheiden):

  • Machen die Klammern hinter dem Typnamen einen Unterschied zu new?

Der Kernpunkt der Antwort lautet:

Manchmal wird der vom new-Operator zurückgegebene Speicher initialisiert, manchmal nicht, je nachdem, ob der Typ, den Sie neu erstellen, ein POD ist oder ob es sich um eine Klasse handelt, die POD-Mitglieder enthält und einen vom Compiler generierten Standardkonstruktor verwendet .

  • In C++1998 gibt es zwei Arten der Initialisierung: Null und Standard
  • In C++2003 wurde eine 3. Art der Initialisierung, die Wertinitialisierung, hinzugefügt.

Um es gelinde auszudrücken, es ist ziemlich komplex und wenn die verschiedenen Methoden eingreifen, sind sie subtil.

Beachten Sie unbedingt, dass MSVC auch in VS 2008 (VC 9 oder cl.exe Version 15.x) den C++98-Regeln folgt.

Das folgende Snippet zeigt, dass MSVC und Digital Mars den C++98-Regeln folgen, während GCC 3.4.5 und Comeau den C++03-Regeln folgen:

#include <cstdio>
#include <cstring>
#include <new>

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

int main()
{
    char buf[sizeof(B)];
    std::memset( buf, 0x5a, sizeof( buf));

    // use placement new on the memset'ed buffer to make sure 
    //  if we see a zero result it's due to an explicit 
    //  value initialization
    B* pB = new(buf) B();   //C++98 rules - pB->m is uninitialized
                            //C++03 rules - pB->m is set to 0
    std::printf( "m  is %d\n", pB->m);
    return 0;
}

  • Nicht, dass es wichtig wäre intaber m() in der dritten Zeile initialisiert value m. Wichtig bei Wechsel int m; zu B m;. 🙂

    – Johannes Schaub – litb

    23. Oktober 2009 um 14:46 Uhr

  • Rechts – A und C werden in diesem Beispiel nicht verwendet (sie werden von der anderen verknüpften Antwort übernommen). Auch wenn C++98 und C++03 unterschiedliche Terminologie verwenden, wenn sie beschreiben, wie A und C aufgebaut sind, ist das Ergebnis in beiden Standards gleich. Nur struct B führt zu unterschiedlichem Verhalten.

    – Michael Burr

    23. Oktober 2009 um 14:55 Uhr

  • Was ich meinte, ist, dass, wenn Sie C zu ändern struct C { C() : m() {}; ~C(); B m; };dann hast du m.m 0 sein. Aber wenn es default-initialisieren würde m wie Sie sagen, C ++ 03 tut es dann m.m nicht wie in C++98 initialisiert werden.

    – Johannes Schaub – litb

    27. September 2010 um 14:44 Uhr


  • Weitere interessante Kommentare zur Handhabung dieser Funktion durch MSVC: stackoverflow.com/questions/3931312/…

    – Brent Bradburn

    26. Juli 2011 um 21:45 Uhr


  • g++ 4.4.7 20120313 für Red Hat 4.4.7-18 initialisiert m mit Ihrem Beispiel auf 0 (Kompilieren mit -std=c++98).

    – Jean

    27. April 2018 um 8:57 Uhr

999160cookie-checkWas bedeuten die folgenden Ausdrücke in C++: Zero-, Default- und Value-Initialisierung?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy