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 

Re: Question de design

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





PostPosted: Thu Jul 17, 2003 7:12 pm    Post subject: Re: Question de design Reply with quote



"amerio" <amerio (AT) hotmail (DOT) com> a écrit dans le message de
news:XFBRa.212212$1F6.2229356 (AT) news (DOT) chello.at...
Quote:
Bonjour,
Supposons que j'ai une classe Objet et deux sous classes ObjetA et ObjetB,
*déjà existants* (je ne peux pas les modifier).

Je dois "rajouter" des membres/méthodes à Objet, et par extension à tous
ces
dérivés.
Ce que je fais actuellement, c'est écrire une classe Super avec toutes les
fonctionnalités que je voudrais rajouter, puis je fais de l'héritahe
multiple :
class SuperA : public ObjetA, public Super
class SuperB : public ObjetB, public Super

SuperA et B sont donc des 'Objet', et ont les fonctionnalités de Super.
Là ou il y a un pb, c'est que Super doit pouvoir utiliser les méthodes
publiques d'un Objet.
Donc pour l'instant, le constructeur de Super prend un pointeur sur un
Objet
associé.
Super::Super(Objet* pObjet):m_pObjet(pObjet){}
Et je construits un SuperA ainsi :
SuperA::SuperA():Super(this){}

Cette construction marche, mais je me demande s'il n'y pas pas moyen de
faire mieux...
C'est peut-etre une pattern que je n'aurais pas reconnue ?

tout dépend de tes contraintes. Selon le cas, tu peux aussi utiliser la
composition au lieu de faire hériter tes classes SuperX, et de redéfinir
complètement l'interface (en gardant les mêmes signatures pour les méthodes
de ObjetX si nécessaire). De cette manière, tu évites l'héritage multiple,
ce qui peut ne pas être dénué d'intéret. En C++, tu peux également gagner en
automatisation en faisant de tes ObjetX un type fourni en paramètre pour tes
classes SuperX. Il y a en fait pas mal de solutions, mais sans connaitre
plus de détail, je ne crois pas qu'on puisse dire quelle est la meilleure
méthode.

Chris



Back to top
amerio
Guest





PostPosted: Thu Jul 17, 2003 7:30 pm    Post subject: Re: Question de design Reply with quote



Quote:
Supposons que j'ai une classe Objet et deux sous classes ObjetA et
ObjetB,
*déjà existants* (je ne peux pas les modifier).

Je dois "rajouter" des membres/méthodes à Objet, et par extension à tous
ces
dérivés.
Ce que je fais actuellement, c'est écrire une classe Super avec toutes
les
fonctionnalités que je voudrais rajouter, puis je fais de l'héritahe
multiple :
class SuperA : public ObjetA, public Super
class SuperB : public ObjetB, public Super

SuperA et B sont donc des 'Objet', et ont les fonctionnalités de Super.
Là ou il y a un pb, c'est que Super doit pouvoir utiliser les méthodes
publiques d'un Objet.
Donc pour l'instant, le constructeur de Super prend un pointeur sur un
Objet
associé.
Super::Super(Objet* pObjet):m_pObjet(pObjet){}
Et je construits un SuperA ainsi :
SuperA::SuperA():Super(this){}

Cette construction marche, mais je me demande s'il n'y pas pas moyen de
faire mieux...
C'est peut-etre une pattern que je n'aurais pas reconnue ?

tout dépend de tes contraintes. Selon le cas, tu peux aussi utiliser la
composition au lieu de faire hériter tes classes SuperX, et de redéfinir
complètement l'interface (en gardant les mêmes signatures pour les
méthodes
de ObjetX si nécessaire). De cette manière, tu évites l'héritage multiple,
ce qui peut ne pas être dénué d'intéret. En C++, tu peux également gagner
en
automatisation en faisant de tes ObjetX un type fourni en paramètre pour
tes
classes SuperX. Il y a en fait pas mal de solutions, mais sans connaitre
plus de détail, je ne crois pas qu'on puisse dire quelle est la meilleure
méthode.

J'avais écarté la composition car trop lourde dans mon cas (Objet est assez
fourni...)
De plus, tous mes Objet sont gérés par un conteneur spécialisé (Manager),
qui stocke uniquement des pointeurs sur Objet, donc la composition n'aurait
pas marché.
Manager::Add(Objet*), et bien sûr je ne peux pas modifier le Manager, ni les
classes Objet.

