j'ai une class A qui contient un tableau de d'objet de la classe B.
D'un autre coté j'aimerai pouvoir stocker un pointeur de la class A dans l'objet B !!!
mais je ne peux pas inclure classA.h dans la définition de l'objet B et inclure classB.h dans la définition de l'objet A
car évidement, l'un des deux fichiers est forcément parsé en premier !!!
Comment solutionne t-on ce problème?
Dans classA.h :
class A; // prototypes de classes class B;
classA { ........... B _tabB[10]; // par exemple, ou: B *_tabB; };
Dans classB.h :
class A; // prototypes de classes class B;
classB { ........... A *_ptrA; };
Et il faut inclure classB.h avant classA.h.
Mais, plutôt qu'un tableau de B, je mettrais un vector de B* dans la classe A: std::vector<B *> _vecB; Comme ça l'ordre des inclusions serait indifférent.
--
Etienne
Le 13/02/2011 10:29, WebShaker a écrit :
j'ai une class A qui contient un tableau de d'objet de la classe B.
D'un autre coté j'aimerai pouvoir stocker un pointeur de la class A dans
l'objet B !!!
mais je ne peux pas inclure classA.h dans la définition de l'objet B
et inclure classB.h dans la définition de l'objet A
car évidement, l'un des deux fichiers est forcément parsé en premier !!!
Comment solutionne t-on ce problème?
Dans classA.h :
class A; // prototypes de classes
class B;
classA
{
...........
B _tabB[10]; // par exemple, ou: B *_tabB;
};
Dans classB.h :
class A; // prototypes de classes
class B;
classB
{
...........
A *_ptrA;
};
Et il faut inclure classB.h avant classA.h.
Mais, plutôt qu'un tableau de B, je mettrais
un vector de B* dans la classe A:
std::vector<B *> _vecB;
Comme ça l'ordre des inclusions serait indifférent.
j'ai une class A qui contient un tableau de d'objet de la classe B.
D'un autre coté j'aimerai pouvoir stocker un pointeur de la class A dans l'objet B !!!
mais je ne peux pas inclure classA.h dans la définition de l'objet B et inclure classB.h dans la définition de l'objet A
car évidement, l'un des deux fichiers est forcément parsé en premier !!!
Comment solutionne t-on ce problème?
Dans classA.h :
class A; // prototypes de classes class B;
classA { ........... B _tabB[10]; // par exemple, ou: B *_tabB; };
Dans classB.h :
class A; // prototypes de classes class B;
classB { ........... A *_ptrA; };
Et il faut inclure classB.h avant classA.h.
Mais, plutôt qu'un tableau de B, je mettrais un vector de B* dans la classe A: std::vector<B *> _vecB; Comme ça l'ordre des inclusions serait indifférent.
--
Etienne
Mickaël Wolff
Tout d'abord, le sujet n'est absoluement pas en charte. Il faut un titre plus explicite.
On 13/02/11 09:51, Etienne Rousee wrote:
Dans classA.h :
class A; // prototypes de classes
En réalité, c'est une déclaration. Au fait, on appelle cette technique « forwarding declaration ».
Dans classB.h :
class A; // prototypes de classes class B;
Déclarer class B est inutile ici.
classB { ........... A *_ptrA;
Les noms de symboles commençant par un underscore sont réservés aux implémenteurs de la STL. Le comportement ici est donc indéfini.
Et il faut inclure classB.h avant classA.h.
Pourquoi ? Il faut inclure le moins de fichiers possible dans les en-têtes, pour limiter le couplage. À moins que tu ne parlais de l'inclusion des en-têtes dans le module de définition de la class B ?
Mais, plutôt qu'un tableau de B, je mettrais un vector de B* dans la classe A: std::vector<B *> _vecB; Comme ça l'ordre des inclusions serait indifférent.
Au delà de l'ordre des includes, c'est surtout qu'un std::vector sera plus naturel en C++ qu'un tableau à la C.
Tout d'abord, le sujet n'est absoluement pas en charte. Il faut un
titre plus explicite.
On 13/02/11 09:51, Etienne Rousee wrote:
Dans classA.h :
class A; // prototypes de classes
En réalité, c'est une déclaration.
Au fait, on appelle cette technique « forwarding declaration ».
Dans classB.h :
class A; // prototypes de classes
class B;
Déclarer class B est inutile ici.
classB
{
...........
A *_ptrA;
Les noms de symboles commençant par un underscore sont réservés aux
implémenteurs de la STL. Le comportement ici est donc indéfini.
Et il faut inclure classB.h avant classA.h.
Pourquoi ? Il faut inclure le moins de fichiers possible dans les
en-têtes, pour limiter le couplage. À moins que tu ne parlais de
l'inclusion des en-têtes dans le module de définition de la class B ?
Mais, plutôt qu'un tableau de B, je mettrais
un vector de B* dans la classe A:
std::vector<B *> _vecB;
Comme ça l'ordre des inclusions serait indifférent.
Au delà de l'ordre des includes, c'est surtout qu'un std::vector sera
plus naturel en C++ qu'un tableau à la C.
Tout d'abord, le sujet n'est absoluement pas en charte. Il faut un titre plus explicite.
On 13/02/11 09:51, Etienne Rousee wrote:
Dans classA.h :
class A; // prototypes de classes
En réalité, c'est une déclaration. Au fait, on appelle cette technique « forwarding declaration ».
Dans classB.h :
class A; // prototypes de classes class B;
Déclarer class B est inutile ici.
classB { ........... A *_ptrA;
Les noms de symboles commençant par un underscore sont réservés aux implémenteurs de la STL. Le comportement ici est donc indéfini.
Et il faut inclure classB.h avant classA.h.
Pourquoi ? Il faut inclure le moins de fichiers possible dans les en-têtes, pour limiter le couplage. À moins que tu ne parlais de l'inclusion des en-têtes dans le module de définition de la class B ?
Mais, plutôt qu'un tableau de B, je mettrais un vector de B* dans la classe A: std::vector<B *> _vecB; Comme ça l'ordre des inclusions serait indifférent.
Au delà de l'ordre des includes, c'est surtout qu'un std::vector sera plus naturel en C++ qu'un tableau à la C.
Michael Doubez
On 13 fév, 18:11, Mickaël Wolff wrote:
Tout d'abord, le sujet n'est absoluement pas en charte. Il faut un titre plus explicite.
On 13/02/11 09:51, Etienne Rousee wrote:> Dans classA.h :
> class A; // prototypes de classes
En r alit , c'est une d claration. Au fait, on appelle cette technique forwarding declaration .
> Dans classB.h :
> class A; // prototypes de classes > class B;
D clarer class B est inutile ici.
> classB > { > ........... > A *_ptrA;
Les noms de symboles commen ant par un underscore sont r serv s au x impl menteurs de la STL. Le comportement ici est donc ind fini.
Uniquement dans le namespace global.
Les noms réservés dans tous les namespaces sont ceux commençant par u n underscore ouis une majuscule ou les noms ayant un double underscore.
[snip]
-- Michael
On 13 fév, 18:11, Mickaël Wolff <mickael.wo...@laposte.net> wrote:
Tout d'abord, le sujet n'est absoluement pas en charte. Il faut un
titre plus explicite.
On 13/02/11 09:51, Etienne Rousee wrote:> Dans classA.h :
> class A; // prototypes de classes
En r alit , c'est une d claration.
Au fait, on appelle cette technique forwarding declaration .
> Dans classB.h :
> class A; // prototypes de classes
> class B;
D clarer class B est inutile ici.
> classB
> {
> ...........
> A *_ptrA;
Les noms de symboles commen ant par un underscore sont r serv s au x
impl menteurs de la STL. Le comportement ici est donc ind fini.
Uniquement dans le namespace global.
Les noms réservés dans tous les namespaces sont ceux commençant par u n
underscore ouis une majuscule ou les noms ayant un double underscore.
Tout d'abord, le sujet n'est absoluement pas en charte. Il faut un titre plus explicite.
On 13/02/11 09:51, Etienne Rousee wrote:> Dans classA.h :
> class A; // prototypes de classes
En r alit , c'est une d claration. Au fait, on appelle cette technique forwarding declaration .
> Dans classB.h :
> class A; // prototypes de classes > class B;
D clarer class B est inutile ici.
> classB > { > ........... > A *_ptrA;
Les noms de symboles commen ant par un underscore sont r serv s au x impl menteurs de la STL. Le comportement ici est donc ind fini.
Uniquement dans le namespace global.
Les noms réservés dans tous les namespaces sont ceux commençant par u n underscore ouis une majuscule ou les noms ayant un double underscore.
[snip]
-- Michael
Mickaël Wolff
On 13/02/11 18:43, Michael Doubez wrote:
Uniquement dans le namespace global.
Les noms réservés dans tous les namespaces sont ceux commençant par un underscore ouis une majuscule ou les noms ayant un double underscore.
Merci pour la précision. J'avais banni l'usage du leading underscore depuis que j'avais appris que c'était réservé dans certains cas. Ceci dit, ça m'explique pourquoi ils utilisent _M_.* dans la STL fournie avec GCC.
Ceci dit, je pense que c'est quand même une bonne idée de ne pas utiliser tout les symboles commençant par underscore. Vu que c'est réservé dans une portée suppérieure, on peut éventuellement avoir des problèmes de symbole caché.
On 13/02/11 18:43, Michael Doubez wrote:
Uniquement dans le namespace global.
Les noms réservés dans tous les namespaces sont ceux commençant par un
underscore ouis une majuscule ou les noms ayant un double underscore.
Merci pour la précision. J'avais banni l'usage du leading underscore
depuis que j'avais appris que c'était réservé dans certains cas. Ceci
dit, ça m'explique pourquoi ils utilisent _M_.* dans la STL fournie avec
GCC.
Ceci dit, je pense que c'est quand même une bonne idée de ne pas
utiliser tout les symboles commençant par underscore. Vu que c'est
réservé dans une portée suppérieure, on peut éventuellement avoir des
problèmes de symbole caché.
Les noms réservés dans tous les namespaces sont ceux commençant par un underscore ouis une majuscule ou les noms ayant un double underscore.
Merci pour la précision. J'avais banni l'usage du leading underscore depuis que j'avais appris que c'était réservé dans certains cas. Ceci dit, ça m'explique pourquoi ils utilisent _M_.* dans la STL fournie avec GCC.
Ceci dit, je pense que c'est quand même une bonne idée de ne pas utiliser tout les symboles commençant par underscore. Vu que c'est réservé dans une portée suppérieure, on peut éventuellement avoir des problèmes de symbole caché.
Etienne Rousee
Le 13/02/2011 18:11, Mickaël Wolff a écrit :
> Tout d'abord, le sujet n'est absoluement pas en charte. Il faut un > titre plus explicite.
Oui, j'ai gardé le titre de l'OP, comme toi.
> On 13/02/11 09:51, Etienne Rousee wrote:
>> Dans classA.h : >> >> class A; // prototypes de classes
> En réalité, c'est une déclaration. > Au fait, on appelle cette technique « forwarding declaration ».
Et en français ? Dans l'esprit, c'est prévenir le compilateur que ce nom existe et que c'est un nom de classe.
>> Dans classB.h : >> >> class A; // prototypes de classes >> class B;
> Déclarer class B est inutile ici. >
>> classB >> { >> ........... >> A *_ptrA;
> Les noms de symboles commençant par un underscore sont réservés aux > implémenteurs de la STL. Le comportement ici est donc indéfini.
Il n'y a pas de loi là dessus. C'est juste une question de convention d'écriture. Il se trouve que j'ai appris le C++ avec cette convention, mais il y en a d'autres. Il doit même y en avoir une par entreprise ou presque.
>
>> Et il faut inclure classB.h avant classA.h.
> Pourquoi ? Il faut inclure le moins de fichiers possible dans les > en-têtes, pour limiter le couplage. À moins que tu ne parlais de > l'inclusion des en-têtes dans le module de définition de la class B ?
Ici, c'est forcément couplé, puisque l'OP veut se servir de A dans B et de B dans A. Mais effectivement, je parlais de l'inclusion dans classB.cpp.
>> Mais, plutôt qu'un tableau de B, je mettrais >> un vector de B* dans la classe A: >> std::vector<B *> _vecB; >> Comme ça l'ordre des inclusions serait indifférent.
> Au delà de l'ordre des includes, c'est surtout qu'un std::vector sera > plus naturel en C++ qu'un tableau à la C.
Oui pour le vecteur, mais B* au lieu de B influe sur l'ordre.
-- Etienne
Le 13/02/2011 18:11, Mickaël Wolff a écrit :
> Tout d'abord, le sujet n'est absoluement pas en charte. Il faut un
> titre plus explicite.
Oui, j'ai gardé le titre de l'OP, comme toi.
> On 13/02/11 09:51, Etienne Rousee wrote:
>> Dans classA.h :
>>
>> class A; // prototypes de classes
> En réalité, c'est une déclaration.
> Au fait, on appelle cette technique « forwarding declaration ».
Et en français ? Dans l'esprit, c'est prévenir le compilateur que ce
nom existe et que c'est un nom de classe.
>> Dans classB.h :
>>
>> class A; // prototypes de classes
>> class B;
> Déclarer class B est inutile ici.
>
>> classB
>> {
>> ...........
>> A *_ptrA;
> Les noms de symboles commençant par un underscore sont réservés aux
> implémenteurs de la STL. Le comportement ici est donc indéfini.
Il n'y a pas de loi là dessus. C'est juste une question de convention
d'écriture. Il se trouve que j'ai appris le C++ avec cette convention,
mais il y en a d'autres. Il doit même y en avoir une par entreprise
ou presque.
>
>> Et il faut inclure classB.h avant classA.h.
> Pourquoi ? Il faut inclure le moins de fichiers possible dans les
> en-têtes, pour limiter le couplage. À moins que tu ne parlais de
> l'inclusion des en-têtes dans le module de définition de la class B ?
Ici, c'est forcément couplé, puisque l'OP veut se servir de A dans B
et de B dans A. Mais effectivement, je parlais de l'inclusion dans
classB.cpp.
>> Mais, plutôt qu'un tableau de B, je mettrais
>> un vector de B* dans la classe A:
>> std::vector<B *> _vecB;
>> Comme ça l'ordre des inclusions serait indifférent.
> Au delà de l'ordre des includes, c'est surtout qu'un std::vector sera
> plus naturel en C++ qu'un tableau à la C.
Oui pour le vecteur, mais B* au lieu de B influe sur l'ordre.
> Tout d'abord, le sujet n'est absoluement pas en charte. Il faut un > titre plus explicite.
Oui, j'ai gardé le titre de l'OP, comme toi.
> On 13/02/11 09:51, Etienne Rousee wrote:
>> Dans classA.h : >> >> class A; // prototypes de classes
> En réalité, c'est une déclaration. > Au fait, on appelle cette technique « forwarding declaration ».
Et en français ? Dans l'esprit, c'est prévenir le compilateur que ce nom existe et que c'est un nom de classe.
>> Dans classB.h : >> >> class A; // prototypes de classes >> class B;
> Déclarer class B est inutile ici. >
>> classB >> { >> ........... >> A *_ptrA;
> Les noms de symboles commençant par un underscore sont réservés aux > implémenteurs de la STL. Le comportement ici est donc indéfini.
Il n'y a pas de loi là dessus. C'est juste une question de convention d'écriture. Il se trouve que j'ai appris le C++ avec cette convention, mais il y en a d'autres. Il doit même y en avoir une par entreprise ou presque.
>
>> Et il faut inclure classB.h avant classA.h.
> Pourquoi ? Il faut inclure le moins de fichiers possible dans les > en-têtes, pour limiter le couplage. À moins que tu ne parlais de > l'inclusion des en-têtes dans le module de définition de la class B ?
Ici, c'est forcément couplé, puisque l'OP veut se servir de A dans B et de B dans A. Mais effectivement, je parlais de l'inclusion dans classB.cpp.
>> Mais, plutôt qu'un tableau de B, je mettrais >> un vector de B* dans la classe A: >> std::vector<B *> _vecB; >> Comme ça l'ordre des inclusions serait indifférent.
> Au delà de l'ordre des includes, c'est surtout qu'un std::vector sera > plus naturel en C++ qu'un tableau à la C.
Oui pour le vecteur, mais B* au lieu de B influe sur l'ordre.
-- Etienne
Michael Doubez
On 13 fév, 20:11, Mickaël Wolff wrote:
On 13/02/11 18:43, Michael Doubez wrote:
> Uniquement dans le namespace global.
> Les noms r serv s dans tous les namespaces sont ceux commen ant par un > underscore ouis une majuscule ou les noms ayant un double underscore.
Merci pour la pr cision. J'avais banni l'usage du leading undersco re depuis que j'avais appris que c' tait r serv dans certains cas. Ceci dit, a m'explique pourquoi ils utilisent _M_.* dans la STL fournie avec GCC.
Il me semble qu'il y a des cas où ça pourrait poser problème avec le C99 qui réserve plus de noms; je suppose que c'est dû à l'absence de namespace. Je crois que POSIX ajoute aussi sont lot de formes réservées.
En pratique, j'ai jamais vu ni entendu parler de problèmes lié à ça . Et c'est à mon avis une réserve pour pouvoir ajouter des noms réservés. Et si quelqu'un râle, qu'on puisse lui dire qu'il n'avait qu'à ne pas utiliser une forme réservée.
Ceci dit, je pense que c'est quand m me une bonne id e de ne pas utiliser tout les symboles commen ant par underscore. Vu que c'est r serv dans une port e supp rieure, on peut ventuellement avoir des probl mes de symbole cach .
Dans le contexte d'une fonction membre, je ne vois pas de cas problème. Peut être dans un cas de classe template où un two-phase lookup aurait dû être utiliser (i.e. utiliser this->_member) et que la variable globale est utilisé en lieu et place de la variable membre. C'est un risque assez vague.
AMA c'est plutôt une question de lisibilité. J'ai utilisé un temps la notation membre_; mais c'est vraiment laid (membre_->foo() ) et pas très lisible. J'ai vu certains utiliser m_member , mMember ou myMember. Le dernière forme étant peut être la plus explicite mais à un je ne sais quoi qui me déplait (peut être mon orgueil qui refuse d'utiliser des conventions d'amateur même si des gens aussi expérimentés que James Kanze l'utilisent :)
Au travaille, nous utilisons tous la forme _member. Et je pense que je ne m'avance pas trop en disant que c'est la forme la plus populaire.
En fait, pour être tout à fait sûr il faudrait que le langage c++ standardise des namespaces de contexte comme dans certains langages dynamiques: - m::* pour désigner les noms membres - g::* les globales - a::* pour les arguments de fonction
Je pense que se réserver des namespaces d'une seule lettre ne casserait pas beaucoup de code. Et ça serait optionnel.
-- Michael
On 13 fév, 20:11, Mickaël Wolff <mickael.wo...@laposte.net> wrote:
On 13/02/11 18:43, Michael Doubez wrote:
> Uniquement dans le namespace global.
> Les noms r serv s dans tous les namespaces sont ceux commen ant par un
> underscore ouis une majuscule ou les noms ayant un double underscore.
Merci pour la pr cision. J'avais banni l'usage du leading undersco re
depuis que j'avais appris que c' tait r serv dans certains cas. Ceci
dit, a m'explique pourquoi ils utilisent _M_.* dans la STL fournie avec
GCC.
Il me semble qu'il y a des cas où ça pourrait poser problème avec le
C99 qui réserve plus de noms; je suppose que c'est dû à l'absence de
namespace. Je crois que POSIX ajoute aussi sont lot de formes
réservées.
En pratique, j'ai jamais vu ni entendu parler de problèmes lié à ça .
Et c'est à mon avis une réserve pour pouvoir ajouter des noms
réservés. Et si quelqu'un râle, qu'on puisse lui dire qu'il n'avait
qu'à ne pas utiliser une forme réservée.
Ceci dit, je pense que c'est quand m me une bonne id e de ne pas
utiliser tout les symboles commen ant par underscore. Vu que c'est
r serv dans une port e supp rieure, on peut ventuellement avoir des
probl mes de symbole cach .
Dans le contexte d'une fonction membre, je ne vois pas de cas
problème. Peut être dans un cas de classe template où un two-phase
lookup aurait dû être utiliser (i.e. utiliser this->_member) et que la
variable globale est utilisé en lieu et place de la variable membre.
C'est un risque assez vague.
AMA c'est plutôt une question de lisibilité. J'ai utilisé un temps la
notation membre_; mais c'est vraiment laid (membre_->foo() ) et pas
très lisible. J'ai vu certains utiliser m_member , mMember ou
myMember. Le dernière forme étant peut être la plus explicite mais à
un je ne sais quoi qui me déplait (peut être mon orgueil qui refuse
d'utiliser des conventions d'amateur même si des gens aussi
expérimentés que James Kanze l'utilisent :)
Au travaille, nous utilisons tous la forme _member. Et je pense que je
ne m'avance pas trop en disant que c'est la forme la plus populaire.
En fait, pour être tout à fait sûr il faudrait que le langage c++
standardise des namespaces de contexte comme dans certains langages
dynamiques:
- m::* pour désigner les noms membres
- g::* les globales
- a::* pour les arguments de fonction
> Les noms r serv s dans tous les namespaces sont ceux commen ant par un > underscore ouis une majuscule ou les noms ayant un double underscore.
Merci pour la pr cision. J'avais banni l'usage du leading undersco re depuis que j'avais appris que c' tait r serv dans certains cas. Ceci dit, a m'explique pourquoi ils utilisent _M_.* dans la STL fournie avec GCC.
Il me semble qu'il y a des cas où ça pourrait poser problème avec le C99 qui réserve plus de noms; je suppose que c'est dû à l'absence de namespace. Je crois que POSIX ajoute aussi sont lot de formes réservées.
En pratique, j'ai jamais vu ni entendu parler de problèmes lié à ça . Et c'est à mon avis une réserve pour pouvoir ajouter des noms réservés. Et si quelqu'un râle, qu'on puisse lui dire qu'il n'avait qu'à ne pas utiliser une forme réservée.
Ceci dit, je pense que c'est quand m me une bonne id e de ne pas utiliser tout les symboles commen ant par underscore. Vu que c'est r serv dans une port e supp rieure, on peut ventuellement avoir des probl mes de symbole cach .
Dans le contexte d'une fonction membre, je ne vois pas de cas problème. Peut être dans un cas de classe template où un two-phase lookup aurait dû être utiliser (i.e. utiliser this->_member) et que la variable globale est utilisé en lieu et place de la variable membre. C'est un risque assez vague.
AMA c'est plutôt une question de lisibilité. J'ai utilisé un temps la notation membre_; mais c'est vraiment laid (membre_->foo() ) et pas très lisible. J'ai vu certains utiliser m_member , mMember ou myMember. Le dernière forme étant peut être la plus explicite mais à un je ne sais quoi qui me déplait (peut être mon orgueil qui refuse d'utiliser des conventions d'amateur même si des gens aussi expérimentés que James Kanze l'utilisent :)
Au travaille, nous utilisons tous la forme _member. Et je pense que je ne m'avance pas trop en disant que c'est la forme la plus populaire.
En fait, pour être tout à fait sûr il faudrait que le langage c++ standardise des namespaces de contexte comme dans certains langages dynamiques: - m::* pour désigner les noms membres - g::* les globales - a::* pour les arguments de fonction