2011-02-02 3 views
1

J'ai une classe de base abstraite pour imposer certaines sous-classes afin de surcharger l'opérateur < <. Je stocke un tas de pointeurs vers des instances de ces sous-classes dans une pile std :: ... A un moment donné, je souhaite dupliquer l'élément supérieur de la pile (et le pousser sur le dessus).Sous-classe de la sous-classe abstraite en cours de duplication

Le problème est que je ne peux pas instancier une classe abstraite. Et évidemment puisque je veux le faire pour chacune de mes sous-classes, je ne connaîtrai pas le type ...

Je me demande si c'est encore possible sans ajouter une autre méthode virtuelle pure (disons 'Base * clone() = 0 ') et l'implémenter dans chacune de mes sous-classes? Sûrement il doit y avoir une manière plus propre.

Répondre

4

Je pense que vous avez réellement besoin d'une méthode Clone dans ce cas. Vous souhaitez copier dynamiquement l'élément de sous-classe au moment de l'exécution, et la manière normale de modifier le comportement au moment de l'exécution est la méthode virtuelle. Sans utiliser de méthode virtuelle, vous n'auriez aucun moyen de savoir de quel enfant il s'agit. Vous pouvez probablement utiliser CRTP pour générer automatiquement ce clone pour vous si:

// 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. 
}; 
+0

Parfait! Merci beaucoup. –

0

Voulez-vous dire faire une copie de la classe, plutôt que de dupliquer le pointeur.

Vous devrez soit implémenter votre propre saisie. en d'autres termes, avoir une fonction virtuelle qui renvoie le type de classe, puis créer la classe appropriée

Ou activer RTTI (Run-Time Type Information) pour faire la même chose. parce que les effets RTTI chaque classe est peut-être plus efficace pour créer votre propre méthode typeof.

Ensuite, vous pouvez

  1. Pop le pointeur
  2. Obtenez le type
  3. instancier la classe correcte à l'aide un constructeur de copie probablement dans un commutateur
  4. Poussez les deux en arrière sur la pile

psuedocode

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

Questions connexes