OVH Cloud OVH Cloud

Template et renvoi d'objet dérivé

5 réponses
Avatar
Nicolas Favre-Félix
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 ?

Merci.

Nicolas

5 réponses

Avatar
Fabien LE LEZ
On Sun, 19 Dec 2004 21:05:36 +0100, Nicolas Favre-Félix
:

Savez vous si c'est possible


http://www.boost.org/libs/libraries.htm#Correctness
http://www.boost.org/libs/libraries.htm#Generic


--
;-)

Avatar
Falk Tannhäuser
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" :

class Factory
{
public:
template<typename T>
T* Create(V* = static_cast<T*>(0)) { /* ... */ }
};

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

Avatar
Nicolas Favre-Félix
Avatar
Alexandre
bonjour,

"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


Avatar
drkm
"Alexandre" writes:

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.


Si tu appelles TesteValiditeT().

--drkm