Toutes les methodes qu'apporte Super sont à usage interne uniquement (cad
que seul Super les utilisent, voire les méthodes surchargées de Objet par
SuperX)

class Objet{virtual void Manage() = 0;}
class ObjetA{virtual void Manage();}
class Super{virtual void Work();}

class SuperA: public ObjetA, public Super
{
virtual void Manage() { ObjetA::Manage(); Work(); }
}

void Manager::Manage() { ... pObject->Manage(); ... }



Back to top
geranium
Guest





PostPosted: Thu Jul 17, 2003 8:09 pm    Post subject: Re: Question de design Reply with quote



bonjour

ah, réduire le couplage, réduire le couplage... là c'est un plat de
spagguetti Wink)

moi je ferais :

Super implemente les nouvelles fonctionnalites et a une reference sur Objet
:
Super::Super(Objet* pObjet):m_pObjet(pObjet){}
Super::NouvelleFunc1
Super::FuncObj(){pObjet->Func()} // delegation de methodes sur Objet

SuperA et SuperB sont sous classes de super (et c'est tout !)

ou bien ?

"amerio" <amerio (AT) hotmail (DOT) com> a écrit dans le message de
news:XFBRa.212212$1F6.2229356 (AT) news (DOT) chello.at...
Quote:
Bonjour,
Supposons que j'ai une classe Objet et deux sous classes ObjetA et ObjetB,
*déjà existants* (je ne peux pas les modifier).

Je dois "rajouter" des membres/méthodes à Objet, et par extension à tous
ces
dérivés.
Ce que je fais actuellement, c'est écrire une classe Super avec toutes les
fonctionnalités que je voudrais rajouter, puis je fais de l'héritahe
multiple :
class SuperA : public ObjetA, public Super
class SuperB : public ObjetB, public Super

SuperA et B sont donc des 'Objet', et ont les fonctionnalités de Super.
Là ou il y a un pb, c'est que Super doit pouvoir utiliser les méthodes
publiques d'un Objet.
Donc pour l'instant, le constructeur de Super prend un pointeur sur un
Objet
associé.
Super::Super(Objet* pObjet):m_pObjet(pObjet){}
Et je construits un SuperA ainsi :
SuperA::SuperA():Super(this){}

Cette construction marche, mais je me demande s'il n'y pas pas moyen de
faire mieux...
C'est peut-etre une pattern que je n'aurais pas reconnue ?






Back to top
amerio
Guest





PostPosted: Thu Jul 17, 2003 8:23 pm    Post subject: Re: Question de design Reply with quote

[reponse en bas]
Quote:

"amerio" <amerio (AT) hotmail (DOT) com> a écrit dans le message de
news:XFBRa.212212$1F6.2229356 (AT) news (DOT) chello.at...
Bonjour,
Supposons que j'ai une classe Objet et deux sous classes ObjetA et
ObjetB,
*déjà existants* (je ne peux pas les modifier).

Je dois "rajouter" des membres/méthodes à Objet, et par extension à tous
ces
dérivés.
Ce que je fais actuellement, c'est écrire une classe Super avec toutes
les
fonctionnalités que je voudrais rajouter, puis je fais de l'héritahe
multiple :
class SuperA : public ObjetA, public Super
class SuperB : public ObjetB, public Super

SuperA et B sont donc des 'Objet', et ont les fonctionnalités de Super.
Là ou il y a un pb, c'est que Super doit pouvoir utiliser les méthodes
publiques d'un Objet.
Donc pour l'instant, le constructeur de Super prend un pointeur sur un
Objet
associé.
Super::Super(Objet* pObjet):m_pObjet(pObjet){}
Et je construits un SuperA ainsi :
SuperA::SuperA():Super(this){}

Cette construction marche, mais je me demande s'il n'y pas pas moyen de
faire mieux...
C'est peut-etre une pattern que je n'aurais pas reconnue ?


ah, réduire le couplage, réduire le couplage... là c'est un plat de
spagguetti Wink)

hehe, c'est pas si simple, hélas...

Quote:
moi je ferais :

Super implemente les nouvelles fonctionnalites et a une reference sur
Objet
:
Super::Super(Objet* pObjet):m_pObjet(pObjet){}
Super::NouvelleFunc1
Super::FuncObj(){pObjet->Func()} // delegation de methodes sur Objet

