Je crée une classe Factory pour faciliter la création de certains
objets. J'ai une classe virtuelle V, et deux classes A et B dérivant de
V. J'aimerais créer dans ma classe Factory une méthode qui prendrait en
paramètre de template un nom de classe dérivant de V. Il ne faut pas que
l'on puisse appeler ce template avec autre chose qu'une classe dérivée
de V, car V est virtuelle.
Je veux pouvoir faire ceci :
class C{};
A a = F.Create<A>(); // pas de problème
B b = F.Create<B>(); // pas de problème
C c = F.Create<C>(); // erreur : seulement des dérivés de V
Ainsi, l'appel C* c = F.Create<C>(); nécessite une conversion de C* vers V*, qui n'existe pas (ce qui donnera une erreur de compilation), alors que A* a = F.Create<A>(); B* b = F.Create<B>(); marchent car la conversion "pointeur sur classe dérivée" vers "pointeur sur classe de base" existe.
Sinon, tu peux regarder sur Boost <http://www.boost.org/> et en particulier boost::enable_if et boost::is_base_and_derived - mais je me n'en suis jamais servi...
Falk
Nicolas Favre-Félix wrote:
Je veux pouvoir faire ceci :
class C{};
A a = F.Create<A>(); // pas de problème
B b = F.Create<B>(); // pas de problème
C c = F.Create<C>(); // erreur : seulement des dérivés de V
Donne à la méthode Create() un paramètre "pointeur sur V" avec
un argument par défaut du type "pointeur sur le type passé en
argument au template" :
Ainsi, l'appel
C* c = F.Create<C>();
nécessite une conversion de C* vers V*, qui n'existe pas (ce qui
donnera une erreur de compilation), alors que
A* a = F.Create<A>();
B* b = F.Create<B>();
marchent car la conversion "pointeur sur classe dérivée" vers
"pointeur sur classe de base" existe.
Sinon, tu peux regarder sur Boost <http://www.boost.org/>
et en particulier boost::enable_if et boost::is_base_and_derived
- mais je me n'en suis jamais servi...
Ainsi, l'appel C* c = F.Create<C>(); nécessite une conversion de C* vers V*, qui n'existe pas (ce qui donnera une erreur de compilation), alors que A* a = F.Create<A>(); B* b = F.Create<B>(); marchent car la conversion "pointeur sur classe dérivée" vers "pointeur sur classe de base" existe.
Sinon, tu peux regarder sur Boost <http://www.boost.org/> et en particulier boost::enable_if et boost::is_base_and_derived - mais je me n'en suis jamais servi...
"Nicolas Favre-Félix" a écrit dans le message de news: 41c5df0c$0$4671$
Bonjour
Je crée une classe Factory pour faciliter la création de certains objets. J'ai une classe virtuelle V, et deux classes A et B dérivant de V. J'aimerais créer dans ma classe Factory une méthode qui prendrait en paramètre de template un nom de classe dérivant de V. Il ne faut pas que l'on puisse appeler ce template avec autre chose qu'une classe dérivée de V, car V est virtuelle. Je veux pouvoir faire ceci :
class C{};
A a = F.Create<A>(); // pas de problème B b = F.Create<B>(); // pas de problème
C c = F.Create<C>(); // erreur : seulement des dérivés de V
Savez vous si c'est possible, et si oui comment ?
une possibilité : tu définies dans V une méthode publique vide (mais pas virtuelle pure) par exemple : class V { public: void PeutFaireUnV(){} };
dans ta classe Factory tu écris une méthode qui appelle cette fonction (méthode que tu n'appeleras jamais) template <class T> class Factory { private: void TesteValiditeT() { T.PeutFaireUnV();} };
si la classe que tu utilises comme paramètre de Create ne possède pas cette fonction, le compilateur refusera la création de l'objet. Par exemple : F.Create<int>(); // compilation impossible F.Create<A>(); // compilation possible
A++ Alex
Merci.
Nicolas
bonjour,
"Nicolas Favre-Félix" <n.favrefelix@eggsbaconandspam--free.fr> a écrit dans
le message de news: 41c5df0c$0$4671$626a14ce@news.free.fr...
Bonjour
Je crée une classe Factory pour faciliter la création de certains objets.
J'ai une classe virtuelle V, et deux classes A et B dérivant de V.
J'aimerais créer dans ma classe Factory une méthode qui prendrait en
paramètre de template un nom de classe dérivant de V. Il ne faut pas que
l'on puisse appeler ce template avec autre chose qu'une classe dérivée de
V, car V est virtuelle.
Je veux pouvoir faire ceci :
class C{};
A a = F.Create<A>(); // pas de problème
B b = F.Create<B>(); // pas de problème
C c = F.Create<C>(); // erreur : seulement des dérivés de V
Savez vous si c'est possible, et si oui comment ?
une possibilité : tu définies dans V une méthode publique vide (mais pas
virtuelle pure) par exemple :
class V
{
public:
void PeutFaireUnV(){}
};
dans ta classe Factory tu écris une méthode qui appelle cette fonction
(méthode que tu n'appeleras jamais)
template <class T> class Factory
{
private:
void TesteValiditeT() { T.PeutFaireUnV();}
};
si la classe que tu utilises comme paramètre de Create ne possède pas cette
fonction, le compilateur refusera la création de l'objet.
Par exemple :
F.Create<int>(); // compilation impossible
F.Create<A>(); // compilation possible
"Nicolas Favre-Félix" a écrit dans le message de news: 41c5df0c$0$4671$
Bonjour
Je crée une classe Factory pour faciliter la création de certains objets. J'ai une classe virtuelle V, et deux classes A et B dérivant de V. J'aimerais créer dans ma classe Factory une méthode qui prendrait en paramètre de template un nom de classe dérivant de V. Il ne faut pas que l'on puisse appeler ce template avec autre chose qu'une classe dérivée de V, car V est virtuelle. Je veux pouvoir faire ceci :
class C{};
A a = F.Create<A>(); // pas de problème B b = F.Create<B>(); // pas de problème
C c = F.Create<C>(); // erreur : seulement des dérivés de V
Savez vous si c'est possible, et si oui comment ?
une possibilité : tu définies dans V une méthode publique vide (mais pas virtuelle pure) par exemple : class V { public: void PeutFaireUnV(){} };
dans ta classe Factory tu écris une méthode qui appelle cette fonction (méthode que tu n'appeleras jamais) template <class T> class Factory { private: void TesteValiditeT() { T.PeutFaireUnV();} };
si la classe que tu utilises comme paramètre de Create ne possède pas cette fonction, le compilateur refusera la création de l'objet. Par exemple : F.Create<int>(); // compilation impossible F.Create<A>(); // compilation possible