Frage

Ich habe eine abstrakte Basisklasse, um einige Unterklassen durchzusetzen, um den << Operator zu überladen.

Ich speichere ein paar Zeiger für Fälle dieser Unterklassen in einem std :: stapel ... irgendwann möchte ich das obere Element des Stapels duplizieren (und darüber drücken).

Das Problem ist, dass ich keine abstrakte Klasse instanziieren kann. Und natürlich, da ich dies für jede meiner Unterklassen tun möchte, werde ich den Typ nicht wissen ...

Ich frage mich, ob dies auch möglich ist, ohne eine andere reine virtuelle Methode hinzuzufügen (sagen wir 'Basis *Clone () = 0') und implementieren Sie sie in jeder meiner Unterklassen. Sicherlich muss es einen saubereren Weg geben.

War es hilfreich?

Lösung

Ich denke du brauchst tatsächlich eine Clone Methode in diesem Fall. Sie möchten das Subklasselement zur Laufzeit dynamisch kopieren, und die normale Möglichkeit, das Verhalten zur Laufzeit zu ändern, sind virtuelle Methoden. Ohne eine virtuelle Methode hätten Sie keine Möglichkeit, herauszufinden, welches Kind es ist. Sie könnten wahrscheinlich CRTP verwenden, um diesen Klon automatisch für Sie zu generieren:

// Totally uncompiled and untested.
class Base
{
public:
    virtual Base* Clone() const = 0;
};

template <class T>
class Child : public Base
{
public:
    virtual Base* Clone() const { return new T(*static_cast<T*>(this)); }
protected:
    Child(); // Can't instantiate directly
    Child(const Child& right); // Can't instantiate directly
};

class Grandchild : public Child<Grandchild>
{
    // Clone should do the right thing.
};

Andere Tipps

Meinen Sie eine Kopie der Klasse, anstatt den Zeiger zu duplizieren?

Sie müssen entweder Ihr eigenes Tippen implementieren. Mit anderen Worten haben eine virtuelle Funktion, die den Klassentyp zurückgibt und dann die entsprechende Klasse erstellt

Oder aktivieren Sie RTTI (Laufzeitinformationen), um dasselbe zu tun. Denn RTTI bewirkt jede Klasse, ist möglicherweise effizienter, um Ihre eigene Typenmethode zu erstellen.

Dann kannst du

  1. Pop den Zeiger
  2. Holen Sie sich den Typ
  3. Instantieren Sie die richtige Klasse mit einem Kopierkonstruktor wahrscheinlich in einem Switch
  4. Schieben Sie beide zurück auf den Stapel

PSUDOCODE

 base* ptr = stack.pop()
 base *copy
 switch (ptr->typeof()) {
  case class1type : copy = new class1(ptr) break;
  case class2type : copy = new class2(ptr) break;
  ...
}

stack.push (ptr)
stack.push(copy)

DC

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top