SuperA et SuperB sont sous classes de super (et c'est tout !)

ou bien ?

Et bien cela je ne peux pas. J'avais certes oublié de dire que tous ces
Objets sont gérés par un Manager (qui ne prend que des Objet*). Des Super ne
dérivant pas de Objet ne conviennent donc pas Sad
(voir mon autre post)

En fait, pour le monde extérieur, je ne rajoute _rien_ à Objet (je ne change
pas l'interface pour Manager, qui ne connait en fait "que"
Objet::Manage()..., et ignore Super). Par contre, SuperX modifie Manage, en
appelant des méthodes de Super...

Je ne sais pas si une autre solution existe, mais il y a tant de choses à
apprendre :-)



Back to top
Christophe Lephay
Guest





PostPosted: Thu Jul 17, 2003 10:41 pm    Post subject: Re: Question de design Reply with quote

"amerio" <amerio (AT) hotmail (DOT) com> a écrit dans le message de
news:4PCRa.213445$1F6.2239234 (AT) news (DOT) chello.at...
Quote:
J'avais écarté la composition car trop lourde dans mon cas (Objet est
assez
fourni...)

Ce n'est pas un argument pertinent, car même si ça peut sembler lourd à
écrire, tu ne l'écris qu'une seule fois (comparé aux n utilisations, c'est
traditionnellement largement amortit)...

Quote:
De plus, tous mes Objet sont gérés par un conteneur spécialisé (Manager),
qui stocke uniquement des pointeurs sur Objet, donc la composition
n'aurait
pas marché.
Manager::Add(Objet*), et bien sûr je ne peux pas modifier le Manager, ni
les
classes Objet.

Si tu utilises l'héritage multiple, pense à faire un héritage virtuel si tu
veux conserver le polymorphisme...

Quote:
Toutes les methodes qu'apporte Super sont à usage interne uniquement (cad
que seul Super les utilisent, voire les méthodes surchargées de Objet par
SuperX)
class Objet{virtual void Manage() = 0;}
class ObjetA{virtual void Manage();}
class Super{virtual void Work();}

class SuperA: public ObjetA, public Super
{
virtual void Manage() { ObjetA::Manage(); Work(); }
}

void Manager::Manage() { ... pObject->Manage(); ... }

La composition reste néanmoins possible :

class SuperObjetA : public ObjetA
{
Super * pSuper;
....
void Manage() { ObjetA::Manage(); pSuper->Work(); }
};

Chris



Back to top
amerio
Guest





PostPosted: Fri Jul 18, 2003 7:02 am    Post subject: Re: Question de design Reply with quote

Quote:
Ce n'est pas un argument pertinent, car même si ça peut sembler lourd à
écrire, tu ne l'écris qu'une seule fois (comparé aux n utilisations, c'est
traditionnellement largement amortit)...

C'est vrai .... sauf que dans mon cas, Objet - bien que je ne puisse pas le
changer *moi* - peut évoluer (autre équipe). Dans ce cas, reporter les
modifs sur Objet devient lourd.
Sinon, je suis d'accord avec toi, le coup serait amorti.

Quote:
De plus, tous mes Objet sont gérés par un conteneur spécialisé
(Manager),
qui stocke uniquement des pointeurs sur Objet, donc la composition
n'aurait
pas marché.
Manager::Add(Objet*), et bien sûr je ne peux pas modifier le Manager, ni
les
classes Objet.

Si tu utilises l'héritage multiple, pense à faire un héritage virtuel si
tu
veux conserver le polymorphisme...
L'héritage virtuel ne sert que si la classe de base est plus d'une fois dans

la hiérarchie, non ?
Et ce n'est pas le cas, ici ! Ou me-trompe-je ?

Quote:

Toutes les methodes qu'apporte Super sont à usage interne uniquement
(cad
que seul Super les utilisent, voire les méthodes surchargées de Objet
par
SuperX)
class Objet{virtual void Manage() = 0;}
class ObjetA{virtual void Manage();}
class Super{virtual void Work();}

class SuperA: public ObjetA, public Super
{
virtual void Manage() { ObjetA::Manage(); Work(); }
}

void Manager::Manage() { ... pObject->Manage(); ... }

La composition reste néanmoins possible :

class SuperObjetA : public ObjetA
{
Super * pSuper;
...
void Manage() { ObjetA::Manage(); pSuper->Work(); }
};

Oui, effectivemnt, ca marche aussi comme ca !
Je vais y réfléchir... merci !



Back to top
Arnaud Debaene
Guest





PostPosted: Fri Jul 18, 2003 11:25 am    Post subject: Re: Question de design Reply with quote

