polymorphie ohne Zeiger?



  • Hallo,

    ich würde gerne auf Zeiger verzichten, sondern Objekte wie eingebaute Datentypen benutzen können.

    Konkret möchte ich eine abstrakte Klasse "Set" erstellen, welche die grundlegenden Rechenoperationen als virtuelle Methoden bereitstellt. Andere Klassen (für nummerische Berechnungen) sollen jetzt einfach diese Klasse Set benutzen und es sollte ihnen egal sein, was nun schließlich dahinter für einen Datentyp ist.

    Nun, das erste Problem ist, dass meine Operatoren (z.B. operator+) ja Objekte zurückgeben sollen, die von Set abgeleitet sind.

    virtual Set operator+(const Set&) const;
    

    Funktioniert schonmal nicht, wenn Set abstrakt ist. Ok, ich könnte ja dummy Implementierungen machen. Aber da ist ja das zweite Problem. Ich kann ihm kein Double Objekt als Set Objekt verkaufen, auch wenn sie voneinander abgeleitet sind. Das Problem tritt so auf:

    const Double& myDouble = dynamic_cast<const Double&>(set);
    

    bekomme ich folgende Warnung:

    e:\Uni\Mathe 4\Math\Double.cpp(20) : warning C4541: 'dynamic_cast' für polymorphen Typ 'math::Set' mit /GR- verwendet; unvorhersehbares Verhalten möglich

    Ist jetzt das Design scheiße und komme ich nicht um Zeiger herum? Aber eigentlich habe ich keine Lust auf ständiges new und delete. Wäre auch nicht schön, weil die Algorithmen nicht mehr so klar rauskommen, weil noch sprachspezifische Dinge getan werden müssen.

    Achso, hatte es natürlich auch schon mit Templates versucht. Aber irgendwie gefiel es mir nicht alle Klassen und Methoden direkt in den Code einzubinden und nicht als Lib dazulinken zu können. Außerdem konnte ich dann nur überladene Operatoren benutzen und nicht Methoden wie z.B. absoluteValue oder Norm oder sowas.

    Danke im Voraus.



  • Achso, hatte es natürlich auch schon mit Templates versucht. Aber irgendwie gefiel es mir nicht alle Klassen und Methoden direkt in den Code einzubinden und nicht als Lib dazulinken zu können. Außerdem konnte ich dann nur überladene Operatoren benutzen und nicht Methoden wie z.B. absoluteValue oder Norm oder sowas.

    Um Datentypen variabel zu gestalten, sind Templates der einzig wahre Weg.
    Ich verstehe allerdings deinen letzten Einwand nicht. Templates können
    beliebige Methoden enthalten und sind nicht auf Operatoren beschränkt. Wäre
    das der Fall, würde die ganze STL nicht funktionieren.



  • Loggy schrieb:

    e:\Uni\Mathe 4\Math\Double.cpp(20) : warning C4541: 'dynamic_cast' für polymorphen Typ 'math::Set' mit /GR- verwendet; unvorhersehbares Verhalten möglich

    Das liegt daran, dass in deinem Compiler RTTI deaktiviert ist.



  • Ganz ohne Zeiger wird das meiner Meinung nach nicht gehen, allerdings das delete kann man Weg hauen. Ich mache oft Sachen in der flogenden Art

    class InstanceBase
    {
    public:
      virtual InstanceBase*clone()const=0;
      virtual std::string to_string()const{return "<not printable>";}
      virtual ~InstanceBase(){}
    };
    class Uninitialized:public InstanceBase
    {
      //...
    };
    class Value{
    public:
      Value():val(new Uninitialized){}
      explicit Value(InstanceBase*val):
        val(val){}
      Value(const Value&other):val(other.val->clone()){}
      void swap(Value&other)throw(){std::swap(val, other.val);}
      Value&operator=(const Value&other)
      {
        Value val(other);
        swap(val);
        return *this;
      }
      std::string to_string()const{return val->to_string();}
      ~Value(){delete val;}
    private:
      InstanceBase*val;
    };
    


  • was soll das swap hier eigentlich?

    Value&operator=(const Value&other) 
      { 
        Value val(other); 
        swap(val); 
        return *this; 
      }
    

    hab ich nicht ganz verstanden;-) swap ist ja tauschen...
    wann liefert das swap da ne exception?

    cu



  • cppler schrieb:

    swap ist ja tauschen...
    wann liefert das swap da ne exception?

    Garnicht, das ist ja der Gag dran. Wenn aber der Copy-Ctor fehlschlagen kann, dann merkst Du das und Dein alter Wert ist noch vorhanden. Überschreibst Du die Werte Deiner Attribute in der Klasse einfach der Reihe nach und eines davon wirft ne Exception, dann hat Deine Klasse den Zustand schon verändert und Du hängst sozusagen in nem Zwischenzustand.

    Hier ist es halt so, daß die Zuweisung entweder klappt oder sie wirft ne Exception, dann hat sich am Objekt aber nichts geändert. Du hast also den definierten Zustand von vor der Zuweisung.


Anmelden zum Antworten