Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

problème de conception

9 réponses
Avatar
Frédéric Gourul
Bonjour,

Désolé pour le titre un peu vague, mais comme je ne sais pas à quoi est du
mon problème, je n'ai pas pu le nommer...
J'ai un petit problème de conception et je ne comprend pas vraiment ce qui
se passe, j'explique: Je voudrai avoir une classe capable de réferencer tous
les types des instances d'une classe template. J'ai fait un petit prototype
qui se contente juste de les compter...

class CountType
{
public:
static size_t count;
CountType() {count++;}
};
size_t CountType::count = 0;

template <class T>
class DerivedType : public CountType
{
private:
DerivedType() {}

public:
static DerivedType<T> instance;
void foo() {}
};

template <class T>
DerivedType<T> DerivedType<T>::instance;


Le code ci-dessus fonctionne bien comme je l'attend.
Si je fais les déclarations suivantes:

DerivedType<int> tint = DerivedType<int>::instance;
DerivedType<float> tfloat1 = DerivedType<float>::instance;
DerivedType<float> tfloat2 = DerivedType<float>::instance;
DerivedType<string> tstring = DerivedType<string>::instance;
cout << "type count: " << CountType::count << endl;

J'obtiens bien 3 types différents crées à partir de DerivedType<T>

Ca se complique lorsque je veux rajouter une méthode virtuelle dans
CountType. Là j'obtiens la valeur 0 et je ne comprend pas ce qui se passe
dans ce cas là... J'ai essayé de contourner le problème en mettant la
méthode virtuelle dans une autre classe et de faire de l'héritage multiple
dans DerivedType<T> mais le résultat est identique. Si j'enlève l'héritage
avec la classe contenant la méthode virtuelle, ca fonctionne.

class CountType
{
public:
static size_t count;
CountType() {count++;}
};
size_t CountType::count = 0;


class BaseType
{
public:
virtual void foo() = 0;
};

template <class T>
class DerivedType : public CountType, public BaseType // si j'enleve
BaseType, c'est ok
{
private:
DerivedType() {}

public:
static DerivedType<T> instance;
void foo() {}
};

template <class T>
DerivedType<T> DerivedType<T>::instance;


Si quelqu'un pouvait m'expliquer ce qui se passe exactement et
éventuellement le moyen de réaliser ce que je veux faire, je l'en remercie
d'avance :)

Fred.

9 réponses

Avatar
Fabrizio Duhem
"Frédéric Gourul" a écrit dans le message de
news: c0d7m5$690$
Bonjour,

Désolé pour le titre un peu vague, mais comme je ne sais pas à quoi est du
mon problème, je n'ai pas pu le nommer...
J'ai un petit problème de conception et je ne comprend pas vraiment ce qui
se passe, j'explique: Je voudrai avoir une classe capable de réferencer
tous

les types des instances d'une classe template. J'ai fait un petit
prototype

qui se contente juste de les compter...

class CountType
{
public:
static size_t count;
CountType() {count++;}
};
size_t CountType::count = 0;

template <class T>
class DerivedType : public CountType
{
private:
DerivedType() {}

public:
static DerivedType<T> instance;
void foo() {}
};

template <class T>
DerivedType<T> DerivedType<T>::instance;


Le code ci-dessus fonctionne bien comme je l'attend.
Si je fais les déclarations suivantes:

DerivedType<int> tint = DerivedType<int>::instance;
DerivedType<float> tfloat1 = DerivedType<float>::instance;
DerivedType<float> tfloat2 = DerivedType<float>::instance;
DerivedType<string> tstring = DerivedType<string>::instance;
cout << "type count: " << CountType::count << endl;

J'obtiens bien 3 types différents crées à partir de DerivedType<T>

Ca se complique lorsque je veux rajouter une méthode virtuelle dans
CountType. Là j'obtiens la valeur 0 et je ne comprend pas ce qui se passe
dans ce cas là... J'ai essayé de contourner le problème en mettant la
méthode virtuelle dans une autre classe et de faire de l'héritage multiple
dans DerivedType<T> mais le résultat est identique. Si j'enlève l'héritage
avec la classe contenant la méthode virtuelle, ca fonctionne.

class CountType
{
public:
static size_t count;
CountType() {count++;}
};
size_t CountType::count = 0;


class BaseType
{
public:
virtual void foo() = 0;
};

