2012-11-19 2 views
0

J'ai récemment reçu un very good answer as how to overload specific class members en dérivant des classes.Polymorphisme de modèle

La question est maintenant que l'un des membres est en fait basé sur un modèle avec des spécialisations étant soit BaseClass, DerivedClass ou Derived2Class

#include <iostream> 

using std::cin; 
using std::cout; 
using std::endl; 


template<class T> 
class Queue 
{ 
    public: 
     Queue(); 
     Queue(T*); 
} 

class Com 
{ 
    public: 
     virtual void setReady() 
     { 
      cout << "Com" << endl; 
     } 
}; 

class DerivedCom : public Com 
{ 
    public: 
     void setReady() 
     { 
      cout << "DCom" << endl; 
     } 
}; 

class Derived2Com : public Com 
{ 
    public: 
     void setReady() 
     { 
      cout << "D2Com" << endl; 
     } 
}; 

class BaseClass 
{ 
    protected: 
     Com* com; 
     Queue<BaseClass>* queue; 

    public: 
     BaseClass(Com* c = new Com, Queue<BaseClass>* q = new Queue<BaseClass>) : com(c), queue(q) 
     { 
     } 

     void setReady() 
     { 
      com->setReady(); 
     } 
}; 

class DerivedClass : public BaseClass 
{ 
    public: 
     DerivedClass() : BaseClass(new DerivedCom, new Queue<DerivedClass>) 
     { 
     } 
}; 

class Derived2Class : public BaseClass 
{ 
    public: 
     Derived2Class() : BaseClass(new Derived2Com, new Queue<Derived2Class>) 
     {} 
}; 

int main() 
{ 
    BaseClass* base = new Derived2Class(); 

    base->setReady(); 
    return 0; 
} 

je peux, sans problème, les classes simples « surcharge » comme Com, DerivedCom et Derived2Com mais la signature du constructeur de BaseClass ne correspondra pas au type que les classes dérivantes essaient de lui envoyer.

+0

S'il s'agit simplement d'une erreur qui manque '' 'avant' q' dans 'BaseClass (Com * c = nouveau Com, Queue q = new Queue )' alors corrigez-le. Mais cela ne résoudra pas vos problèmes ... – PiotrNycz

+0

Le point crucial est que Queue ne dérive pas de la file d'attente ' –

Répondre

1

Au lieu de Queue<BaseClass>* queue; vous devriez avoir Queue<BaseClass*> queue; ou, mieux encore, Queue<std::unique_ptr<BaseClass>> et l'initialiser uniquement dans le constructeur de base:

BaseClass(Com* c = new Com, Queue<BaseClass*> q = Queue<BaseClass*>()) : com(c), queue(q) 
{ 
} 

Cependant, avoir la BaseClass tenir une collection d'elle-même en tant que membre est une odeur de code. Je repenserais cette partie.

La raison pour laquelle cela ne fonctionne pas est que Queue<BaseClass> et Queue<DerivedClass> sont classes complètement différentes.

+0

' Queue' n'instancie jamais la classe qu'il gère, c'est juste un wrapper pour une file d'attente d'invocation de méthode : http://pastie.org/5401518. De cette façon, je peux reporter les appels de méthode, c'est-à-dire utiliser queue-> push (& BaseClass :: setReady); 'et les appeler plus tard en utilisant' queue-> pop() ' –

+0

@NilsWerner Je ne vois pas en quoi cela est pertinent. –

+0

Ouais, ce n'est pas. Je voulais juste montrer qu'il y a une raison pour laquelle je le fais. –

-1

Vous auriez dû Queue<BaseClass*>* queue = new Queue<BaseClass*>(); Ceci déclare un pointeur de file d'attente du pointeur de type BaseClass sur le tas et vous permet d'utiliser la notation de pointeur que vous avez mentionné ci-dessus queue->push(&BaseClass::setReady); et comme ...

+0

-1 car il n'y a pas besoin de 'queue 'à allouer avec new. –

+0

et bien que cela puisse être vrai ... Je disais juste qu'il avait besoin de se référer à un pointeur vers la file d'attente puisqu'il utilisait la notation par pointeur, donc je suis désolé, mais ça DOIT être un pointeur pour que ça marche, beaucoup moins compilé. J'apprécie le moins 1 pour vous mal compris ma réponse ... –