OVH Cloud OVH Cloud

Template

7 réponses
Avatar
PurL
Bonjour,

j'ai :

template <class type> void maClasse::maFonction(type *maVariable)
{
...
}

A l'intérieur de cette fonction le type "type" est utilisable.
Peut-on le sauvegarder au sein de la classe pour pouvoir l'utiliser dans une
autre fonction de cette meme classe ?

Merci,

PurL

7 réponses

Avatar
Christophe de VIENNE
PurL wrote:
Bonjour,

j'ai :

template <class type> void maClasse::maFonction(type *maVariable)
{
...
}

A l'intérieur de cette fonction le type "type" est utilisable.
Peut-on le sauvegarder au sein de la classe pour pouvoir l'utiliser dans une
autre fonction de cette meme classe ?


Qu'est-ce que tu entends par sauvegarder ? Et quelle utilisation veux-tu
en faire dans ton autre fonction ?


--
Christophe de Vienne

Avatar
PurL
Qu'est-ce que tu entends par sauvegarder ? Et quelle utilisation
veux-tu en faire dans ton autre fonction ?


Toujours mon histoire de callback.
Si je ne peux pas passer une fonction membre, je passe l'objet, mais il peut
avoir plusieur type différent :

class CallBack
{
template <class type> void fct(type *frm);
type *m_frm;
void AutreFonction();
};

template <class type> void CallBack::fct(type *frm)
{
//je sauvegarde frm dans une variable membre, mais cette
//variable doit etre du meme type que frm
m_frm = frm;
}

void CallBack::AutreFonction()
{
//ici je voudais faire :
m_frm->FonctionCallBack();
}

Bien evidement, chaque classe qui desire que la class CallBack les appelle
doivent avoir toute la fonction membre FonctionCallBack().

Merci pour votre aide,

PurL

Avatar
Andre Heinen
On Fri, 6 Aug 2004 13:53:46 +0200, "PurL"
wrote:

template <class type> void maClasse::maFonction(type *maVariable)
{
...
}

A l'intérieur de cette fonction le type "type" est utilisable.
Peut-on le sauvegarder au sein de la classe pour pouvoir l'utiliser dans une
autre fonction de cette meme classe ?


Oui, mais tu dois mettre le template sur la classe et non pas sur
la fonction:

template<typename T>
class MaClasse {
public:
void maFonction(T* maVariable);
};

int main() {
MaClasse<int> mc;
int i = 2;
mc.maFonction(&i);
}

template<typename T>
void MaClasse<T>::maFonction(T* maVariable) {
}

Etait-ce bien ce que tu demandais?

--
Andre Heinen
My address is "a dot heinen at europeanlink dot com"

Avatar
PurL
Oui, mais tu dois mettre le template sur la classe et non pas sur
la fonction:

template<typename T>
class MaClasse {
public:
void maFonction(T* maVariable);
};

int main() {
MaClasse<int> mc;
int i = 2;
mc.maFonction(&i);
}

template<typename T>
void MaClasse<T>::maFonction(T* maVariable) {
}

Etait-ce bien ce que tu demandais?