template <class T>
class DerivedType : public CountType, public BaseType // si j'enleve
BaseType, c'est ok
{
private:
DerivedType() {}

public:
static DerivedType<T> instance;
void foo() {}
};

template <class T>
DerivedType<T> DerivedType<T>::instance;


Si quelqu'un pouvait m'expliquer ce qui se passe exactement et
éventuellement le moyen de réaliser ce que je veux faire, je l'en remercie
d'avance :)

Fred.






bonjour,

polymorphisme statique a l'aide de template.

template <typename T>
class BaseType
{
public:
void foo() {}
};

template <class T>
class DerivedType : public CountType, public BaseType<T>
{
private:
DerivedType() {}

public:
static DerivedType<T> instance;
void foo() {}
};


fabrizio.

Avatar
Frédéric Gourul
"Fabrizio Duhem" a écrit dans le message news:
402a267d$0$28634$

bonjour,

polymorphisme statique a l'aide de template.

Le problème c'est que j'en ai besoin de ce polymorphisme justement... Je ne

veux pas que BaseType soit template car dans CountType je vais conserver les
références sur les instances unique de chaque DerivedType<T>, j'aimerais
donc avoir un vector<BaseType*>...

J'ai comme l'impression que ce que je demande est impossible...
Une petite explication technique ? (pour ma culture)

Une piste sur un moyen de faire ce que je veux d'une autre facon ?

merci.

Avatar
Frédéric Gourul
"Fabrizio Duhem" a écrit dans le message news:
402a267d$0$28634$

polymorphisme statique a l'aide de template.



J'ai à moitié résolu mon problème en utilisant une allocation dynamique pour
les instances de mes types dérivés, ce qui donne ceci:

class BaseType;

class CountType
{
public:
static size_t count;
static vector<BaseType*> table;
};
size_t CountType::count = 0;
vector<BaseType*> CountType::table;

class BaseType
{
public:
static size_t count;
BaseType() {CountType::count++; CountType::table.push_back(this);}
virtual void foo() = 0;
};

template <class T>
class DerivedType : public BaseType
{
private:
DerivedType() {}
static DerivedType<T>* pinst;

public:
static DerivedType<T>* instance() {return pinst;}
void foo() {}
};

template <class T>
DerivedType<T>* DerivedType<T>::pinst = new DerivedType<T>();


DerivedType<int>* tint = DerivedType<int>::instance();
DerivedType<float>* tfloat1 = DerivedType<float>::instance();
DerivedType<float>* tfloat2 = DerivedType<float>::instance();
DerivedType<string>* tstring = DerivedType<string>::instance();
cout << "type count: " << CountType::count << endl;
cout << "table count: " << CountType::table.size() << endl;

J'ai bien la valeur 3 pour "type count", mais j'ai 0 pour la taille du
vecteur !!!!
Ce comportement bizarre m'a fait douter et j'ai testé le même code sur un
autre compilo (gcc) et là j'ai bien la valeur 3 pour les deux. D'ailleurs,
avec gcc, mon premier exemple était déja correct... Mais avec HP-UX aCC,
j'ai bien le problème... Je testerai ce soir sur VC pour voir ce que ca
donne.

Qui a raison ? A votre avis est-ce un bug de aCC ? Y'a-t-il quelque chose
que je fais mal ?

Avatar
Jean-Marc Bourguet
"Frédéric Gourul" writes:

Bonjour,

Désolé pour le titre un peu vague, mais comme je ne sais pas à quoi est du
mon problème, je n'ai pas pu le nommer...
J'ai un petit problème de conception et je ne comprend pas vraiment ce qui
se passe, j'explique: Je voudrai avoir une classe capable de réferencer tous
les types des instances d'une classe template. J'ai fait un petit prototype
qui se contente juste de les compter...

class CountType
{
public:
static size_t count;
CountType() {count++;}
};
size_t CountType::count = 0;

template <class T>
class DerivedType : public CountType
{
private:
DerivedType() {}

public:
static DerivedType<T> instance;
void foo() {}
};

template <class T>
DerivedType<T> DerivedType<T>::instance;


Le code ci-dessus fonctionne bien comme je l'attend.
Si je fais les déclarations suivantes:

