 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Guillaume Gourdin Guest
|
Posted: Sun Sep 28, 2003 6:28 pm Post subject: Héritage et template |
|
|
Bonjour à tous. Voilà, j'ai une classe template que je voudrais instancier
selon le type du template :
template <class T> class Pipo {};
// plus loin...
Pipo * pipo;
switch (Type)
{
case 0 : pipo = new Pipo<float>(); break;
case 1 : pipo = new Pipo<int>(); break;
case 2 : pipo = new Pipo<short>(); break;
}
Mais ce code ne compile pas sous VC6, car, grosso modo, le compilateur me
dit qu'il ne peut pas convertir de Pipo<float>* vers Pipo, idem pour les int
et les shorts.
Avez-vous des suggestions pour pallier ce genre de problème et avoir un
pointeur de template génétique quelques soit le type du template ? J'avais
pensé à créer une classe PipoFloat héritant de Pipo<float>, mais ça ne
semble pas résoudre le problème.
Merci.
|
|
| Back to top |
|
 |
Michaël Monerau Guest
|
Posted: Sun Sep 28, 2003 6:47 pm Post subject: Re: Héritage et template |
|
|
Guillaume Gourdin wrote:
| Quote: | Avez-vous des suggestions pour pallier ce genre de problème et avoir
un pointeur de template génétique quelques soit le type du template ?
J'avais pensé à créer une classe PipoFloat héritant de Pipo<float>,
mais ça ne semble pas résoudre le problème.
|
Tu peux faire un :
class PipoBase
{
// tu mets ici les opérations que tu voudras
// pouvoir faire avec ton PipoBase*
// en virtuelle pure ou non, selon tes besoins
};
Et ensuite :
templace <class T> class Pipo : public PipoBase
{
// tu mets l'implémentation des fonctions
// qui en ont besoin...
}
Et maintenant, tu peux faire ton code :
##
PipoBase * pipo;
switch (Type)
{
case 0 : pipo = new Pipo<float>(); break;
case 1 : pipo = new Pipo<int>(); break;
case 2 : pipo = new Pipo<short>(); break;
}
pipo->UneFonctionDePipoBase ();
##
Le problème avec cette méthode, c'est que tu ne pas retourner un objet du
type du template par exemple (les fonctions de PipoBase ne peuvent pas
savoir qu'on va dériver en template...).
D'ailleurs, si quelqu'un a une solution pour palier à ce dernier problème,
je suis preneur :-)
Je ne sais pas si ça s'accomode à ce que tu veux faire...
--
<=- Michaël "Cortex" Monerau -=>
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Sun Sep 28, 2003 6:51 pm Post subject: Re: Héritage et template |
|
|
On Sun, 28 Sep 2003 20:28:01 +0200, "Guillaume Gourdin"
<nospam (AT) nospam (DOT) fr> wrote:
| Quote: | template <class T> class Pipo {};
// plus loin...
Pipo * pipo;
|
Déjà, ceci ne devrait pas être accepté par le compilo.
A priori, la méthode pour résoudre ton problème est :
class Pipo_base
{
// Ici, les fonctions communes
};
template <class T> class Pipo : public Pipo_base
{
...
};
Pipo_base* pipo;
switch (...)
{
case 0 : pipo = new Pipo<float>; break;
case 1 : pipo = new Pipo<int>; break;
|
|
| Back to top |
|
 |
Guillaume Gourdin Guest
|
Posted: Sun Sep 28, 2003 7:49 pm Post subject: Re: Héritage et template |
|
|
| Quote: | class Pipo_base
{
// Ici, les fonctions communes
};
|
Ca ne convient pas, car la classe Pipo traite des données qui elles aussi
sont typées par le template. Par ex.
template <class T> class Pipo
{
public:
void Set(const T & Data) {_Data = Data}
private:
T _Data;
};
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Mon Sep 29, 2003 1:58 am Post subject: Re: Héritage et template |
|
|
On Sun, 28 Sep 2003 21:49:47 +0200, "Guillaume Gourdin"
<nospam (AT) nospam (DOT) fr> wrote:
| Quote: | void Set(const T & Data) {_Data = Data}
|
Et comment voudrais-tu faire appel à une telle fonction en passant par
un "Pipo*" ?
|
|
| Back to top |
|
 |
Christophe Lephay Guest
|
Posted: Mon Sep 29, 2003 4:16 am Post subject: Re: Héritage et template |
|
|
"Fabien LE LEZ" <gramster (AT) gramster (DOT) com> a écrit dans le message de
news:qc4fnv4uenvik2barfc6vk2rpgf4p564sp (AT) 4ax (DOT) com...
| Quote: | On Sun, 28 Sep 2003 21:49:47 +0200, "Guillaume Gourdin"
void Set(const T & Data) {_Data = Data}
Et comment voudrais-tu faire appel à une telle fonction en passant par
un "Pipo*" ?
|
Personnellement, je parlerais pas trop de Pipo à Gourdin, des fois que ça
l'excite ;)
Chris
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Mon Sep 29, 2003 7:24 am Post subject: Re: Héritage et template |
|
|
"Michaël Monerau" <cort (AT) meloo (DOT) com> wrote
| Quote: | Guillaume Gourdin wrote:
Avez-vous des suggestions pour pallier ce genre de problème et avoir
un pointeur de template génétique quelques soit le type du template
? J'avais pensé à créer une classe PipoFloat héritant de
Pipo<float>, mais ça ne semble pas résoudre le problème.
Tu peux faire un :
class PipoBase
{
// tu mets ici les opérations que tu voudras
// pouvoir faire avec ton PipoBase*
// en virtuelle pure ou non, selon tes besoins
};
Et ensuite :
templace <class T> class Pipo : public PipoBase
{
// tu mets l'implémentation des fonctions
// qui en ont besoin...
}
Et maintenant, tu peux faire ton code :
##
PipoBase * pipo;
switch (Type)
{
case 0 : pipo = new Pipo<float>(); break;
case 1 : pipo = new Pipo<int>(); break;
case 2 : pipo = new Pipo<short>(); break;
}
pipo->UneFonctionDePipoBase ();
##
Le problème avec cette méthode, c'est que tu ne pas retourner un objet
du type du template par exemple (les fonctions de PipoBase ne peuvent
pas savoir qu'on va dériver en template...).
D'ailleurs, si quelqu'un a une solution pour palier à ce dernier
problème, je suis preneur
|
Je crois que boost::any pourrait faire l'affaire. Mais je me poserais
des questions : pourquoi ? Qu'est-ce qu'on va réelement faire avec pipo ?
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
|
|
| Back to top |
|
 |
Michaël Monerau Guest
|
Posted: Mon Sep 29, 2003 2:31 pm Post subject: Re: Héritage et template |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | Le problème avec cette méthode, c'est que tu ne pas retourner un
objet du type du template par exemple (les fonctions de PipoBase ne
peuvent pas savoir qu'on va dériver en template...).
D'ailleurs, si quelqu'un a une solution pour palier à ce dernier
problème, je suis preneur :-)
Je crois que boost::any pourrait faire l'affaire. Mais je me poserais
des questions : pourquoi ? Qu'est-ce qu'on va réelement faire avec
pipo ?
|
J'avais eu le pb avec un système que je voulais implémenter : je voulais
faire une variable d'un type que l'on veut (int, float, types persos...), et
duquel on pourrait avoir la valeur. Comme un type intégral en fait, mais
encapsulé pour pouvoir traiter un vector de tels objets et les manipuler
chacun pareil. Voilà un code qui résume un peu (en raccourci) :
class UVarBase
{
public:
virtual xxx GetValue () const = 0;
};
template <class T>
class UVar
{
public:
typedef const_ref_type const T&;
virtual xxx GetValue () const = 0;
// je voudrais :
virtual const T& GetValue () const = 0;
};
Bon, je n'ai pas mis les opérateurs et les setteurs... Mais l'idée y est.
Dans la classe de base, on ne peut pas connaître le type template final. Du
coup, la fonction GetValue ne peut pas renvoyer le bon type directement.
Alors moi j'avais fait renvoyer un void*, que je recastais ensuite en
faisant confiance au programmeur qui appelait la fonction :
template <class T>
typename UVar<T>::const_ref_type UVarValue (const UVar<T>* pUVar)
{
return *(reinterpret_cast<UVar(pUVar->GetValue()));
}
Et donc, on pouvait avoir, avec une UVar, sa valeur. Maintenant, si on
voulait la valeur d'une UVarBase, j'avais fait :
|
|
| Back to top |
|
 |
Michaël Monerau Guest
|
Posted: Mon Sep 29, 2003 2:35 pm Post subject: Re: Héritage et template |
|
|
Michaël Monerau wrote:
| Quote: | kanze (AT) gabi-soft (DOT) fr wrote:
template <class T
typename UVar
{
return
*(reinterpret_cast<UVar(pUVar->GetValue())); }
Et donc, on pouvait avoir, avec une UVar, sa valeur. Maintenant, si on
voulait la valeur d'une UVarBase, j'avais fait :
|
Zut... le message est parti trop vite. Je reprends :
Pour avoir la valeur d'une UVarBase, je faisais :
template <class T>
typename UVar<T>::const_ref_type UVarValue (const UVarBase* pUVarBase)
{
return UVarValue<T> (&pUVarBase->ToUVar<T> ());
}
et j'appelais :
UVarBase* pUVarBase = new UVar<float>;
// ...
UVarValue<float> (pUVarBase);
delete pUVarBase;
(en vérité, c'était pour un autre usage : une suite d'options dans un de mes
programmes... Mais bon).
Peut-être existe-t-il un meilleur idiôme pour faire ce que je voulais...
Mais ça me permettait d'avoir un vector<UVarBase*> et de pouvoir gérer
toutes les options facilement (à partir de leur nom). Mais ça impose de
faire très attention au paramètre template donne à UVarValue (UVarBase*).
--
<=- Michaël "Cortex" Monerau -=>
|
|
| Back to top |
|
 |
Christophe Lephay Guest
|
Posted: Mon Sep 29, 2003 2:42 pm Post subject: Re: Héritage et template |
|
|
"Michaël Monerau" <cort (AT) meloo (DOT) com> a écrit dans le message de
news:unXdb.181378$hd6.2304997 (AT) news (DOT) chello.at...
| Quote: | J'avais eu le pb avec un système que je voulais implémenter : je voulais
faire une variable d'un type que l'on veut (int, float, types persos...),
et
duquel on pourrait avoir la valeur. Comme un type intégral en fait, mais
encapsulé pour pouvoir traiter un vector de tels objets et les manipuler
chacun pareil. Voilà un code qui résume un peu (en raccourci) :
class UVarBase
{
public:
virtual xxx GetValue () const = 0;
};
template
class UVar
{
public:
typedef const_ref_type const T&;
virtual xxx GetValue () const = 0;
// je voudrais :
virtual const T& GetValue () const = 0;
};
|
J'ai un jour été confronté à ce problème, et je l'ai résolu en passant par
un stream pour extraire la valeur...
Chris
|
|
| Back to top |
|
 |
Michaël Monerau Guest
|
Posted: Mon Sep 29, 2003 2:52 pm Post subject: Re: Héritage et template |
|
|
Christophe Lephay wrote:
| Quote: | template <class T
class UVar
{
public:
typedef const_ref_type const T&;
virtual xxx GetValue () const = 0;
// je voudrais :
virtual const T& GetValue () const = 0;
};
J'ai un jour été confronté à ce problème, et je l'ai résolu en
passant par un stream pour extraire la valeur...
|
C'est-à-dire ? Je ne vois pas ce que tu veux dire... Mon but est aussi de
passer par un stream ensuite pour l'afficher. Le type 'T' doit alors aussi
surcharger l'opérateur '<<' pour lui...
Mais si tu fais passer directement par un stream, comment récupérer
l'information si tu ne sais pas de quel type elle est ?
--
<=- Michaël "Cortex" Monerau -=>
|
|
| Back to top |
|
 |
Christophe Lephay Guest
|
Posted: Mon Sep 29, 2003 3:05 pm Post subject: Re: Héritage et template |
|
|
Michaël Monerau" <cort (AT) meloo (DOT) com> a écrit dans le message de
news:pGXdb.181652$hd6.2309645 (AT) news (DOT) chello.at...
| Quote: | Christophe Lephay wrote:
template <class T
class UVar
{
public:
typedef const_ref_type const T&;
virtual xxx GetValue () const = 0;
// je voudrais :
virtual const T& GetValue () const = 0;
};
J'ai un jour été confronté à ce problème, et je l'ai résolu en
passant par un stream pour extraire la valeur...
C'est-à-dire ? Je ne vois pas ce que tu veux dire... Mon but est aussi de
passer par un stream ensuite pour l'afficher. Le type 'T' doit alors aussi
surcharger l'opérateur '<<' pour lui...
Mais si tu fais passer directement par un stream, comment récupérer
l'information si tu ne sais pas de quel type elle est ?
|
La méthode classique...
class base
{
protected:
virtual void print( ostream& ostr ) = 0;
};
ostream& operator<<( ostream& ostr, base& b )
{
base.print( ostr );
return ostr;
}
template< class T >
class derived : public base
{
public:
derived( const T& param ) : value( param ) {}
protected:
void print( ostream& ostr )
{
ostr << value;
}
private:
T value;
};
Chris
PS : désolé si le message apparait dans un nouveau thread, mais mon OE fait
encore des siennes...
|
|
| Back to top |
|
 |
Christophe Lephay Guest
|
Posted: Mon Sep 29, 2003 6:21 pm Post subject: Re: Héritage et template |
|
|
"Christophe Lephay" <christophe-lephay (AT) wanadoo (DOT) fr> a écrit dans le message
de news:bl9rjp$8k7$1 (AT) news-reader2 (DOT) wanadoo.fr...
| Quote: | ostream& operator<<( ostream& ostr, base& b )
{
base.print( ostr );
return ostr;
}
|
Oups, vous avez mal lu ;)
Il fallait lire :
b.print( ostr );
Chris
|
|
| Back to top |
|
 |
Michaël Monerau Guest
|
Posted: Mon Sep 29, 2003 7:20 pm Post subject: Re: Héritage et template |
|
|
Christophe Lephay wrote:
| Quote: | La méthode classique...
class base
{
protected:
virtual void print( ostream& ostr ) = 0;
};
ostream& operator<<( ostream& ostr, base& b )
{
base.print( ostr );
return ostr;
}
template< class T
class derived : public base
{
public:
derived( const T& param ) : value( param ) {}
protected:
void print( ostream& ostr )
{
ostr << value;
}
private:
T value;
};
|
Ok, mais là c'est seulement pour le mettre dans un string. Admettons que
maintenant, je veuille récupérer la valeur contenue dans derived, avec un
pointeur vers base... Est-ce possible en C++ ?
--
<=- Michaël "Cortex" Monerau -=>
|
|
| Back to top |
|
 |
Christophe Lephay Guest
|
Posted: Mon Sep 29, 2003 11:02 pm Post subject: Re: Héritage et template |
|
|
"Michaël Monerau" <cort (AT) meloo (DOT) com> a écrit dans le message de
news:AB%db.186235$hd6.2404988 (AT) news (DOT) chello.at...
| Quote: | Christophe Lephay wrote:
La méthode classique...
class base
{
protected:
virtual void print( ostream& ostr ) = 0;
};
ostream& operator<<( ostream& ostr, base& b )
{
base.print( ostr );
return ostr;
}
template< class T
class derived : public base
{
public:
derived( const T& param ) : value( param ) {}
protected:
void print( ostream& ostr )
{
ostr << value;
}
private:
T value;
};
Ok, mais là c'est seulement pour le mettre dans un string.
|
Dans un stream, pas un string...
| Quote: | Admettons que
maintenant, je veuille récupérer la valeur contenue dans derived, avec un
pointeur vers base... Est-ce possible en C++ ?
|
L'opération est totalement symétrique. Il suffit de définir de la même
manière istream& operator>>( istream&, base& ) et une fonction membre
virtual void get( istream& )...
Chris
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|