laufzeit- und übersetzungs-polymorphismus kombinierbar ?



  • hallo!
    ich habe ein konzept, dass im grunde gleich arbeiten soll, allerdings mit verschiedenen datenstrukturen. daher habe ich eine klassenhierarchie aufgebaut die folgendermaßen aussieht:

    template<class T1, class T2> Base { /* ... */ };

    class Derived1 : public Base<DataStruct1, DataType1> { /* ... / };
    class Derived2 : public Base<DataStruct2, DataType2> { /
    ... / };
    class Derived3 : public Base<DataStruct3, DataType3> { /
    ... / };
    class Derived4 : public Base<DataStruct4, DataType4> { /
    ... */ };

    die einzelnen derived-klassen müssen desweiteren von einer verwaltungsklasse verwaltet werden. dazu wäre es ideal, wenn ich die irgendwie laufzeitpolymorph in einer liste list<base<class T1, class T2>> verwalten könnte, was ja aber nicht geht. gibt es irgendeine andere möglichkeit, die derived-klassen polymorph zu handhaben, außer die klassen hart in die verwaltungsklasse zu coden ?

    danke im voraus,
    flashy



  • Kling für mich nach Mehrfachvererbung. Oder wolltest du das absichtlich nicht ?



  • Die Klassen haben gar keine gemeinsame Basisklasse. 🙄
    Templates werden zur Compilezeit übersetzt, du erzeugst also
    4 Base Klassen.

    Devil



  • wie meinst du das mit der mehrfachvererbung ? versteh ich grad nicht so wirklich.



  • @ Devil

    aha, klingt logisch 🙂

    jut dann danke erstmal



  • flashy schrieb:

    wie meinst du das mit der mehrfachvererbung ? versteh ich grad nicht so wirklich.

    Er meint wahrscheinlich, das du dir ne weitere Klasse als Basisklasse
    schreibst, die dann das Verhalten als Interface enthält.

    Devil



  • hallo dochnochmal ..
    also es stimmt wohl zwar, dass ich da vier basis-klassen erzeuge, aber die haben ja alle die implementierungen der Base-klasse. also handelt es sich doch um eine hierarchie mit Base als basis, oder nicht ?



  • Nein. Templates sind wie der Name schon sagt Schablonen. Mit deren Hilfe kannst du Klassen generieren lassen (deshalb generische Programmierung). Für verschiedene Templateargumente etnstehen auch verschiednene Klassen, selbst wenn deren Implementierung gleich ist. Du kannst aber auch so zwei Klassen schreiben, die innen völlig identisch sind. Dennoch sind es zwei verschiedene Klassen.

    Mittels Spezialisierung könnte sogar die Implementierung der generierten Klassen für verschiedene Type völlig verschieden aussehen.



  • ok, das mit den einzelnen basis-klassen wegen generischer prog. etc. ist mir jetzt klar. aber selbst wenn es verschiedene klassen sind, stehen sie doch in einer hierarchie oder nicht ? sie benutzen doch dieselben grundlegenden operationen für ihre eigenen datentypen oder?



  • flashy schrieb:

    ok, das mit den einzelnen basis-klassen wegen generischer prog. etc. ist mir jetzt klar. aber selbst wenn es verschiedene klassen sind, stehen sie doch in einer hierarchie oder nicht ? sie benutzen doch dieselben grundlegenden operationen für ihre eigenen datentypen oder?

    ne
    foo<a> und foo<b> haben nix miteinander zu tun.

    template<typename T>
    class A
    {
    public:
      void foo();
    };
    
    template<>
    class A<int>
    {
    public:
      void nofoo();
    };
    

    A<float> und A<int> haben ein unterschiedliches Interfaces



  • class Foo {
    public:
       void bar () {}
    };
    class Baz {
    public:
       void bar () {}
    };
    

    Beide bieten die selbe Funktionalität. Derivate der jeweiligen Klassen sind dennoch nicht in ein un der selben Hirachie. Ob du nun Klassen selber schreibst oder generieren lässt ist egal.



  • Was du willst is wahrscheinlich:

    class FooBase{
    public:
      virtual void foo()=0;
      virtual ~FooBase(){}
    };
    template<class T>
    class Foo:public FooBase{
      T t;
    public:
      void foo(){
        t=0;
      }
    };
    

    In dem Fall haben all Foo templates das gleiche Interfach nämlich FooBase. Alles was du jetzt noch tun ist nach FooBase upcasten.

    foo<a> und foo<b> haben nix miteinander zu tun.

    Doch:

    template<class T>
    void func(foo<T>f){
      f=0;
    }
    

    oder:

    template<class Foo>
    void func(Foo f){
      f=0;
    }
    

    Sie sollten (können) das gleiche statische Interface haben.

    Dynamisch haben sie aber nix gemein.


Anmelden zum Antworten