DerivedType<int> tint = DerivedType<int>::instance;
DerivedType<float> tfloat1 = DerivedType<float>::instance;
DerivedType<float> tfloat2 = DerivedType<float>::instance;
DerivedType<string> tstring = DerivedType<string>::instance;
cout << "type count: " << CountType::count << endl;

J'obtiens bien 3 types différents crées à partir de DerivedType<T>


Euh, 3 instances, 2 types.
Ca se complique lorsque je veux rajouter une méthode virtuelle dans
CountType. Là j'obtiens la valeur 0 et je ne comprend pas ce qui se passe
dans ce cas là... J'ai essayé de contourner le problème en mettant la
méthode virtuelle dans une autre classe et de faire de l'héritage multiple
dans DerivedType<T> mais le résultat est identique. Si j'enlève l'héritage
avec la classe contenant la méthode virtuelle, ca fonctionne.


#include <iostream>

class CountType
{
public:
static size_t count;
CountType() {count++;}
};
size_t CountType::count = 0;
class BaseType
{
public:
virtual void foo() = 0;
};

template <class T>
class DerivedType : public CountType, public BaseType
{
public:
DerivedType() {}
void foo() {}
};

int main() {
DerivedType<int> i1;
DerivedType<int> i2;
DerivedType<float> i3;

std::cout << CountType::count << std::endl;
}

Affiche 3 avec les 2 compilateurs que j'ai essaye.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Frédéric Gourul
"Jean-Marc Bourguet" a écrit dans le message news:

"Frédéric Gourul" writes:

int main() {
DerivedType<int> i1;
DerivedType<int> i2;
DerivedType<float> i3;

std::cout << CountType::count << std::endl;
}

Affiche 3 avec les 2 compilateurs que j'ai essaye.



Non, le but du jeu est, dans ce cas, d'obtenir la valeur 2:
i1 et i2 ont le même type, donc il doivent partager la même instance de
DerivedType<int>.

Il y a donc ici deux types différents: DerivedType<int> et
DerivedType<float> et, dans ma version précédente, seulement deux instances
puisqu'on ne peut avoir qu'une seule instance d'un DerivedType<T>.

Mais comme je l'ai dit, la version que j'avais donnée fonctionne bien sous
gcc (mais pas sur HP-UX aCC) :(
A+

Avatar
Jean-Marc Bourguet
"Frédéric Gourul" writes:

"Jean-Marc Bourguet" a écrit dans le message news:

"Frédéric Gourul" writes:

int main() {
DerivedType<int> i1;
DerivedType<int> i2;
DerivedType<float> i3;

std::cout << CountType::count << std::endl;
}

Affiche 3 avec les 2 compilateurs que j'ai essaye.



Non, le but du jeu est, dans ce cas, d'obtenir la valeur 2:


Je suis distrait, je ne devrais pas essayer de repondre sur usenet en
meme temps que je travaille.

N'y aurait-il pas un probleme d'initialisation de variables non
locales? Je ne vois pas de raison pour count (qui doit etre
initialise statiquement), mais pour vector<> dans un autre post, il
faudrait s'assurer qu'il est initialise avant les
DerivedType<>::instance et ca j'ai aucune idee si c'est defini ou pas.
Je crois qu'on a deja discutte de ca ici mais ne me souviens pas du
resultat (recherche avec les suspects habituels pour ce genre de
choses: Gaby, James)

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Frédéric Gourul
"Jean-Marc Bourguet" a écrit dans le message news:

"Frédéric Gourul" writes:


N'y aurait-il pas un probleme d'initialisation de variables non
locales? Je ne vois pas de raison pour count (qui doit etre
initialise statiquement), mais pour vector<> dans un autre post, il
faudrait s'assurer qu'il est initialise avant les
DerivedType<>::instance et ca j'ai aucune idee si c'est defini ou pas.


Mouais depuis le début je sentais bien que c'était un problème d'ordre
d'initialisation, j'ai souvent vu des avertissements sur ce ng, mais comme
je ne connais pas du tout les règles d'initialisation, je ne savais pas ce
que je faisais de mal... J'avoue ne toujours pas comprendre (j'ai lu une
discussion sur le sujet dans les archives, mais je ne suis pas assez
expérimenté sur le sujet pour bien tout comprendre).

Je crois qu'on a deja discutte de ca ici mais ne me souviens pas du
resultat (recherche avec les suspects habituels pour ce genre de
choses: Gaby, James)


