vector mit sub klassen



  • Guten Tag,

    sagen wir ich habe eine abstrakte Basisklasse A und 2 Subklassen B und C:

    class A {
    public:
       virtual void aMethod() = 0;
    };
    
    class B : public A {
    public:
       virtual void aMethod() { ... };
       void bMethod() { ... }
    };
    
    class C : public A {
    public:
       virtual void aMethod() { ... };
       void cMethod() { ... }
    };
    

    Jede Subklasse überschreibt aMethod() und hat eine spezifische Methode.

    Jetzt habe ich auch noch eine Managerklasse, die einen vector von B* und C* hält:

    class Manager {
       vector<B*> mBs;
       vector<C*> mCs;
    };
    

    Manager erzeugt jetzt mit new Instanzen von Bs und Cs und pusht sie in den jeweiligen vector. Manchmal iteriere ich über mBs und rufe auf allen Objekten bMethod() auf (selbiges gilt für mCs):

    for(vector<B*>::iterator it = mBs.begin(); it != mBs.end(); ++it)
       (*it)->bMethod();
    

    Allerdings will ich zu 90% einfach nur für ALLE B* und C* die Basisklassen Methode aMethod() aufrufen. Im Moment mache ich das umständlich, indem ich über die einzelnen vectors iteriere:

    for(vector<B*>::iterator it = mBs.begin(); it != mBs.end(); ++it)
       (*it)->aMethod();
    for(vector<C*>::iterator it = mCs.begin(); it != mCs.end(); ++it)
       (*it)->aMethod();
    

    Hier würde ich natürlich viel lieber irgendwie über einen Container (oder mehrere) von A* iterieren.

    Hat jemand eine Idee, wie ich das in C++ umsetzen könnte, dass ich Container habe, ich denen ich spezifische Mehoden aufrufen kann, aber sie auch per Basisklassenzeiger ansprechen kann?



  • klassa schrieb:

    Hat jemand eine Idee, wie ich das in C++ umsetzen könnte, dass ich Container habe, ich denen ich spezifische Mehoden aufrufen kann, aber sie auch per Basisklassenzeiger ansprechen kann?

    das einzige, was mir dazu einfällt, ist gar nicht schön:

    std::vector<A*> allObjects;
    
    for (A* obj : allObjects)
    {
      obj->aMethod();
    
      if (B* b = dynamic_cast<B>(obj))
        b->bMethod();
    
      if (C* c = dynamic_cast<C>(obj))
        c->cMethod();
    }
    

    Wenn du dein Problem etwas präziser darstellst, können wir dir bestimmt bei einer saubereren Lösung helfen!



  • Im übrigen wäre es hier auch gut, Smartpointer zu verwenden, die kümmern sich automatisch um delete und copy. Und machen deinen Code exceptionsafe.

    Zum Problem selber: Kannst du nicht versuchen den speziellen B und C Teil zu verallgemeinern und nach A auszulagern? Irgendetwas müssen B und C ja mit A zu tun haben, sonst würdest du keine Vererbung verwenden (hoffe ich!), das heißt du solltest auch die speziellen Eigenschaften verallgemeinern können. Ansonsten ist Vererbung ggf. unangebracht.



  • Nathan schrieb:

    Zum Problem selber: Kannst du nicht versuchen den speziellen B und C Teil zu verallgemeinern und nach A auszulagern? Irgendetwas müssen B und C ja mit A zu tun haben, sonst würdest du keine Vererbung verwenden (hoffe ich!), das heißt du solltest auch die speziellen Eigenschaften verallgemeinern können. Ansonsten ist Vererbung ggf. unangebracht.

    Die Gemeinsamkeiten habe ich in dem Beispiel mit aMethod() bezeichnet. Klar haben sie noch einige weitere gemeinsame Methoden (die alle in A sind), aber das ist für das Problem ja egal.

    Und das B und C auch unterschiedliche Methoden haben ist ja auch normal - sonst bräuchte ich ja keine neue Klasse und könnte gleich nur As verwenden.



  • klassa schrieb:

    Und das B und C auch unterschiedliche Methoden haben ist ja auch normal - sonst bräuchte ich ja keine neue Klasse und könnte gleich nur As verwenden.

    Nein.

    C++ Coding Standards schrieb:

    Inherit to Be Reused, Not to Reuse

    Der Sinn von Vererbung ist nicht, Code der in A ist, "elegant" wieder zu verwenden, sondern allgemeiner Code, der nur mit A Objekten arbeitet, zu erweitern. Der Code der A verwendet, sollte nichts von B und C wissen! Aber mithilfe virtueller Methoden in B und C kannst du ihn modifizieren.



  • Nathan schrieb:

    klassa schrieb:

    Und das B und C auch unterschiedliche Methoden haben ist ja auch normal - sonst bräuchte ich ja keine neue Klasse und könnte gleich nur As verwenden.

    Nein.

    C++ Coding Standards schrieb:

    Inherit to Be Reused, Not to Reuse

    Der Sinn von Vererbung ist nicht, Code der in A ist, "elegant" wieder zu verwenden, sondern allgemeiner Code, der nur mit A Objekten arbeitet, zu erweitern. Der Code der A verwendet, sollte nichts von B und C wissen! Aber mithilfe virtueller Methoden in B und C kannst du ihn modifizieren.

    Mein Code in A weiß doch auch absolut nichts von B und C. Ich habe jetzt auch ehrlich gesagt keine Lust auf eine Grundsatzdiskussion zu Vererbung. Nur, ob man für das von mir geschilderte Problem was machen kann. Wenn nicht is das auch ok.



  • klassa schrieb:

    Nathan schrieb:

    klassa schrieb:

    Und das B und C auch unterschiedliche Methoden haben ist ja auch normal - sonst bräuchte ich ja keine neue Klasse und könnte gleich nur As verwenden.

    Nein.

    C++ Coding Standards schrieb:

    Inherit to Be Reused, Not to Reuse

    Der Sinn von Vererbung ist nicht, Code der in A ist, "elegant" wieder zu verwenden, sondern allgemeiner Code, der nur mit A Objekten arbeitet, zu erweitern. Der Code der A verwendet, sollte nichts von B und C wissen! Aber mithilfe virtueller Methoden in B und C kannst du ihn modifizieren.

    Mein Code in A weiß doch auch absolut nichts von B und C. Ich habe jetzt auch ehrlich gesagt keine Lust auf eine Grundsatzdiskussion zu Vererbung. Nur, ob man für das von mir geschilderte Problem was machen kann. Wenn nicht is das auch ok.

    Es geht nicht um den Code in A, sondern um den Code der A verwendet.
    Und für dein geschildertes Problem ist die eleganteste Lösung die von daddy_felix.


Anmelden zum Antworten