"amerio" <amerio (AT) hotmail (DOT) com> wrote

Quote:
Bonjour,
Supposons que j'ai une classe Objet et deux sous classes ObjetA et ObjetB,
*déjà existants* (je ne peux pas les modifier).

Je dois "rajouter" des membres/méthodes à Objet, et par extension à tous ces
dérivés.
Ce que je fais actuellement, c'est écrire une classe Super avec toutes les
fonctionnalités que je voudrais rajouter, puis je fais de l'héritahe
multiple :
class SuperA : public ObjetA, public Super
class SuperB : public ObjetB, public Super

SuperA et B sont donc des 'Objet', et ont les fonctionnalités de Super.
Là ou il y a un pb, c'est que Super doit pouvoir utiliser les méthodes
publiques d'un Objet.
Donc pour l'instant, le constructeur de Super prend un pointeur sur un Objet
associé.
Super::Super(Objet* pObjet):m_pObjet(pObjet){}
Et je construits un SuperA ainsi :
SuperA::SuperA():Super(this){}

Cette construction marche, mais je me demande s'il n'y pas pas moyen de
faire mieux...
C'est peut-etre une pattern que je n'aurais pas reconnue ?

Est-ce quelque chose comme ceci ferait l'affaire? :

template <class T> class Super : public T
{
//blabla
};

typedef Super<ObjetA> SuperA;
typedef Super<ObjetB> SuperB;

Tu évites l'héritage multiple, tes objets sont toujours des Objet et
donc manipulables par ton Manager.

Arnaud

Back to top
amerio
Guest





PostPosted: Fri Jul 18, 2003 4:23 pm    Post subject: Re: Question de design Reply with quote

Quote:
Supposons que j'ai une classe Objet et deux sous classes ObjetA et
ObjetB,
*déjà existants* (je ne peux pas les modifier).

Je dois "rajouter" des membres/méthodes à Objet, et par extension à tous
ces
dérivés.
Ce que je fais actuellement, c'est écrire une classe Super avec toutes
les
fonctionnalités que je voudrais rajouter, puis je fais de l'héritahe
multiple :
class SuperA : public ObjetA, public Super
class SuperB : public ObjetB, public Super

SuperA et B sont donc des 'Objet', et ont les fonctionnalités de Super.
Là ou il y a un pb, c'est que Super doit pouvoir utiliser les méthodes
publiques d'un Objet.
Donc pour l'instant, le constructeur de Super prend un pointeur sur un
Objet
associé.
Super::Super(Objet* pObjet):m_pObjet(pObjet){}
Et je construits un SuperA ainsi :
SuperA::SuperA():Super(this){}

Cette construction marche, mais je me demande s'il n'y pas pas moyen de
faire mieux...
C'est peut-etre une pattern que je n'aurais pas reconnue ?

Est-ce quelque chose comme ceci ferait l'affaire? :

template <class T> class Super : public T
{
//blabla
};

typedef Super<ObjetA> SuperA;
typedef Super<ObjetB> SuperB;

Tu évites l'héritage multiple, tes objets sont toujours des Objet et
donc manipulables par ton Manager.

Oui, cela peut resoudre mon problème, mais je regrette que le template
m'oblige à tout mettre dans le .h
Bien sur, je pourrais faire un '.inl' plutot qu'un cpp (ou inclure et ne pas
compiler le .cpp)
L'autre avantage est que je pourrais utiliser directement les méthodes de
Objet, sans passer par un pointeur (si je ne me trompe pas).
Par contre pour le typedef, je ne comprend pas. SuperA n'est pas juste un
mix de Super et ObjetA, mais doit pouvoir les étendre (héritage).
Peut-etre que cela convient :
class SuperA : public Super<ObjetA>
{
....
}

Par contre, encore une question :
Si je construits ainsi SuperA et SuperB, puis-je faire un static_cast vers
l'un ou l'autre à partir d'un Super* ? (et d'abord, comment le construire si
c'est un template ??)



Back to top
Arnaud Debaene
Guest





PostPosted: Fri Jul 18, 2003 6:30 pm    Post subject: Re: Question de design Reply with quote

amerio wrote:
Quote:
Est-ce quelque chose comme ceci ferait l'affaire? :

template <class T> class Super : public T
{
//blabla
};

typedef Super<ObjetA> SuperA;
typedef Super<ObjetB> SuperB;

Tu évites l'héritage multiple, tes objets sont toujours des Objet et
donc manipulables par ton Manager.

