C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Classe imbriquée et héritage

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Vincent Richard
Guest





PostPosted: Mon Jul 28, 2003 12:06 pm    Post subject: Classe imbriquée et héritage Reply with quote



Bonjour,

Je suis confronté à un petit problème de syntaxe avec mon code :

template <class T>
class O
{
// ...
};

class A : public O <A::event>
{
public:

class event
{
// ...
};
};

Mais évidemment, le code ne compile pas ("A::event non déclaré"). Et je ne
peux pas utiliser la solution habituelle qui est de déclarer un "class XXX"
avant l'utilisation. Dans mon cas, ça serait :

class A
{
class event;
};

class A : public O <A::event>
{
public:

class event
{
// ...
};
};

qui ne compile bien entendu pas (redéfinition de A). Un "class A::event;" ne
compile évidemment pas non plus...

Quelqu'un a-t-il une idée de comment faire, sachant que je souhaite garder
"event" comme une classe imbriquée dans A (pour des raisons de facilité
d'utilisation et de lisibilité ("event" concerne A)) ?

Merci d'avance pour vos réponses.

Vincent

--
SL> Au fait elle est mieux ma signature maintenant ?
Oui. T'enlève encore les conneries que t'as écrit dedans et c'est bon.
-+- JB in <http://www.le-gnu.net> : Le neuneuttoyage par le vide -+-
Back to top
Gabriel Dos Reis
Guest





PostPosted: Mon Jul 28, 2003 3:24 pm    Post subject: Re: Classe imbriquée et héritage Reply with quote



Luc Hermitte <hermitte (AT) free (DOT) fr.invalid> writes:

Quote:
Ce n'est pas forcément ce que tu attends, mais cela t'en rapprochera un
peu.

class couche
{
class event {...};
public:
class A : public O<event> {...};
};
using couche::A;


L'as-tu essayé ?

(cela ne peut pas marcher).

-- Gaby


Back to top
Vincent Richard
Guest





PostPosted: Mon Jul 28, 2003 3:49 pm    Post subject: Re: Classe imbriquée et héritage Reply with quote



Le Lundi 28 Juillet 2003 17:29, Gabriel Dos Reis a écrit :

Quote:
Hmm. Je ne comprends pas vraiment ce que tu veux faire avec ça -- mais
je suppose que je ne suis pas censé comprendre :-)

Tu veux utiliser un nom avant de l'avoir déclarer. Pour moi, cela
indique un problème dans la conception.

Je ne pense pas que le problème vienne d'une erreur de conception. En fait,
c'est plutôt une question de style : je tiens à laisser la classe "event"
dans A. :-)

Explication complète de mon problème : je dispose d'une classe template
"observable" qui est utilisée dans un système de notification :

template <class EVENT_TYPE>
class observable
{
protected:

virtual ~observable() { }

void notify(const EVENT_TYPE& event);

// [...]
};

J'ai également plusieurs classes héritant de "observable" qui peuvent
émettre chacune leur type d'évènement propre :

class A : public observable <A::event>
{
public:

class event { /* ... */ }
};

class B : public observable <B::event>
{
public:

class event { /* ... */ }
};

// ...etc...

Evidemment le code ci-dessus ne compile pas, et c'est bien là le problème...

D'ailleurs, je ne comprends pas pourquoi C++ n'autorise pas le code montré
précédemment : étant donné que la déclaration de la classe n'est pas encore
terminée ('};' final), les choses manquantes peuvent encore être déclarées.
Dans le cas de l'héritage, je ne pense pas que ça pose un quelconque
problème.

Le compilateur pourrait par exemple faire une première "passe" sur le code
de déclaration de la classe, puis une deuxième en s'assurant cette fois-ci
que tout est bien connu... bon, je suis pas développeur de compilo ! :-)

Vincent

--
SL> Au fait elle est mieux ma signature maintenant ?
Oui. T'enlève encore les conneries que t'as écrit dedans et c'est bon.
-+- JB in <http://www.le-gnu.net> : Le neuneuttoyage par le vide -+-

Back to top
d4RK
Guest





