frage zur verheiratung von zwei template klassen



  • Welche Vererbungshierarchie? Ich sehe nicht eine, sondern zwei:

    EffA : public Base<int>
    EffB : public Basestd::string

    Wobei Base<int> und Basestd::string nix miteinander zu tun haben, vererbungstechnisch.

    Mir kommt EffA und EffB auch recht überflüssig vor.



  • hintergrund ist der,
    dass abgebildete vererbungshirarchie fest vorgegeben ist durch eine
    externe library, heisst ich kann sie nicht aendern.

    ich nutze besagte library in eigener software und verwalte derzeit eine liste von EffA Instanzen.
    die listen-struktur ist ein zentraler bestandteil der software und muss beibehalten werden. allerdings habe ich nun die anforderung dass diese liste auch EffB elemente enthalten koennen soll.

    Die Verwandtheit beider Klassen EffA und EffB (sind doch beiderseits Base abkoemmlinge dachte ich !?!) wollte ich fuer die deklaration einer solchen liste ausnutzen, habe aber keinen schimmer 😕, ob das ueberhaupt moeglich ist !?

    Sind da vielleicht unions nuetzlich um obiges unter einen hut zu bekommen !?

    danke vorab schonmal.



  • @kruemelkacker:
    das beispiel ist vereinfacht. dass effb und effa keine weiteren spezielleren eigentschaften besitzen macht sie natuerlich ueberfluessig, darum gehts mir aber nicht.
    ok, dann spreche ich Dir zuliebe nicht von vererbungs-hirarchie sondern von vererbungs-beziehung.

    ich hatte gedacht dass EffA und EffB abkoemmlinge von Base seien und damit schon "verwandt", aber irgendwas scheine ich da zu uebersehen !?


  • Mod

    Wie schon gesagt Base<int> und Basestd::string sind komplett unterschiedliche Klassen, die gar nichts miteinander zu tun haben, außer einer gemeinsamen Namenshälfte. Die beiden haben so viel gemeinsam wie die folgenden beiden Klassen:

    class Base_int { /* ... */ };
    
    class Base_std_string { /* ... */ };
    

    Die würdest du ja auch nicht als gemeinsame Basisklasse ansehen.



  • krümelkacker hat Recht, dass beide Klassen vom gleichen Template erben nützt hier nichts.
    Aber vielleicht hilft Dir boost::any weiter.

    Gruß
    Werner



  • hmm, irgendwie hat sich der knoten in meinem kopf noch nicht ganz geloest:
    ich moechte mein code-beispiel daher etwas erweitern, vielleicht ist das ja der grund:

    template <typename T>
    class Saeugetier
    {
      public:
        Saeugetier( T t, int z):besondereEigenschaft(t),anzahlZitzen(z){}
        T besondereEigenschaft;
        int anzahlZitzen;
    };
    class Schaf : public Sauegetier<int>
    {
      public:
        Schaf( int i ) : Saeugetier(i,4){}
    };
    
    class Mensch : public Saeugetier<std::string>
    {
      public:
        Mensch( std::string str ) : Saeugetier(str,2){}
    };
    

    wieso ist mensch nun nicht mit schaf verwandt ?
    ich hab ne liste von schafen und will diese verallgemeinern auf eine liste von saeugetieren (die auch mensch sein koennen ... abgesehen von der tatsache, dass manche menschen manchmal auch schafe sein koennen 😃 )



  • pepe75 schrieb:

    wieso ist mensch nun nicht mit schaf verwandt ?

    Weil Sauegetier<int> nicht mit Saeugetierstd::string verwandt ist.

    pepe75 schrieb:

    ich hab ne liste von schafen und will diese verallgemeinern auf eine liste von saeugetieren

    Das geht nicht, weil es keine Klasse namens Saeugetier gibt. Ein Klassentemplate ist keine Klasse, sondern eine Vorlage für ganz viele verschiedene Klassen, die nichts miteinander zu tun haben.



  • Zuerst sollte der Begriff "Template" geklärt werden. Schaue z.B. hier: http://www.c-plusplus.net/forum/128361-full oder http://de.wikipedia.org/wiki/Template_(Programmierung) oder http://www.willemer.de/informatik/cpp/cpptempl.htm.
    Dein Problem ist mir nicht 100% klar; aber eine Möglichkeit wäre vielleicht anstelle von Vererbung Aggregation oder Assoziation zu verwenden. Also mache ggf. eine gemeinsame Oberklasse von EffA und EffB welche alle Gemeinsamkeiten vereint und NUTZE nur in EffA Base<int> und in EffB Basestd::string.
    Gruß Helmut



  • Werner Salomon schrieb:

    Aber vielleicht hilft Dir boost::any weiter.

    boost::any ist IMO selten sinnvoll. Eher boost::variant. Dennoch denke ich, dass der TE eher noch eine gemeinsame Basisklasse haben will.



  • Falls die Objekte alle auf die gleiche Weise angesprochen werden, könnte noch type erasure eine Möglichkeit sein:

    class base_foo
    {
    public:
       virtual void bar() = 0;
       virtual ~base_foo(){}
    };
    template< class T >
    class foo
      : public base_foo
    {
    public:
        foo( T obj_ )
          : obj( std::move( obj_ ) )
        {
        }
        void bar()
        {
            obj.bar();
        }
    private:
        T obj;
    };
    
    std::vector< base_foo* > container;
    container.push_back( new foo< A >( A() ) );
    container.push_back( new foo< B >( B() ) );
    

    EDIT: siehe pyhax



  • @GorbGorb Du hast 3 verschiedene Bezeichnungen für foo_base : base_for, base_foo und foo_base 🤡



  • pepe75 schrieb:

    ich hatte gedacht dass EffA und EffB abkoemmlinge von Base seien und damit schon "verwandt", aber irgendwas scheine ich da zu uebersehen !?

    Ja, tust Du. Nix kann im Sinne der Vererbung Abkömmling von Base sein, weil Base gar keine Klasse ist. Es ist nur eine parametrisierte Vorlage, mit der Du diverse Klassen erzeugen kannst. Klassen wie Base<int> oder Base<string>. Das sind zwei verschiedene Klassen, die in keiner Vererbungsbeziehung zueinander stehen.


Anmelden zum Antworten