C++11 Kurzform für vector class member Inititialisierung



  • Hallo,

    #include <vector>
    
    class Teil1 // Klassendefinition mit Initialisierung der Member
    {
    public:
          int ID     = 0;
       double Laenge = 0.0;
       double Breite = 0.0;
    }
    
    class Teil2 // Klassendefinition ohne Initialisierung der Member
    {
    public:
          int ID;
       double Laenge;
       double Breite;
    }
    
    int main()
    {
       std::vector<Teil1>T1;
       T1.resize(10); // Alle Member von T1 der 10 Vectoren sind mit 0 initialisiert :-)
    
       std::vector<Teil2>T2{};
       T2.resize(10); // Kein Member von T2 initialisiert :-(
    }
    

    Gibt es in C++11 eine kurze Möglichkeit alle Member von Teil2 bzw. T2 mit "0" zu initialiseren?



  • mireiner schrieb:

    std::vector<Teil2>T2{};
       T2.resize(10); // Kein Member initialisiert :-(
    

    Wie kommst du auf diese Vermutung? (Und bitte die Klammern weglassen)

    Ausserdem ginge es kürzer mit

    std::vector<Teil2>T2(10);
    

    aber ich nehme an, dein Beispiel hat schon einen Grund.



  • Danke für den Hinweis mit den Klammern zum anlegen von Vectoren.

    Allerdings werden mit "0" nur die Membervariablen der Klasse Teil1 initialisiert, die schon in der Klassendefinition mit "0" initialisert wurden. Die Vectoren der Klasse Teil2, in der keine Initialisierung innerhalb der Klassendefinition geschieht, werden nicht mit "0" initialisiert:

    std::vector<Teil1>T1(10); // Alle Klassenmember mit "0" initialisiert
       std::vector<Teil2>T2(10); // Keine Initialisierung der Klassenmember
    

    Ich habe oben die Vectoren über "resize()" angelegt, weil bei mir die Vectoren innerhalb einer Klasse definiert werden:

    class Beispiel1
    {
    public:
       Beispiel1()
       {
          Teil1.resize(10); // Funkioniert
       }
       std::vector<Teil1>T1
    }
    
    class Beispiel2
    {
    public:
       std::vector<Teil1>T1(10); // Fehlermeldung
    }
    


  • Nein, beides wird korrekt initializiert.

    Das nennt sich Value Initialization.

    Kurzform: Es gibt 3 Arten:
    - Default-Initialization (aka "Keine Initialisierung")
    - Zero-Initialization (aka memset 0)
    - Value-Initialization (aka 0 oder Default-Konstruktor)
    Wie dem obigen Link zu entnehmen ist, führt vector eine Value-Initialisierung durch, d.h. alle Member werden schön mit 0 gefüllt.



  • Nein, beides wird korrekt initializiert.

    Mmmh, merkwürdig - wie schon gesagt werden bei mir die Vektoren T2 der Klasse Teil2 nicht initialisiert. Kann das am MS Visual Studio 2013 Compiler liegen, den ich verwende?

    Das nennt sich Value Initialization http://en.cppreference.com/w/cpp/language/value_initialization

    Von der Seite habe ich übrigens die Initialisierung mit den {} geschweiften Klammern abgeschaut.



  • mireiner schrieb:

    Nein, beides wird korrekt initializiert.

    Mmmh, merkwürdig - wie schon gesagt werden bei mir die Vektoren T2 der Klasse Teil2 nicht initialisiert. Kann das am MS Visual Studio 2013 Compiler liegen, den ich verwende?

    Nach meiner Erfahrung macht das MSVC schon korrekt.

    Dass es bei dir nicht funktioniert liegt vermutlich daran dass dein "T2" etwas anders aussieht als das hier gezeigte, und aus irgend einem Grund kein POD mehr ist. Und deswegen nicht genullt wird.
    Es reicht z.B. schon wenn eine der Membervariablen einen Konstruktor hat.

    Also

    struct Foo // POD
    {
        int x;
        int y;
    };
    
    struct Foo // kein POD
    {
        int x;
        int y;
        std::string z;
    };
    


  • Ist dein VS mit Update 4?



  • mireiner schrieb:

    Ich habe oben die Vectoren über "resize()" angelegt, weil bei mir die Vectoren innerhalb einer Klasse definiert werden:

    Dann kannste den Konstruktor trotzdem in einer Initialisierungsliste aufrufen.



  • hustbaer schrieb:

    Dass es bei dir nicht funktioniert liegt vermutlich daran dass dein "T2" etwas anders aussieht als das hier gezeigte, und aus irgend einem Grund kein POD mehr ist. Und deswegen nicht genullt wird.
    Es reicht z.B. schon wenn eine der Membervariablen einen Konstruktor hat.

    Uff - das war es - danke für den Tip: Die Vector Deklaration stammt aus einem Qt 5.4 Programm. Dort befindet sich in der Klasse zusätzlich noch die Member Variable QPointF Point. Ohne QPointF funktioniert die Initialisierung einwandfrei.

    class Teil1
    {
    public:
          int   ID;
       double   Laenge;
       double   Breite;
       QPointF  Point;
    };
    
    class Teil2
    {
    public:
          int   ID;
       double   Laenge;
       double   Breite;
    };
    
    std::vector<Teil1>T1(10); // Member werden nicht initialisiert
    std::vector<Teil2>T2(10); // Member werden initialisiert
    

    Damit habe ich natürlich nicht gerechnet. Will sicher heißen, dass Qt noch nicht C++11 kompatibel ist.



  • mireiner schrieb:

    Will sicher heißen, dass Qt noch nicht C++11 kompatibel ist.

    WTF? Nein! Das heisst nur dass du etwas verwenden möchtest von dem du offenbar viel zu wenig verstehst, nämlich die automatische zero-initialization von PODs.
    Aber als guter Noob gleich mal behaupten dass der fremde Code schuld ist. 🙄

    Verpass deiner Klasse einen Konstruktor wo du alle Member explizit auf Null setzt und die Sache ist erledigt.



  • Nathan schrieb:

    Dann kannste den Konstruktor trotzdem in einer Initialisierungsliste aufrufen.

    Ja danke, ist auch eine Möglichkeit.



  • hustbaer schrieb:

    Aber als guter Noob gleich mal behaupten dass der fremde Code schuld ist.

    Sorry - bin Anfänger und verstehe wirklich nicht sonderlich viel von der Materie. Qt wollte ich damit nicht schlecht machen - bin sehr zufrieden damit.

    hustbaer schrieb:

    Verpass deiner Klasse einen Konstruktor wo du alle Member explizit auf Null setzt und die Sache ist erledigt.

    Das hatte ich ohnehin schon gemacht (siehe Eingansposting oben, Klasse Teil1) - wollte nur in Erfahrung bringen, ob es unter C++11 nicht noch eine kürzere Variante gibt.

    Danke an alle für die Hilfe!


Anmelden zum Antworten