Oui, cela peut resoudre mon problème, mais je regrette que le template
m'oblige à tout mettre dans le .h
Eternel problèmes des templates, jusqu'à ce que export sot disponible sur

ton compilateur préféré.

Quote:
L'autre avantage est que je pourrais utiliser directement les
méthodes de Objet, sans passer par un pointeur (si je ne me trompe
pas).
Dans quel contexte? Effectivement, SuperA et SuperB héritent publiquement de

Objet, donc ses méthodes sont disponibles dans leur implémentation.

Quote:
Par contre pour le typedef, je ne comprend pas. SuperA n'est pas
juste un mix de Super et ObjetA, mais doit pouvoir les étendre
(héritage).
Peut-etre que cela convient :
class SuperA : public Super {
...
}
Ah, ok, j'avais pas compris que SuperA et SuperB définissaient un niveau de

spécialisation supplémentaire.

Quote:
Par contre, encore une question :
Si je construits ainsi SuperA et SuperB, puis-je faire un static_cast
vers l'un ou l'autre à partir d'un Super* ? (et d'abord, comment le
construire si c'est un template ??)

Super n'est pas un type en tant que tel. Tu ne peux pas définir de Super*,
tu ne peux instancier que des spécialisations complètes. Je ne vois pas trop
où tu veux en venir là....

Arnaud



Back to top
amerio
Guest





PostPosted: Fri Jul 18, 2003 7:52 pm    Post subject: Re: Question de design Reply with quote

Quote:
Si je construits ainsi SuperA et SuperB, puis-je faire un static_cast
vers l'un ou l'autre à partir d'un Super* ? (et d'abord, comment le
construire si c'est un template ??)

Super n'est pas un type en tant que tel. Tu ne peux pas définir de Super*,
tu ne peux instancier que des spécialisations complètes. Je ne vois pas
trop
où tu veux en venir là....

Il est bien sur évident que Super* n'est pas définissable.
En fait, ma question venait du fait que j'utilise actuellement un tableau de
Super* pour contenir ceux de mes Objet qui dérivent par héritage multiple de
Super et Objet.
Donc j'ai un tableau de Super*... Que je ne peux plus écrire si je fais un
template.

Au passage, supposons que j'ai un pointeur sur un Objet, dont je sois *sur*
qu'il est aussi un Super<Objet>.
J'ai donc :
Objet* pObjet ; // pObjet = new SuperA; ou SuperB; c'est sur
Comment accéder au méthode de Super via pObjet ? (communes à SuperA et
SuperB, mais par contre je ne sais pas si c'est un SuperA ou B, juste un
Super...)



Back to top
Christophe Lephay
Guest





PostPosted: Fri Jul 18, 2003 11:00 pm    Post subject: Re: Question de design Reply with quote

"amerio" <amerio (AT) hotmail (DOT) com> a écrit dans le message de
news:PdYRa.233259$1F6.2436072 (AT) news (DOT) chello.at...
Quote:
Si je construits ainsi SuperA et SuperB, puis-je faire un static_cast
vers l'un ou l'autre à partir d'un Super* ? (et d'abord, comment le
construire si c'est un template ??)

Super n'est pas un type en tant que tel. Tu ne peux pas définir de
Super*,
tu ne peux instancier que des spécialisations complètes. Je ne vois pas
trop
où tu veux en venir là....

Il est bien sur évident que Super* n'est pas définissable.
En fait, ma question venait du fait que j'utilise actuellement un tableau
de
Super* pour contenir ceux de mes Objet qui dérivent par héritage multiple
de
Super et Objet.
Donc j'ai un tableau de Super*... Que je ne peux plus écrire si je fais un
template.

Tu peux très bien regler ce problème à peu de frais :

class Super
{
....
virtual void work() = 0;
....
};

template< class T >
SuperObjet : virtual public Objet, virtual public Super
{
void work();
void methode() { T::methode(); work(); }
};

Quote:
Au passage, supposons que j'ai un pointeur sur un Objet, dont je sois
*sur*
qu'il est aussi un Super<Objet>.
J'ai donc :
Objet* pObjet ; // pObjet = new SuperA; ou SuperB; c'est sur
Comment accéder au méthode de Super via pObjet ? (communes à SuperA et
SuperB, mais par contre je ne sais pas si c'est un SuperA ou B, juste un
Super...)

Un dynamic_cast< Super * > ne fait pas l'affaire ?

Chris



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.