Ca a l'air d'etre ca.
L'ennui c'est que ma classe CallBack est une classe VCL et je ne peux
apparement pas faire de template avec :(

PurL

Avatar
Christophe de VIENNE
PurL wrote:
Qu'est-ce que tu entends par sauvegarder ? Et quelle utilisation
veux-tu en faire dans ton autre fonction ?



Toujours mon histoire de callback.
Si je ne peux pas passer une fonction membre, je passe l'objet, mais il peut
avoir plusieur type différent :
[...]

Bien evidement, chaque classe qui desire que la class CallBack les appelle
doivent avoir toute la fonction membre FonctionCallBack().



Alors la solution est d'utiliser des objets foncteurs. regarde du côté
de boost par exemple : http://www.boost.org/doc/html/function.html

Recherche un peu sur google aussi, tu trouveras de nombreux
cours/tutoriels dessus (en anglais c'est 'functor').


Sinon voir la solution d'André.

A+

Christophe


--
Christophe de Vienne


Avatar
Falk Tannhäuser
PurL wrote:
Toujours mon histoire de callback.
Si je ne peux pas passer une fonction membre, je passe l'objet, mais il peut
avoir plusieur type différent :

class CallBack
{
template <class type> void fct(type *frm);
type *m_frm;
void AutreFonction();
};

template <class type> void CallBack::fct(type *frm)
{
//je sauvegarde frm dans une variable membre, mais cette
//variable doit etre du meme type que frm
m_frm = frm;
}

void CallBack::AutreFonction()
{
//ici je voudais faire :
m_frm->FonctionCallBack();
}

Bien evidement, chaque classe qui desire que la class CallBack les appelle
doivent avoir toute la fonction membre FonctionCallBack().


Tu veux peut-être quelque chose du genre :
_____________________________________________________________________________
#include <cassert>

class CallBack
{
class ClientBase
{
public:
virtual void call_back() = 0;
virtual ~ClientBase() {}
};

template<typename T> class Client: public ClientBase
{
T the_client;
public:
Client(T const& cl) : the_client(cl) {}
void call_back() { the_client.FonctionCallBack(); }
};

ClientBase* m_frm;

public:
CallBack() : m_frm(0) {}
~CallBack() { delete m_frm; }
template<typename T> void Enregistrer(T const& cl)
{ delete m_frm; m_frm = new Client<T>(cl); }
void AutreFonction() { assert(m_frm != 0); m_frm->call_back(); }
}; // class CallBack

//////////////////// Tests: ////////////////////////////
#include <iostream>
#include <ostream>
#include <string>

struct foo
{
int i;
foo(int i) : i(i) {}
void FonctionCallBack() { std::cout << "foo: " << i << 'n'; }
};

struct bar
{
double d;
bar(double d) : d(d) {}
void FonctionCallBack() { std::cout << "bar: " << d << 'n'; }
};

struct toto
{
std::string s;
toto(std::string const& s) : s(s) {}
void FonctionCallBack() { std::cout << "toto: " << s << 'n'; }
};

int main()
{
CallBack cb;

cb.Enregistrer(foo(42));
cb.AutreFonction();

cb.Enregistrer(bar(6.55957));
cb.AutreFonction();

cb.Enregistrer(toto("Hello PurL!"));
cb.AutreFonction();

return 0;
}
_____________________________________________________________________________

Il est à noter que les classes de test 'foo', 'bar' et toto n'ont pas besoin
d'avoir des relations d'héritage (ancêtre commun ...) entre elles, tout ce
qu'il leur faut est la fonction membre 'void FonctionCallBack()'.
Il faut voir s'il faut faire des copies des objets passés à
'ClientBase::Enregistrer' comme je l'ai fait (cela évite des ennuis dûs à
la durée de vie des objets) ou s'il suffit de stocker des pointeurs
comme toi tu comptais faire dans le bout de code posté (prudence alors !)

Falk

Avatar
Falk Tannhäuser
Falk Tannhäuser wrote:
Il est à noter que les classes de test 'foo', 'bar' et toto n'ont pas
besoin d'avoir des relations d'héritage (ancêtre commun ...) entre elles,
tout ce qu'il leur faut est la fonction membre 'void FonctionCallBack()'.


Même cette restriction peut être levée moyennant une petite modif
de la classe 'Client' imbriquée dans 'CallBack' :

template<typename T> class Client: public ClientBase
{
T the_client;
void (T::* mem_fun)();
public:
Client(T const& cl, void (T::* mf)()) : the_client(cl), mem_fun(mf) {}
void call_back() { (the_client.*mem_fun)(); }
};

puis on passe le pointeur sur la fonction membre souhaitée dans
'CallBack::Enregistrer' qui est complétée comme suit :

template<typename T> void Enregistrer(T const& cl, void (T::* mf)())
{ delete m_frm; m_frm = new Client<T>(cl, mf); }

Cela permet d'avoir n'importe quel nom pour les fonctions membre
à appeler :

struct foo
{
...
void tralala() { ... }
};

struct bar
{
...
void blablabla() { ... }
void gnagnagna() { ... }
};


int main()
{
CallBack cb;

cb.Enregistrer(foo(42), &foo::tralala);
cb.AutreFonction();

cb.Enregistrer(bar(6.55957), &bar::blablabla);
cb.AutreFonction();

cb.Enregistrer(bar(1.95583), &bar::gnagnagna);
cb.AutreFonction();

return 0;
}

Falk