Implementierung mit ":"?



  • Hallo,

    ich habe folgendes in einem c++ Lehrbuch gefunden:

    //Klasse
    class Klasse
    {
    public:
         Klasse();
    private:
         int a,b,c;
    };
    
    //Implementierung
    Klasse::Klasse()
         :a(0), b(0),c(0)
    {
    
    }
    

    ist das das Gleiche als würde ich den Konstruktor so Implementieren:

    Klasse::Klasse
    {
         a = 0;
         b = 0;
         c = 0;
    }
    

    oder gibt zwischen den Implementationen unterschiede?



  • Du bist im falschen Forum. Trotzdem bekommst Du eine Antwort von mir:

    Ja, es ist das gleiche.

    Es gibt Leute, die ziehen die erste Form vor, andere (wie ich z.B.) die zweite Form. Wenn Du aber Membervariablen mit eigenen Konstruktor hast, solltest Du nach Möglichkeit die erste Form verwenden, da diese dann schneller ist. In der zweiten Variante müsste nämlich der Konstruktor aufgerufen werden um dann gleich die Initialisierung durch den Zuweisungsoperator zu überschreiben.

    mfg Martin



  • Heeiiigou schrieb:

    ist das das Gleiche als würde ich den Konstruktor so Implementieren: [...]

    Nein, es ist absolut nicht das gleiche.

    Heeiiigou schrieb:

    oder gibt zwischen den Implementationen unterschiede?

    Ja, bei der ersten Variante werden a, b und c mit 0 initialisiert, bei der zweiten Variante werden a, b und c im Allgemeinen erst Defaultinitialisiert und ihnen gleich darauf ein neuer Wert zugewiesen.



  • Nein, es ist nicht gleich. Bei der ersten Version werden die Membervariabeln initialisiert, in der zweiten Version wird ihnen ein Wert zugewiesen (ein wichtiger Unterschied).

    Den Unterschied kann man an folgendem Beispiel sehen:

    class Point
    {
    private:
        int _x, _y;
    public:
        Point(int x, int y) : _x(x), _y(y) { }
    };
    
    class Foo
    {
    private:
        Point p;
    public:
        Foo(int x, int y) : p(Point(x,y))
        {
    
        }
    };
    

    Mit

    Foo(int x, int y)
        {
           p = Point(x,y);
        }
    

    wird das Programm nicht kompilieren, denn die Klasse Point hat keinen Default-Konstruktor und kann deshalb nicht default initialisiert werden.



  • das ist nicht das gleiche!

    Wenn die Member const sind, oder eine Referenz sind, oder eine Membervariable keinen Default Konstruktor hat, so musst du sie in der Initialisierungsliste (so nennt sich das Ding) initialisieren.

    Und dann gibt es noch Fälle, wo es performancerelevant ist.
    Schreibst du keine Initialisierungsliste, so legt der Compiler eine für dich an - es werden also die Default Konstruktoren von den Membervariablen aufgerufen.
    Das heißt, die Variable wird standardmäßig einmal initialisiert, und kurz darauf setzt du sie auf einen passenden Wert. Warum nicht gleich auf passenden Wert setzen?

    Also, gewöhn dir am besten die Verwendung der Initialisierungsliste an!



  • Hi,

    grundsätzlich habt Ihr ja recht. Aber im konkreten Beispiel handelt es sich um Membervariablen vom Typ int. Da ist es tatsächlich das gleiche.

    mfg Martin



  • mgaeckler schrieb:

    grundsätzlich habt Ihr ja recht. Aber im konkreten Beispiel handelt es sich um Membervariablen vom Typ int. Da ist es tatsächlich das gleiche.

    Nein. Es kompiliert in dem konkreten Beispiel mit den meisten Compilern in einem optimierten Build sehr wahrscheinlich auf den gleichen Maschinencode ruter. Aber es ist trotzdem nicht das gleiche...



  • dot schrieb:

    mgaeckler schrieb:

    grundsätzlich habt Ihr ja recht. Aber im konkreten Beispiel handelt es sich um Membervariablen vom Typ int. Da ist es tatsächlich das gleiche.

    Nein. Es kompiliert in dem konkreten Beispiel mit den meisten Compilern in einem optimierten Build sehr wahrscheinlich auf den gleichen Maschinencode ruter. Aber es ist trotzdem nicht das gleiche...

    Ein Compiler, der das nicht im Sinne des Entwicklers auflösen kann, gehört in die Tonne getreten. Oder kannst Du mir einen Grund nennen, warum der Compiler das nicht machen sollte?



  • mgaeckler schrieb:

    dot schrieb:

    mgaeckler schrieb:

    grundsätzlich habt Ihr ja recht. Aber im konkreten Beispiel handelt es sich um Membervariablen vom Typ int. Da ist es tatsächlich das gleiche.

    Nein. Es kompiliert in dem konkreten Beispiel mit den meisten Compilern in einem optimierten Build sehr wahrscheinlich auf den gleichen Maschinencode ruter. Aber es ist trotzdem nicht das gleiche...

    Ein Compiler, der das nicht im Sinne des Entwicklers auflösen kann, gehört in die Tonne getreten.

    Wie gesagt: Das ändert nichts daran, dass Initialisierung etwas grundlegend anderes ist als eine Zuweisung...

    mgaeckler schrieb:

    Oder kannst Du mir einen Grund nennen, warum der Compiler das nicht machen sollte?

    Das ist nicht der Punkt...



  • Danke für die Hilfe (:

    also nochmal Zusammenfassend.

    Es handelt sich dabei um eine sogenannte Initialisierungsliste, mit der man Kostruktoren aufrufen kann die Parameter haben, da sonst versucht wird einen Default-Konstruktor aufzurufen und dieser, wenn er nicht existiert, zu Fehlern führt.

    😃 👍


Log in to reply