Frage zur Variablen Initialisierung im Konstruktor



  • Hallo ist es besser die Variablen Zuweisung in der Klasse zu schreiben oder außerhalb der Klasse ?

    ( Variablen zuweisung in der Klasse )

    #include <iostream>
    using namespace std;
    
    class autos
    {
    
            private:
                    int speed;
                    char *marke;
    
            public:
                    void wagen1 ();
    
            autos( int s  , char *m)
            {
                    speed = s;
                    marke = m;
    
            }
    
            ~autos()
            { cout <<"dest" << endl; }
    
    };
    
    void autos :: wagen1()
    {
     cout<<"Geschwindigkeit: " << speed << endl;
     cout<<"Marke: " << marke << endl;
    }
    
    int main()
    {
    
            {
            autos aut ( 100 , "test");
            aut.wagen1();
            }
    
    system("PAUSE");
    
    }
    

    ( Variablen zuweisung außerhalb der Klasse )

    #include <iostream>
    using namespace std;
    
    class autos
    {
    
            private:
                    int speed;
                    char *marke;
    
            public:
                    void wagen1 ();
    
            autos( int  , char* ) ;
    
            ~autos() ;
    
    };
    
    autos :: autos ( int s , char *m )
    {
    speed = s;
    marke = m;
    }
    
    autos::~autos()
    {
     cout<<"dest"<<endl;
    }
    
    void autos :: wagen1()
    {
     cout<<"Geschwindigkeit: " << speed << endl;
     cout<<"Marke: " << marke << endl;
    }
    
    int main()
    {
    
    {
    autos aut ( 100 , "test");
    aut.wagen1();
    }
    
    system("PAUSE");
    
    }
    


  • Das ist völlig egal^^ Das ist eher eine Designfrage. Ich finde letzteres besser, so, finde ich, behält man die Übersicht. Das ganze hat aber nichts mit Initialisierung zu tun. Im ctor-Rumpf sind die Variablen bereits initialisiert. Sieh dir dazu mal Initialisierungslisten im Konstruktor an.



  • Halte deine Header-Dateien nach Möglichkeit frei von Code, also reine
    Deklarationen, solange du keine Templates benutzt.



  • Hi,

    eigentlich hat deine Frage gar nichts mit "Initialisierung" oder "Zuweisung" zu tun, sondern ist eine Frage der Codeorganisation - sie betrifft JEDE Klassenfunktion.
    Technisch sind beide Varianten (wenn ich nichts übersehen habe) identisch (Ausnahme: "inline-Empfehlung").
    Es gibt nur sehr wenige "zwingende" Gründe für eine Defintion (!) innerhalb oder außerhalb der Klasse selbst: Templates brauchen Ersteres - ein bestimmtes "Austauschbarkeitskonzept" wird durch Zweiteres vereinfacht.
    Alles Andere ist IMHO Geschmackssache.

    Ich persönlich entscheide mich im Großen und Ganzen:
    - kleine/"organische" Implementierungen oder solche mit "dokumentierendem Charakter" packe ich in die Klassendeklaration.
    - alles Andere "raus".

    Oder anders ausgedrückt: Eine Klassendeklaration soll einem Außenstehenden Betrachter möglichst verständlich sein - da wo "Innendefinition" diesem Ziel dient, nutze ich sie.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    [...]Technisch sind beide Varianten (wenn ich nichts übersehen habe) identisch (Ausnahme: "inline-Empfehlung").[...]

    Das stimmt nur dann, wenn für die Version mit getrennter Deklaration und Definition die Definition in einer Übersetzungseinheit angesiedelt ist. Ist sie im Header definiert, verletzt dies (so wie der Code dort steht) die ODR und führt folglich zu einem Compilefehler.



  • speicher schrieb:

    Hallo ist es besser die Variablen Zuweisung in der Klasse zu schreiben oder außerhalb der Klasse ?

    Ich würde jegliche Methodendefinition in der Regel immer auslagern, und man trennt dies auch in den Dateien auf. In die Headerdateien gehören üblicherweise nur die Deklarationen, in der zugehörigen Sourcedatei in der Regel die Definitionen (Implementierung).

    Zudem ist es beim Konstruktor ohnehin besser die Initialisierungsliste zu verwenden, innerhalb des Konstruktorrumpfes ist dies eine nachträgliche Zuweisung (Was bei komplexeren Objekten durchaus Unterschiede macht).

    Besser:

    // autos.h
    #ifndef AUTOS_HEADER
    #define AUTOS_HEADER
    
    #include <string>
    
    class autos
    {
      private:
        int speed;
        std::string marke;
    
      public:
        //...
        autos(int speed, std::string const & marke);
        //...
    };
    #endif
    
    // autos.cpp
    #include "autos.h"
    #include <iostream>
    
    using namespace std; // Nicht im Header verwenden
    
    //...
    autos::autos(int speed, std::string const & marke)
    :   speed(speed),
        marke(marke)
    {
    }
    //...
    
    // main.cpp
    #include "autos.h"
    
    int main()
    {
      {
        autos aut(100, "test");
        aut.wagen1();
      }
    
      system("PAUSE");
    }
    


  • Tachyon schrieb:

    Simon2 schrieb:

    [...]Technisch sind beide Varianten (wenn ich nichts übersehen habe) identisch (Ausnahme: "inline-Empfehlung").[...]

    Das stimmt nur dann, wenn für die Version mit getrennter Deklaration und Definition die Definition in einer Übersetzungseinheit angesiedelt ist. Ist sie im Header definiert, verletzt dies (so wie der Code dort steht) die ODR und führt folglich zu einem Compilefehler.

    Sorry - das habe ich nicht verstanden.
    Was gilt nur im von Dir genannten Fall? Dass beide Varianten "technisch identisch" (damit meinte ich die Eigenschaften des kompilierten Programms) sind?
    ...

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Sorry - das habe ich nicht verstanden.
    Was gilt nur im von Dir genannten Fall? Dass beide Varianten "technisch identisch" (damit meinte ich die Eigenschaften des kompilierten Programms) sind?
    ...

    Gruß,

    Simon2.

    Wenn Du den Code so wie oben geschrieben getrennt (Deklarationen in Header, Definitionen in cpp, komplett in cpp geht auch) ausführst, ist Deine Aussage richtig. Dann ist es, mal abgesehen von der inline Empfehlung, identisch zum direkt in der Klasse eingebetetten Code.
    Wenn Du den getrennten Code aber komplett in den Header packst dann verletzt Du die ODR, sobald Du den Header mehr als einmal inkludierst. Hier hilft nur die explizite inline -Spezifizierung jeder Methode.



  • OK - Du meintest also "wenn man Fehler beim inlining macht, gibt's Linkerfehler".

    Davon habe ich nicht sprechen wollen, sondern vom Laufzeitverhalten des resultieren Programms.
    Auch hatte ich nicht den Eindruck, als ob der gute "speicher" überhaupt an Headerfiles gedacht (oder davon gehört ? 😉 ) hat.
    Aber vielleicht habe ich mich da auch geirrt.

    Auf jeden Fall ist es gut, wenn zu einem Thema verschiedene Leute jeweils neue Aspekte beitragen - so wie Du gerade.

    Gruß,

    Simon2.


Anmelden zum Antworten