J'espérai bien que les suspects en question se manifesteraient ;)

Merci.
A+

Avatar
Fabrizio Duhem
"Frédéric Gourul" a écrit dans le message de
news: c0dj0p$52q$

"Fabrizio Duhem" a écrit dans le message news:
402a267d$0$28634$

polymorphisme statique a l'aide de template.



J'ai à moitié résolu mon problème en utilisant une allocation dynamique
pour

les instances de mes types dérivés, ce qui donne ceci:

class BaseType;

class CountType
{
public:
static size_t count;
static vector<BaseType*> table;
};
size_t CountType::count = 0;
vector<BaseType*> CountType::table;

class BaseType
{
public:
static size_t count;
BaseType() {CountType::count++; CountType::table.push_back(this);}
virtual void foo() = 0;
};

template <class T>
class DerivedType : public BaseType
{
private:
DerivedType() {}
static DerivedType<T>* pinst;

public:
static DerivedType<T>* instance() {return pinst;}
void foo() {}
};

template <class T>
DerivedType<T>* DerivedType<T>::pinst = new DerivedType<T>();


DerivedType<int>* tint = DerivedType<int>::instance();
DerivedType<float>* tfloat1 = DerivedType<float>::instance();
DerivedType<float>* tfloat2 = DerivedType<float>::instance();
DerivedType<string>* tstring = DerivedType<string>::instance();
cout << "type count: " << CountType::count << endl;
cout << "table count: " << CountType::table.size() << endl;

J'ai bien la valeur 3 pour "type count", mais j'ai 0 pour la taille du
vecteur !!!!
Ce comportement bizarre m'a fait douter et j'ai testé le même code sur un
autre compilo (gcc) et là j'ai bien la valeur 3 pour les deux. D'ailleurs,
avec gcc, mon premier exemple était déja correct... Mais avec HP-UX aCC,
j'ai bien le problème... Je testerai ce soir sur VC pour voir ce que ca
donne.

Qui a raison ? A votre avis est-ce un bug de aCC ? Y'a-t-il quelque chose
que je fais mal ?




re salut :-)

testé avec mingw (gcc win32), et vc7
output

type count: 3
vector size: 5
1
2
1
foo
test2





#include <iostream>
#include <vector>
#include <string>

struct base;

struct counter
{
counter(){ count++; }
static size_t count;
};

size_t counter::count = 0;


struct type_container
{
public:
typedef std::vector< base* >::iterator iterator;

void push(base* p) { __table.push_back(p); }
size_t size() { return __table.size(); }

static type_container& instance()
{
static type_container __instance;
return __instance;
}

iterator begin()
{
return __table.begin();
}

iterator end()
{
return __table.end();
}

private:
type_container() {}

std::vector< base* > __table;
};



struct base
{
base()
{
type_container::instance().push(this);
}

virtual void foo() = 0;
};


template <typename T>
struct derived : base
{
typedef T type;
T value;

derived()
{
static counter _increment;
}

void foo()
{
std::cout << value << std::endl;
}
};

int main()
{
derived<float> _f1;
_f1.value = 1.0f;

derived<float> _f2;
_f2.value = 2.0f;

derived<int> _i1;
_i1.value = 1;

derived<std::string> _s1;
_s1.value = "foo";

derived<std::string> _s2;
_s2.value = "test2";

std::cout << "type count: " << counter::count << std::endl;
std::cout << "vector size: " << type_container::instance().size() <<
std::endl;

typedef type_container::iterator iterator;
iterator end = type_container::instance().end();

for(iterator i = type_container::instance().begin(); i != end; i++)
{
(*i)->foo();
}

}







---

Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.581 / Virus Database: 368 - Release Date: 09/02/2004


Avatar
Frédéric Gourul
"Frédéric Gourul" a écrit dans le message de
news:c0dj0p$52q$

Ce comportement bizarre m'a fait douter et j'ai testé le même code sur un
autre compilo (gcc) et là j'ai bien la valeur 3 pour les deux. D'ailleurs,
avec gcc, mon premier exemple était déja correct... Mais avec HP-UX aCC,
j'ai bien le problème... Je testerai ce soir sur VC pour voir ce que ca
donne.


Testé avec VC7 ca donne le résultat attendu, comme avec gcc...
Dois-je conclure à un bug de aCC HP-UX ?