J'ai un problème simple à vous soumettre.
J'ai écrit une classe qui permet de gérer le parsing d'un fichier dans
un format spécifique (chargement, sauvegarde, lecture/écriture de
paramètres, etc).
Cette classe publique A encapsule une liste d'instances de classe B qui
représentent autant de sections de mon fichier.
Pour l'instant, ça ressemble à peu prés à ça :
class B
{
...
};
class A
{
private:
List<B*> m_sections;
};
Je souhaiterais que cette classe B ne soit pas publique.
Dois-je en faire une sous-classe de A ? Est-ce que ça ne risque pas de
gêner la lisibilité de mon source ?
Autre chose, comme je suis loin de maîtriser ne serait-ce qu'un centième
de ce merveilleuse langage qu'est le C++, je me pose également la
question de l'utilité de déclarer m_sections comme une list de B plutôt
que d'une liste de B*. Pour l'instant, je dois vider manuellement
m_sections à chaque fois que j'ai besoin de le réinitialiser.
Mais j'ai peur qu'en écrivant "List<B> m_sections;" je risque de
multiplier les instanciations et les recopies d'objets lorsque je
voudrais parcourir ma liste et en utiliser les éléments.
J'ai un problème simple à vous soumettre.
J'ai écrit une classe qui permet de gérer le parsing d'un fichier dans
un format spécifique (chargement, sauvegarde, lecture/écriture de
paramètres, etc).
Cette classe publique A encapsule une liste d'instances de classe B qui
représentent autant de sections de mon fichier.
Pour l'instant, ça ressemble à peu prés à ça :
class B
{
...
};
class A
{
private:
List<B*> m_sections;
};
Je souhaiterais que cette classe B ne soit pas publique.
Dois-je en faire une sous-classe de A ? Est-ce que ça ne risque pas de
gêner la lisibilité de mon source ?
Autre chose, comme je suis loin de maîtriser ne serait-ce qu'un centième
de ce merveilleuse langage qu'est le C++, je me pose également la
question de l'utilité de déclarer m_sections comme une list de B plutôt
que d'une liste de B*. Pour l'instant, je dois vider manuellement
m_sections à chaque fois que j'ai besoin de le réinitialiser.
Mais j'ai peur qu'en écrivant "List<B> m_sections;" je risque de
multiplier les instanciations et les recopies d'objets lorsque je
voudrais parcourir ma liste et en utiliser les éléments.
J'ai un problème simple à vous soumettre.
J'ai écrit une classe qui permet de gérer le parsing d'un fichier dans
un format spécifique (chargement, sauvegarde, lecture/écriture de
paramètres, etc).
Cette classe publique A encapsule une liste d'instances de classe B qui
représentent autant de sections de mon fichier.
Pour l'instant, ça ressemble à peu prés à ça :
class B
{
...
};
class A
{
private:
List<B*> m_sections;
};
Je souhaiterais que cette classe B ne soit pas publique.
Dois-je en faire une sous-classe de A ? Est-ce que ça ne risque pas de
gêner la lisibilité de mon source ?
Autre chose, comme je suis loin de maîtriser ne serait-ce qu'un centième
de ce merveilleuse langage qu'est le C++, je me pose également la
question de l'utilité de déclarer m_sections comme une list de B plutôt
que d'une liste de B*. Pour l'instant, je dois vider manuellement
m_sections à chaque fois que j'ai besoin de le réinitialiser.
Mais j'ai peur qu'en écrivant "List<B> m_sections;" je risque de
multiplier les instanciations et les recopies d'objets lorsque je
voudrais parcourir ma liste et en utiliser les éléments.
Bonsoir à tous !
J'ai un problème simple à vous soumettre.
J'ai écrit une classe qui permet de gérer le parsing d'un fichier dans un
format spécifique (chargement, sauvegarde, lecture/écriture de paramètres,
etc).
Cette classe publique A encapsule une liste d'instances de classe B qui
représentent autant de sections de mon fichier.
Pour l'instant, ça ressemble à peu prés à ça :
class B
{
...
};
class A
{
private:
List<B*> m_sections;
};
Je souhaiterais que cette classe B ne soit pas publique.
Dois-je en faire une sous-classe de A ? Est-ce que ça ne risque pas de
gêner la lisibilité de mon source ?
Autre chose, comme je suis loin de maîtriser ne serait-ce qu'un centième de
ce merveilleuse langage qu'est le C++, je me pose également la question de
l'utilité de déclarer m_sections comme une list de B plutôt que d'une liste
de B*. Pour l'instant, je dois vider manuellement m_sections à chaque fois
que j'ai besoin de le réinitialiser.
Bonsoir à tous !
J'ai un problème simple à vous soumettre.
J'ai écrit une classe qui permet de gérer le parsing d'un fichier dans un
format spécifique (chargement, sauvegarde, lecture/écriture de paramètres,
etc).
Cette classe publique A encapsule une liste d'instances de classe B qui
représentent autant de sections de mon fichier.
Pour l'instant, ça ressemble à peu prés à ça :
class B
{
...
};
class A
{
private:
List<B*> m_sections;
};
Je souhaiterais que cette classe B ne soit pas publique.
Dois-je en faire une sous-classe de A ? Est-ce que ça ne risque pas de
gêner la lisibilité de mon source ?
Autre chose, comme je suis loin de maîtriser ne serait-ce qu'un centième de
ce merveilleuse langage qu'est le C++, je me pose également la question de
l'utilité de déclarer m_sections comme une list de B plutôt que d'une liste
de B*. Pour l'instant, je dois vider manuellement m_sections à chaque fois
que j'ai besoin de le réinitialiser.
Bonsoir à tous !
J'ai un problème simple à vous soumettre.
J'ai écrit une classe qui permet de gérer le parsing d'un fichier dans un
format spécifique (chargement, sauvegarde, lecture/écriture de paramètres,
etc).
Cette classe publique A encapsule une liste d'instances de classe B qui
représentent autant de sections de mon fichier.
Pour l'instant, ça ressemble à peu prés à ça :
class B
{
...
};
class A
{
private:
List<B*> m_sections;
};
Je souhaiterais que cette classe B ne soit pas publique.
Dois-je en faire une sous-classe de A ? Est-ce que ça ne risque pas de
gêner la lisibilité de mon source ?
Autre chose, comme je suis loin de maîtriser ne serait-ce qu'un centième de
ce merveilleuse langage qu'est le C++, je me pose également la question de
l'utilité de déclarer m_sections comme une list de B plutôt que d'une liste
de B*. Pour l'instant, je dois vider manuellement m_sections à chaque fois
que j'ai besoin de le réinitialiser.
J'ai un problème simple à vous soumettre. J'ai écrit une
classe qui permet de gérer le parsing d'un fichier dans un
format spécifique (chargement, sauvegarde, lecture/écriture
de paramètres, etc).
Cette classe publique A encapsule une liste d'instances de
classe B qui représentent autant de sections de mon fichier.
Pour l'instant, ça ressemble à peu prés à ça :
class B
{
...
};
class A
{
private:
List<B*> m_sections;
};
Je souhaiterais que cette classe B ne soit pas publique.
class A {
class B {
friend class A;
}
std::list<B> m_sections;
public:
A(){};
}Dois-je en faire une sous-classe de A ? Est-ce que ça ne
risque pas de gêner la lisibilité de mon source ?
Lisibilité de ton source ?
Tu n'es pas obligé de mettre le code des méthodes de B dans
sa définition dans A.
Autre chose, comme je suis loin de maîtriser ne serait-ce
qu'un centième de ce merveilleuse langage qu'est le C++, je
me pose également la question de l'utilité de déclarer
m_sections comme une list de B plutôt que d'une liste de B*.
Pour l'instant, je dois vider manuellement m_sections à
chaque fois que j'ai besoin de le réinitialiser. Mais j'ai
peur qu'en écrivant "List<B> m_sections;" je risque de
multiplier les instanciations et les recopies d'objets
lorsque je voudrais parcourir ma liste et en utiliser les
éléments.
Puisque tu te dis débutant:
1) écrit un code correct, en laissant le compilo faire
le max de boulot (et entre autre vider ton m_section)
2) quand ça tournera, interroge toi sur les perfs.
En l'occurence, comme je ne connais pas List, il
m'est difficile de dire quoi que ce soit sur ce dont
tu parles.
Mais avec std::list et des accès par itérateurs,
non, à moins que tu le fasses exprès, il n'y a pas
de raison d'avoir moultes recopies inutiles.
J'ai un problème simple à vous soumettre. J'ai écrit une
classe qui permet de gérer le parsing d'un fichier dans un
format spécifique (chargement, sauvegarde, lecture/écriture
de paramètres, etc).
Cette classe publique A encapsule une liste d'instances de
classe B qui représentent autant de sections de mon fichier.
Pour l'instant, ça ressemble à peu prés à ça :
class B
{
...
};
class A
{
private:
List<B*> m_sections;
};
Je souhaiterais que cette classe B ne soit pas publique.
class A {
class B {
friend class A;
}
std::list<B> m_sections;
public:
A(){};
}
Dois-je en faire une sous-classe de A ? Est-ce que ça ne
risque pas de gêner la lisibilité de mon source ?
Lisibilité de ton source ?
Tu n'es pas obligé de mettre le code des méthodes de B dans
sa définition dans A.
Autre chose, comme je suis loin de maîtriser ne serait-ce
qu'un centième de ce merveilleuse langage qu'est le C++, je
me pose également la question de l'utilité de déclarer
m_sections comme une list de B plutôt que d'une liste de B*.
Pour l'instant, je dois vider manuellement m_sections à
chaque fois que j'ai besoin de le réinitialiser. Mais j'ai
peur qu'en écrivant "List<B> m_sections;" je risque de
multiplier les instanciations et les recopies d'objets
lorsque je voudrais parcourir ma liste et en utiliser les
éléments.
Puisque tu te dis débutant:
1) écrit un code correct, en laissant le compilo faire
le max de boulot (et entre autre vider ton m_section)
2) quand ça tournera, interroge toi sur les perfs.
En l'occurence, comme je ne connais pas List, il
m'est difficile de dire quoi que ce soit sur ce dont
tu parles.
Mais avec std::list et des accès par itérateurs,
non, à moins que tu le fasses exprès, il n'y a pas
de raison d'avoir moultes recopies inutiles.
J'ai un problème simple à vous soumettre. J'ai écrit une
classe qui permet de gérer le parsing d'un fichier dans un
format spécifique (chargement, sauvegarde, lecture/écriture
de paramètres, etc).
Cette classe publique A encapsule une liste d'instances de
classe B qui représentent autant de sections de mon fichier.
Pour l'instant, ça ressemble à peu prés à ça :
class B
{
...
};
class A
{
private:
List<B*> m_sections;
};
Je souhaiterais que cette classe B ne soit pas publique.
class A {
class B {
friend class A;
}
std::list<B> m_sections;
public:
A(){};
}Dois-je en faire une sous-classe de A ? Est-ce que ça ne
risque pas de gêner la lisibilité de mon source ?
Lisibilité de ton source ?
Tu n'es pas obligé de mettre le code des méthodes de B dans
sa définition dans A.
Autre chose, comme je suis loin de maîtriser ne serait-ce
qu'un centième de ce merveilleuse langage qu'est le C++, je
me pose également la question de l'utilité de déclarer
m_sections comme une list de B plutôt que d'une liste de B*.
Pour l'instant, je dois vider manuellement m_sections à
chaque fois que j'ai besoin de le réinitialiser. Mais j'ai
peur qu'en écrivant "List<B> m_sections;" je risque de
multiplier les instanciations et les recopies d'objets
lorsque je voudrais parcourir ma liste et en utiliser les
éléments.
Puisque tu te dis débutant:
1) écrit un code correct, en laissant le compilo faire
le max de boulot (et entre autre vider ton m_section)
2) quand ça tournera, interroge toi sur les perfs.
En l'occurence, comme je ne connais pas List, il
m'est difficile de dire quoi que ce soit sur ce dont
tu parles.
Mais avec std::list et des accès par itérateurs,
non, à moins que tu le fasses exprès, il n'y a pas
de raison d'avoir moultes recopies inutiles.
Il n'est même pas obligé à mettre la définition de la classe B
dans la classe A. Au moins s'il n'utilise que std::list<B*> --
la norme dit que std::list<B> a un comportement indéfini si B
est un type incomplet.
Il n'est même pas obligé à mettre la définition de la classe B
dans la classe A. Au moins s'il n'utilise que std::list<B*> --
la norme dit que std::list<B> a un comportement indéfini si B
est un type incomplet.
Il n'est même pas obligé à mettre la définition de la classe B
dans la classe A. Au moins s'il n'utilise que std::list<B*> --
la norme dit que std::list<B> a un comportement indéfini si B
est un type incomplet.
"kanze" writes:Il n'est même pas obligé à mettre la définition de la classe
B dans la classe A. Au moins s'il n'utilise que
std::list<B*> -- la norme dit que std::list<B> a un
comportement indéfini si B est un type incomplet.
Ah ?
gotw Item 27, Herb nous dit que l'instanciation de
std::list<B> ne requiert théoriquement pas à B d'être un type
complet -- même si certains compilateurs en éprouvent le
besoin.
A l'époque ou j'avais lu ça, j'avais été surpris. Mais l'ODR (
3.2 ), m'avait convaincu. Mais bon, vu les ramifications de ce
chapitre, il est largement probable que j'ai manqué le petit
alinéa décisif. Qu'en est il ?
"kanze" <kanze@gabi-soft.fr> writes:
Il n'est même pas obligé à mettre la définition de la classe
B dans la classe A. Au moins s'il n'utilise que
std::list<B*> -- la norme dit que std::list<B> a un
comportement indéfini si B est un type incomplet.
Ah ?
gotw Item 27, Herb nous dit que l'instanciation de
std::list<B> ne requiert théoriquement pas à B d'être un type
complet -- même si certains compilateurs en éprouvent le
besoin.
A l'époque ou j'avais lu ça, j'avais été surpris. Mais l'ODR (
3.2 ), m'avait convaincu. Mais bon, vu les ramifications de ce
chapitre, il est largement probable que j'ai manqué le petit
alinéa décisif. Qu'en est il ?
"kanze" writes:Il n'est même pas obligé à mettre la définition de la classe
B dans la classe A. Au moins s'il n'utilise que
std::list<B*> -- la norme dit que std::list<B> a un
comportement indéfini si B est un type incomplet.
Ah ?
gotw Item 27, Herb nous dit que l'instanciation de
std::list<B> ne requiert théoriquement pas à B d'être un type
complet -- même si certains compilateurs en éprouvent le
besoin.
A l'époque ou j'avais lu ça, j'avais été surpris. Mais l'ODR (
3.2 ), m'avait convaincu. Mais bon, vu les ramifications de ce
chapitre, il est largement probable que j'ai manqué le petit
alinéa décisif. Qu'en est il ?
Fabien CHÊNE wrote:"kanze" writes:Il n'est même pas obligé à mettre la définition de la classe
B dans la classe A. Au moins s'il n'utilise que
std::list<B*> -- la norme dit que std::list<B> a un
comportement indéfini si B est un type incomplet.
Ah ?
gotw Item 27, Herb nous dit que l'instanciation de
std::list<B> ne requiert théoriquement pas à B d'être un type
complet -- même si certains compilateurs en éprouvent le
besoin.
Tiens, je me serais attendu au contraire. La norme dit clairement
(§17.4.3.6/2) : « In particular, the effects are undefined in the
following cases: [...] -- if an incomplete type is used as a
template argument when instantiating a template component. » En
revanche, tant qu'on n'instantie que la définition de la classe (et
non les définitions de ses membres), j'imagine que ça passe sur la
quasi-totalité des implémentations.
Note que l'article de Herb que tu cites date de 1997. Avant la
norme, en fait. Je crois que le texte final était déjà étabil à
cette date, mais ce n'est pas dit que tout le monde l'avait déjà
lu en détail et s'en est rendu compte de toutes ses
implications. Si on considère l'implémentation SGI
(originalement HP) de la STL, et les spécifications exactes de
quand un compilateur doit instancier quoi dans les templates, il
n'y a pas de problème avec le type incomplet -- de même
qu'aujourd'hui, il marche en fait avec pratiquement toutes les
implémentations. En revanche, il y avait pas mal de compilateurs
alors qui instantiait toute la classe, y compris toutes les
fonctions membres, comme un ensemble. Ce qui poserait pas mal de
problèmes dans la pratique.A l'époque ou j'avais lu ça, j'avais été surpris. Mais l'ODR (
3.2 ), m'avait convaincu. Mais bon, vu les ramifications de ce
chapitre, il est largement probable que j'ai manqué le petit
alinéa décisif. Qu'en est il ?
La norme n'a pas cherché à délimiter sur chaque cas séparément.
Elle a pris la solution de faire une interdiction globale. C'est
donc un comportement indéfini. Dans la pratique, c'est un de ces
cas où si ça compile, ça marcherait.
Et aussi, ça compilera en fait, sauf dans les compilateurs anciens
qui instantient toutes les fonctions membre chaque fois qu'ils
instantient la classe. (Ce qui poserait d'autres problèmes aussi.)
Fabien CHÊNE wrote:
"kanze" <kanze@gabi-soft.fr> writes:
Il n'est même pas obligé à mettre la définition de la classe
B dans la classe A. Au moins s'il n'utilise que
std::list<B*> -- la norme dit que std::list<B> a un
comportement indéfini si B est un type incomplet.
Ah ?
gotw Item 27, Herb nous dit que l'instanciation de
std::list<B> ne requiert théoriquement pas à B d'être un type
complet -- même si certains compilateurs en éprouvent le
besoin.
Tiens, je me serais attendu au contraire. La norme dit clairement
(§17.4.3.6/2) : « In particular, the effects are undefined in the
following cases: [...] -- if an incomplete type is used as a
template argument when instantiating a template component. » En
revanche, tant qu'on n'instantie que la définition de la classe (et
non les définitions de ses membres), j'imagine que ça passe sur la
quasi-totalité des implémentations.
Note que l'article de Herb que tu cites date de 1997. Avant la
norme, en fait. Je crois que le texte final était déjà étabil à
cette date, mais ce n'est pas dit que tout le monde l'avait déjà
lu en détail et s'en est rendu compte de toutes ses
implications. Si on considère l'implémentation SGI
(originalement HP) de la STL, et les spécifications exactes de
quand un compilateur doit instancier quoi dans les templates, il
n'y a pas de problème avec le type incomplet -- de même
qu'aujourd'hui, il marche en fait avec pratiquement toutes les
implémentations. En revanche, il y avait pas mal de compilateurs
alors qui instantiait toute la classe, y compris toutes les
fonctions membres, comme un ensemble. Ce qui poserait pas mal de
problèmes dans la pratique.
A l'époque ou j'avais lu ça, j'avais été surpris. Mais l'ODR (
3.2 ), m'avait convaincu. Mais bon, vu les ramifications de ce
chapitre, il est largement probable que j'ai manqué le petit
alinéa décisif. Qu'en est il ?
La norme n'a pas cherché à délimiter sur chaque cas séparément.
Elle a pris la solution de faire une interdiction globale. C'est
donc un comportement indéfini. Dans la pratique, c'est un de ces
cas où si ça compile, ça marcherait.
Et aussi, ça compilera en fait, sauf dans les compilateurs anciens
qui instantient toutes les fonctions membre chaque fois qu'ils
instantient la classe. (Ce qui poserait d'autres problèmes aussi.)
Fabien CHÊNE wrote:"kanze" writes:Il n'est même pas obligé à mettre la définition de la classe
B dans la classe A. Au moins s'il n'utilise que
std::list<B*> -- la norme dit que std::list<B> a un
comportement indéfini si B est un type incomplet.
Ah ?
gotw Item 27, Herb nous dit que l'instanciation de
std::list<B> ne requiert théoriquement pas à B d'être un type
complet -- même si certains compilateurs en éprouvent le
besoin.
Tiens, je me serais attendu au contraire. La norme dit clairement
(§17.4.3.6/2) : « In particular, the effects are undefined in the
following cases: [...] -- if an incomplete type is used as a
template argument when instantiating a template component. » En
revanche, tant qu'on n'instantie que la définition de la classe (et
non les définitions de ses membres), j'imagine que ça passe sur la
quasi-totalité des implémentations.
Note que l'article de Herb que tu cites date de 1997. Avant la
norme, en fait. Je crois que le texte final était déjà étabil à
cette date, mais ce n'est pas dit que tout le monde l'avait déjà
lu en détail et s'en est rendu compte de toutes ses
implications. Si on considère l'implémentation SGI
(originalement HP) de la STL, et les spécifications exactes de
quand un compilateur doit instancier quoi dans les templates, il
n'y a pas de problème avec le type incomplet -- de même
qu'aujourd'hui, il marche en fait avec pratiquement toutes les
implémentations. En revanche, il y avait pas mal de compilateurs
alors qui instantiait toute la classe, y compris toutes les
fonctions membres, comme un ensemble. Ce qui poserait pas mal de
problèmes dans la pratique.A l'époque ou j'avais lu ça, j'avais été surpris. Mais l'ODR (
3.2 ), m'avait convaincu. Mais bon, vu les ramifications de ce
chapitre, il est largement probable que j'ai manqué le petit
alinéa décisif. Qu'en est il ?
La norme n'a pas cherché à délimiter sur chaque cas séparément.
Elle a pris la solution de faire une interdiction globale. C'est
donc un comportement indéfini. Dans la pratique, c'est un de ces
cas où si ça compile, ça marcherait.
Et aussi, ça compilera en fait, sauf dans les compilateurs anciens
qui instantient toutes les fonctions membre chaque fois qu'ils
instantient la classe. (Ce qui poserait d'autres problèmes aussi.)