Designfrage: Codeduplizierung bei Konstruktoren - Defaultwerte



  • Hallo Forum,

    Ich habe eine Klasse Base und eine geerbte Klasse Derieved .
    Der Konstruktor von Base enthält Default-Parameter, der von Derieved demnach auch.

    class Base {
    public:
        // Konstruktor mit Default-Parameter
        Base(int a = 12, int b = 23, int c = 34);
    
        // ...
    };
    
    class Derieved : public Base {
    public:
        // Konstruktor mit den selben Default-Parametern
        Derieved(int a = 12, int b = 23, int c = 34);
    
        // ...
    };
    

    Das Problem: wenn sich nun ein Defaultwert in Base::Base ändert, müssen die Parameter auch in Derieved::Derieved geändert werden - und das finde ich sehr unschön.

    Wie würdet ihr so ein Problem lösen?

    Danke schon mal im Voraus.



  • Da die Defaultparameter wahrscheinlich nicht irgendwelche Magic Numbers sind, kannst du deren Werte als Konstanten im Header der Basisklasse deklarieren. So musst du bei einer Änderung nur einen Ort anpassen.

    P.S.: "derived" 🙂



  • Nexus schrieb:

    P.S.: "derived" 🙂

    Das sollte schon "Derieved" heißen :p
    Spaß bei Seite: Danke für den Hinweiß 😉

    Nexus schrieb:

    Da die Defaultparameter wahrscheinlich nicht irgendwelche Magic Numbers sind, kannst du deren Werte als Konstanten im Header der Basisklasse deklarieren.

    Wenn die Konstanten ausschließlich von dieser Klasse verwendet werden, haltest du es dann für sinnvoll sie als static const direkt mit in die Klasse zu packen? Oder widerspricht das dem allgemeinen Nutzen von static const ?

    Grüße



  • Vielleicht ist das ein Fall, wo ein Makro angebracht wäre?



  • Aragnier schrieb:

    Vielleicht ist das ein Fall, wo ein Makro angebracht wäre?

    Sicher nicht in C++ oder?


  • Mod

    Mir fällt es schwer, einen Fall auszudenken, in dem Defaultparameter für den Konstruktor einer Basisklasse sinnvoll sind.



  • daersc schrieb:

    Wenn die Konstanten ausschließlich von dieser Klasse verwendet werden, haltest du es dann für sinnvoll sie als static const direkt mit in die Klasse zu packen?

    Könntest du machen. Eventuell sammelst du solche Konstanten auch in einem separaten Namensraum.

    daersc schrieb:

    Aragnier schrieb:

    Vielleicht ist das ein Fall, wo ein Makro angebracht wäre?

    Sicher nicht in C++ oder?

    Hier macht es nicht besonders viel Sinn, aber Makros können schon ab und zu sinnvoll sein, um Codeduplizierung zu vermeiden.

    camper schrieb:

    Mir fällt es schwer, einen Fall auszudenken, in dem Defaultparameter für den Konstruktor einer Basisklasse sinnvoll sind.

    Wenn die Basisklasse nicht durch die abgeleitete Klasse initialisiert wird?



  • #define BASE_DEFAULT_PARAMS int a = 12, int b = 23, int c = 34
    
    class Base
    {
    public:
        Base(BASE_DEFAULT_PARAMS);
    };
    
    class Diehreift : public Base
    {
    public:
        Diehreift(int nochEinAndererParameter, BASE_DEFAULT_PARAMS);
    };
    

  • Mod

    Nexus schrieb:

    camper schrieb:

    Mir fällt es schwer, einen Fall auszudenken, in dem Defaultparameter für den Konstruktor einer Basisklasse sinnvoll sind.

    Wenn die Basisklasse nicht durch die abgeleitete Klasse initialisiert wird?

    Was mit LSP nicht zu vereinbaren ist. Zudem wissen wir nicht, was die Defaultargmuente repräsentieren.



  • camper schrieb:

    Was mit LSP nicht zu vereinbaren ist.

    Warum wird das Liskovsche Substitutionsprinzip verletzt, wenn die Basisklasse nicht abstrakt ist und man von ihr eigenständige Objekte erstellen kann? Die abgeleitete Klasse kann ja eine Erweiterung der Basisklasse repräsentieren und entsprechend mehr Parameter erfordern, welche eine Standardbelegung haben können.

    Beispiel:

    class Schiff
    {
        public:
            Schiff(float Geschwindigkeit = 200.f);
        // ...
    };
    
    class Faehre : public Schiff
    {
        public:
            Faehre(float Geschwindigkeit = 200.f, unsigned int TransportPlaetze = 80);
        // ...
    };
    

    Anwendung:

    int main()
    {
        Schiff s;
        Fahre f;
    }
    

Anmelden zum Antworten