Frage zu Konstruktoren



  • Hallo, mir ist gerade eine Frage aufgekommen. Es handelt sich um Konstruktoren.
    Genauer um Defaultwerte. Folgendermaßen kann man ja der Klasse Beispiel Defaultwerte zuweisen, wenn man die Werte nicht selbst als Parameter übergibt:

    // beispiel.h
    #include <string>
    // ...
    class Beispiel
    {
    private:
        std::string name;
        int nummer;
    public:
    // Default-Konstruktor
    Beispiel()
    {
        name = "ding";
        nummer = 1111;
    }
    // Eigene Werte als Parameter:
    Beispiel(std::string name, int nummer)
    {
        this->name = name;
        this->nummer = nummer;
    }
    };
    

    Aber was ist nun der Unterschied zur folgender Variante:

    // beispiel.h
    #include <string>
    // ...
    class Beispiel
    {
    private:
        std::string name;
        int nummer;
    public:
    // Default-Konstruktor und eigene Werte in einem
    Beispiel(std::string name = "ding", int nummer = 1111)
    {
        this->name = name;
        this->nummer = nummer;
    }
    };
    

    Hier werden ja auch, wenn beim Aufruf keine Werte übergebn werden, die Standardwerte übernommen. Und wenn beides gleich ist - welche Variante ist dann besser / welcher Stil ist besser?

    Gruß

    Edit: War ein Fehler in der 2. Variante, nochmal verbessert 😉


  • Mod

    Es gibt einen Unterschied, denn die zweite Variante kann auch mit nur einen string (und ohne den int) aufgerufen werden. Mit der ersten Variante vermittelst du tendenziell eher den Eindruck, dass der parameterlose Aufruf dem Konzept eines "leeren" Objektes entspricht, die zweite Variante vermittelt eher das Konzept eines Standardwertes. Wenn du Überladung anstatt Defaultparameter benutzt, vermittelst du dadurch auch den Eindruck, dass in den überladenen Funktionen etwas prinzipiell unterschiedliches geschieht, ansonsten hättest du schließlich Defaultparameter nutzen können und dir doppelte Schreibarbeit (und Wartung) sparen können.

    Am besten ist keine von beiden. Beide sollten Initialisierungslisten benutzen.

    ^(Es gibt noch ein paar eher theoretische Unterschiede. Zum Beispiel, kann man bei der ersten Variante Breakpoints im Debugger für die unterschiedlichen Varianten setzen. Dafür muss man bei der zweiten Variante im Debugger Breakpoints für die unterschiedlichen Varianten setzen. 🙂 )^



  • Alles klar, sehr hilfreich!
    Eine Frage noch, was meinst du mit "beide Varianten sollten Initialisierungslisten verwenden"? Kannst du ein Beispiel dazu geben?

    Gruß



  • Hallo,

    Default Konstruktor mit Initialisierungsliste

    Beispiel() : 
        name("ding"), 
        nummer(1111) 
    {}
    

    http://de.wikipedia.org/wiki/Initialisierungsliste


Anmelden zum Antworten