Designproblem lösen



  • Hi, ich bin der, der hier schon letztens das Problem mit dem Slicing hatte 😉

    Angedacht ist folgendes:

    • Es soll eine Basisklasse "A" mit einer abstrakten Methode geben
    • Diese Basisklasse liefert den Benutzer über Methoden Instanzen/Objekte von einer Klasse B. Nur B ist für den Anwender der Klasse relevant, evtl. Klassen die von B erben interessieren ihn nicht
    class A
    {
    public:
    virtual MyFunc() = 0;
    
    std::vector<B*>& AccessVec();
    
    protected:
    std::vector<B*> vec;
    // std::vector<B> vec; Diese Variante wäre Ideal, ist aber wegen des Slicings nicht möglich 
    };
    

    Jetzt können verschiedene Klassen das "Interface" A mit der abstrakten Methode implementieren und ggfs. zur Realisierung Subtypen der Klasse B verwenden.
    Somit soll folgendes möglich sein:

    A *ptrA = new Subtyp1();  // An einer Stelle kann der Benutzer jetzt sagen "Nee, ich will jetzt mal die Ergebnisse von new Subtyp2() sehen
    

    Problem:
    Ich muss das mit Pointern realisieren, weil ich sonst in den Klassen die A mit Subtypen von B implementieren nicht alle Informationen gespeichert bekomme.

    Wie löse ich das Problem? Gibt's da ein tolles Designpattern?
    Falls ich das unklar erklärt habe: Einfach nachhaken 🙂



  • Ich muss das mit Pointern realisieren ...
    Wie löse ich das Problem?

    Die Loesung kennst du doch schon ... mit Pointern.



  • Ich denke auch, dass normale Polymorphie reichen sollte. Allerdings kannst du RAII mit Hilfe von Smart-Pointern umsetzen und somit eine Freigabe des Speichers sicherstellen.

    std::vector<B*>& AccessVec();
    

    Als Anmerkung: Funktionen, die Non-Const-Referenzen auf Membervariablen zurückgeben, sind nicht gut, da sie das Kapselungsprinzip umgehen (da kannst du gerade so gut public -Member haben). Schränke die Zugriffsfunktionen also stärker ein, indem du zum Beispiel in Lese- und Schreibzugriff unterteilst und vielleicht nur wenige Operationen implementierst, für die nicht der ganze Container bekannt sein muss.


  • Mod

    Meinst du mit 'An einer Stelle kann der Benutzer jetzt sagen "Nee, ich will jetzt mal die Ergebnisse von new Subtyp2() sehen"' das hier?

    #include<iostream>
    
    using namespace std;
    
    class A
    {
    protected:
      int member;
    public:
      A(const A &a): member(a.member){}
      A(const int &i): member(i){}
      virtual void MyFunc() = 0;
    }; 
    
    class subtyp1: public A
    {
    public:
      subtyp1(const A& a):A(a) {}
      subtyp1(const int& i): A(i) {}
      virtual void MyFunc(){
        cout << "Typ 1: " <<member << endl;
      }
    };
    
    class subtyp2: public A
    {
    public:
      subtyp2(const A& a):A(a) {}
      subtyp2(const int& i): A(i) {}
      virtual void MyFunc(){
        cout << "Typ 2: " <<member << endl;
      }
    };
    
    int main(){
      A * ptrA = new subtyp1(1);
      ptrA->MyFunc();
      (static_cast<subtyp2>(*ptrA)).MyFunc();
    }
    

    Ausgabe:

    Typ 1: 1
    Typ 2: 1
    

Anmelden zum Antworten