PostPosted: Mon Jul 28, 2003 5:00 pm    Post subject: Re: Classe imbriquée et héritage Reply with quote

On 28 Jul 2003, 15:03:37, Luc Hermitte wrote:
Quote:
Vincent Richard <chere-loque.MARRE-DE-LA-PUB (AT) wanadoo (DOT) fr.invalid> wrote
in news:3f25121c$0$1783$626a54ce (AT) news (DOT) free.fr:
Je suis confronté à un petit problème de syntaxe avec mon code :

template <class T
class O
{
// ...
};

class A : public O {
public:

class event
{
// ...
};
};

Mais évidemment, le code ne compile pas ("A::event non déclaré"). Et
je ne peux pas utiliser la solution habituelle qui est de déclarer un
"class XXX" avant l'utilisation. Dans mon cas, ça serait :

Quelqu'un a-t-il une idée de comment faire, sachant que je souhaite
garder "event" comme une classe imbriquée dans A (pour des raisons de
facilité d'utilisation et de lisibilité ("event" concerne A)) ?


Ce n'est pas forcément ce que tu attends, mais cela t'en rapprochera un
peu.

class couche
{
class event {...};
public:
class A : public O };
using couche::A;

_____


il est clair qu'il faut laisser la classe 'event' dans la classe
A puisqu'elle en est caractéristique, mais on ne peut pas s'en
sortir en laissant la classe 'observable' template (impossible
à compiler):
j'utiliserais plutôt le polymorphisme pour m'en sortir ici, ie:
declarer une classe baseEvent de laquelle dériveraient toutes
les classes internes 'event' des classes qui en declarent (A
pour l'exemple ci-dessus). Observable redevient une classe non-template
et 'notify' travaille simplement sur les membres communs des
'event[s]'. Par contre étant donné que je ne vois pas trop ce
que fait notify sur son argument, je ne peux pas préciser...

eg: (un truc comme ça :)

class baseEvent{
//membres communs aux events...
//des virtuels donc...
};

class Observable{
//...
void notify(const baseEvent& event);
//...
};

class A:public observable{
public:
class event:public baseEvent{
//...
};
//...
};

Back to top
Luc Hermitte
Guest





PostPosted: Mon Jul 28, 2003 5:18 pm    Post subject: Re: Classe imbriquée et héritage Reply with quote

Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net> wrote in
news:m3zniy4quk.fsf (AT) uniton (DOT) integrable-solutions.net:

Quote:
| Ce n'est pas forcément ce que tu attends, mais cela t'en rapprochera
| un peu.
|
| class couche {
| class event {...}; public:
| class A : public O<event> {...}; }; using couche::A;


L'as-tu essayé ?

J'avoue que non.

--
Luc Hermitte <hermitte at free.fr>
FAQ de <news:fr.comp.lang.c++> :
<http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/>
Dejanews : <http://groups.google.com/advanced_group_search>

Back to top
Vincent Richard
Guest





PostPosted: Mon Jul 28, 2003 6:17 pm    Post subject: Re: Classe imbriquée et héritage Reply with quote

Le Lundi 28 Juillet 2003 19:00, d4RK a écrit :

[PRECISION]
L'objet "observable" est censée envoyer des évènements, tandis que
l'objet "observer" les reçoit (classique) :

template <class EVENT_TYPE>
class observer
{
virtual ~observer() { }
virtual void update(const observable <EVENT_TYPE>* o,
const EVENT_TYPE& e);
};
[/PRECISION]

Quote:
il est clair qu'il faut laisser la classe 'event' dans la classe
A puisqu'elle en est caractéristique, mais on ne peut pas s'en
sortir en laissant la classe 'observable' template (impossible
à compiler):
j'utiliserais plutôt le polymorphisme pour m'en sortir ici, ie:
declarer une classe baseEvent de laquelle dériveraient toutes
les classes internes 'event' des classes qui en declarent (A
pour l'exemple ci-dessus). Observable redevient une classe non-template
et 'notify' travaille simplement sur les membres communs des
'event[s]'.

Oui, mais cela empêche d'implémenter "observer" pour plusieurs objets
différents. Tout du moins, cela nécessite de tout regrouper dans
une seule fonction et de tester le type d'évènement (pas très élégant,
à mon goût).

Méthode "template" :

class test : public observer <A::event>, public observer <B::event>
{
void update(const observable <A::event>* o, const A::event& e)
{
// traitement des évènements de A
}

void update(const observable <B::event>* o, const B::event& e)
{
// traitement des évènements de B
}
};

Méthode "non-template" :

class test : public observer
{
// ...
void update(const observable* o, const event& e)
{
if (typeid(e) == typeid(A::event))
{ /* traitement A */ }
else if (typeid(e) == typeid(B::event))
{ /* traitement B */ }
}
};

Quote:
Par contre étant donné que je ne vois pas trop ce
que fait notify sur son argument, je ne peux pas préciser...

"notify" permet aux classes qui héritent de "observable" d'envoyer
un évènement (l'argument) à chacun des observateurs enregistrés auprès
de l'observé (classe "observer" et std::vector <observer*> dans
l'objet "observable" non présents ici, j'avais simplifié).

Vincent

--
SL> Au fait elle est mieux ma signature maintenant ?
Oui. T'enlève encore les conneries que t'as écrit dedans et c'est bon.
-+- JB in <http://www.le-gnu.net> : Le neuneuttoyage par le vide -+-

Back to top
d4RK
Guest





PostPosted: Mon Jul 28, 2003 7:51 pm    Post subject: Re: Classe imbriquée et héritage Reply with quote

On 28 Jul 2003, 20:17:01, Vincent Richard wrote:
Quote:
Le Lundi 28 Juillet 2003 19:00, d4RK a écrit :

[PRECISION]
L'objet "observable" est censée envoyer des évènements, tandis que
l'objet "observer" les reçoit (classique) :

template <class EVENT_TYPE
class observer
{
virtual ~observer() { }
virtual void update(const observable const EVENT_TYPE& e);
};
[/PRECISION]

il est clair qu'il faut laisser la classe 'event' dans la classe
A puisqu'elle en est caractéristique, mais on ne peut pas s'en
sortir en laissant la classe 'observable' template (impossible
à compiler):
j'utiliserais plutôt le polymorphisme pour m'en sortir ici, ie:
declarer une classe baseEvent de laquelle dériveraient toutes
les classes internes 'event' des classes qui en declarent (A
pour l'exemple ci-dessus). Observable redevient une classe non-template
et 'notify' travaille simplement sur les membres communs des
'event[s]'.

Oui, mais cela empêche d'implémenter "observer" pour plusieurs objets
différents. Tout du moins, cela nécessite de tout regrouper dans
une seule fonction et de tester le type d'évènement (pas très élégant,
à mon goût).

Méthode "template" :

class test : public observer <A::event>, public observer <B::event
{
void update(const observable {
// traitement des évènements de A
}

void update(const observable <B::event>* o, const B::event& e)
{
// traitement des évènements de B
}
};

Méthode "non-template" :

class test : public observer
{
// ...
void update(const observable* o, const event& e)
{
if (typeid(e) == typeid(A::event))
{ /* traitement A */ }
else if (typeid(e) == typeid(B::event))
{ /* traitement B */ }
}
};

Par contre étant donné que je ne vois pas trop ce
que fait notify sur son argument, je ne peux pas préciser...

"notify" permet aux classes qui héritent de "observable" d'envoyer
un évènement (l'argument) à chacun des observateurs enregistrés auprès
de l'observé (classe "observer" et std::vector <observer*> dans
l'objet "observable" non présents ici, j'avais simplifié).

Vincent


Ok, c'est + clair :
J'ai trouvé une solution(?) qui ne t'empêche pas d'avoir un code
qui reste 'propre' mais ça rajoute un objet 'bidon' pour chacune de tes
classes observables, ie:

au lien de faire:

class A:public Observable<A::Event>{...}

qui reste définitivement incompilable, tu peut faire:

class A{
//la classe A normale...
};
class AObservable:public A,public Observable<A::Event>{};

qui rajoute évidemment une classe 'bidon', quoique le tout reste assez
cohérent. (on ne peut pas tout avoir!)

En reprenant une synthèse de tes exemples;
Voila le code simplifié qui doit faire en gros ce que tu veux
(&& qui compile :)

<CODE>
#include <iostream>
using namespace std;

template<class EVENTTYPE> class Observer;

template<class EVENTTYPE>
class Observable{
public:
void registerObserver(Observer<EVENTTYPE>* _observer){
myObserver=_observer;
}
void notify(EVENTTYPE& e){
myObserver->update(*this,e);
}
private:
//normalement un container (vive les listes chainées)
//on se contente d'un champ pour le test Smile
Observer<EVENTTYPE>* myObserver;
};

template<class EVENTTYPE>
class Observer{
public:
virtual void update(Observable<EVENTTYPE>& o,EVENTTYPE& e)=0;
};

class A{
public:
class Event{};
Event ping;
};

class B{
public:
class Event{};
};

class AObservable:public A,public Observable<A::Event>{};

class BObservable:public B,public Observable<B::Event>{};

class test:public Observer<A::Event>,public Observer<B::Event>{
public:
void update(Observable<A::Event>& o,A::Event& e){
//traitement...
cout<<"got it! Smile"< }

void update(Observable //traitement...
}
};

int main(void){
test theObserver;
AObservable AO;
BObservable BO;
AO.registerObserver(&theObserver);
BO.registerObserver(&theObserver);
AO.notify(AO.ping);
return 42;
}
</CODE>

(comme tu l'as deviné, tu obtiens 'got it! Smile' lors de l'exécution)
Mais, il est impossible qu'il ait un truc qui m'échappe dans
ce que tu veux faire...

Back to top
d4RK
Guest





PostPosted: Mon Jul 28, 2003 8:18 pm    Post subject: Re: Classe imbriquée et héritage Reply with quote

On 28 Jul 2003, 19:51:42, d4RK wrote:

Quote:
[...]
}
/CODE

(comme tu l'as deviné, tu obtiens 'got it! Smile' lors de l'exécution)
Mais, il est impossible qu'il ait un truc qui m'échappe dans
ce que tu veux faire...

je voulais évidemment dire "il est **possible** qu'il ait qq
chose qui m'échappe " ;)

Back to top
Vincent Richard
Guest





PostPosted: Mon Jul 28, 2003 8:20 pm    Post subject: Re: Classe imbriquée et héritage Reply with quote

Le Lundi 28 Juillet 2003 21:51, d4RK a écrit :

Quote:
J'ai trouvé une solution(?) qui ne t'empêche pas d'avoir un code
qui reste 'propre' mais ça rajoute un objet 'bidon' pour chacune de tes
classes observables, ie:

au lien de faire:

class A:public Observable<A::Event>{...}

qui reste définitivement incompilable, tu peut faire:

class A{
//la classe A normale...
};
class AObservable:public A,public Observable<A::Event>{};

qui rajoute évidemment une classe 'bidon', quoique le tout reste assez
cohérent. (on ne peut pas tout avoir!)

Merci, cette solution me convient. Du point de vue intérieur (code), ce
n'est pas très "élégant", mais ce qui compte, c'est au niveau de
l'utilisateur, et là les exigences sont respectées (modulo le fait
que la classe "bidon" pollue l'espace de noms, mais on ne peut pas
tout avoir...).

Bon, n'empêche que ça serait pas mal que les compilateurs acceptent
cette foutue syntaxe ! ;-)

Vincent

--
SL> Au fait elle est mieux ma signature maintenant ?
Oui. T'enlève encore les conneries que t'as écrit dedans et c'est bon.
-+- JB in <http://www.le-gnu.net> : Le neuneuttoyage par le vide -+-

Back to top
Gabriel Dos Reis
Guest





PostPosted: Mon Jul 28, 2003 8:24 pm    Post subject: Re: Classe imbriquée ethéritage Reply with quote

Vincent Richard <chere-loque.MARRE-DE-LA-PUB (AT) wanadoo (DOT) fr.invalid> writes:

Quote:
Bon, n'empêche que ça serait pas mal que les compilateurs acceptent
cette foutue syntaxe ! Wink

c'est pas demain la veille ;-)

-- Gaby

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.