J'ai un problème de compréhension de l'usage du mot-clé const.
J'ai une classe qui possède un pointeur, ou des pointeurs, vers des objets.
Pour éviter les risques de fuite mémoire, je voudrais que ce soit toujours
cette classe qui alloue et désalloue ses pointeurs, et non l'utilisateur de
la classe. En revanche, l'utilisateur peut avoir besoin d'agir sur l'objet
pointé. Donc il faut que j'ai une méthode "get" retournant ce pointeur.
Mais, je veux que l'utilisateur ne puisse pas libérer le pointeur, le
modifier etc, mais doit quand même pouvoir appeler des méthodes non const
de l'objet pointé ! Je ne sais donc pas quelle syntaxe je dois utiliser.
Exemple :
class Bar;
class Foo {
public:
Bar* getBar() { return m_bar };
private:
Bar* m_bar;
}
Au niveau de la méthode getBar(), j'imagine que je dois placer un mot-clé
const, mais je ne sais pas comment !
En bref, j'ai vraiment du mal à saisir les différences entre les différentes
syntaxes.
Corrigez-moi si je me trompe :
// Le pointeur est constant, on peut appeler des méthodes non const de
l'objet pointé ?
const Bar* getBar()
// idem ?
Bar const* getBar()
// Le pointeur n'est pas constant, mais l'objet si ? Donc je ne peut pas
appeler de méthodes non const, mais je peux faire pointer ce pointeur sur
autre chose ?
Bar* const getBar()
Merci d'avance pour votre aide précieuse, même si je me doute bien que cette
question a déjà été posée 100 fois. Pourtant, j'ai cherché sur le net, mais
j'ai vraiment du mal à comprendre... Je manque certainement de pratique.
--
Hamiral
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Franck Branjonneau
Hamiral écrivait:
J'ai un problème de compréhension de l'usage du mot-clé const.
Merci d'avance pour votre aide précieuse, même si je me doute bien que cette question a déjà été posée 100 fois. Pourtant, j'ai cherché sur le net, mais j'ai vraiment du mal à comprendre... Je manque certainement de pratique.
[18.5] Quelle est la différence entre "const Fred* p", "Fred * const p", et "const Fred * const p"?
devrait répondre à tes interrogations.
Pourquoi retourner un pointeur (autrement dit pourquoi pas une référence) ?
Pourquoi retourner un pointeur const (un Bar * const) ? (« Pour m'éviter de le "deleter". » me diras-tu. As tu essayer ?) (<http://www.gotw.ca/gotw/006.htm> te diras pourquoi retourner un objet constant)
As-tu réfléchis à la copie et à l'affectation de Foo ?
-- Franck Branjonneau
Hamiral <hamiral@hamham.fr> écrivait:
J'ai un problème de compréhension de l'usage du mot-clé const.
Merci d'avance pour votre aide précieuse, même si je me doute bien
que cette question a déjà été posée 100 fois. Pourtant, j'ai cherché
sur le net, mais j'ai vraiment du mal à comprendre... Je manque
certainement de pratique.
[18.5] Quelle est la différence entre "const Fred* p", "Fred * const
p", et "const Fred * const p"?
devrait répondre à tes interrogations.
Pourquoi retourner un pointeur (autrement dit pourquoi pas une
référence) ?
Pourquoi retourner un pointeur const (un Bar * const) ? (« Pour
m'éviter de le "deleter". » me diras-tu. As tu essayer ?)
(<http://www.gotw.ca/gotw/006.htm> te diras pourquoi retourner
un objet constant)
As-tu réfléchis à la copie et à l'affectation de Foo ?
J'ai un problème de compréhension de l'usage du mot-clé const.
Merci d'avance pour votre aide précieuse, même si je me doute bien que cette question a déjà été posée 100 fois. Pourtant, j'ai cherché sur le net, mais j'ai vraiment du mal à comprendre... Je manque certainement de pratique.
[18.5] Quelle est la différence entre "const Fred* p", "Fred * const p", et "const Fred * const p"?
devrait répondre à tes interrogations.
Pourquoi retourner un pointeur (autrement dit pourquoi pas une référence) ?
Pourquoi retourner un pointeur const (un Bar * const) ? (« Pour m'éviter de le "deleter". » me diras-tu. As tu essayer ?) (<http://www.gotw.ca/gotw/006.htm> te diras pourquoi retourner un objet constant)
As-tu réfléchis à la copie et à l'affectation de Foo ?
C'est probablement ce que je ferais (avec la version const). L'utilisateur a la permission d'utiliser l'instance de Bar et il ignore qu'elle est gérée avec un pointeur. Cela ne l'empêchera pas pour autant de faire un delete & foo.getBar().
-- Franck Branjonneau
Hamiral <hamiral@hamham.fr> écrivait:
Donc, si je définis ma méthode ainsi :
Bar& Foo:getBar() {
return *m_bar;
}
Cela résoud mon problème ?
C'est probablement ce que je ferais (avec la version
const). L'utilisateur a la permission d'utiliser l'instance de Bar et
il ignore qu'elle est gérée avec un pointeur. Cela ne l'empêchera pas
pour autant de faire un delete & foo.getBar().
C'est probablement ce que je ferais (avec la version const). L'utilisateur a la permission d'utiliser l'instance de Bar et il ignore qu'elle est gérée avec un pointeur. Cela ne l'empêchera pas pour autant de faire un delete & foo.getBar().
-- Franck Branjonneau
Hamiral
Franck Branjonneau wrote:
Cela ne l'empêchera pas pour autant de faire un delete & foo.getBar().
Argh ! Mais il n'existe pas un moyen pour empêcher l'utilisateur de détruire cet objet ???
-- Hamiral, qui pense qu'il va devoir se contenter d'un bon commentaire (nécessaire mais pas suffisant)
Franck Branjonneau wrote:
Cela ne l'empêchera pas
pour autant de faire un delete & foo.getBar().
Argh !
Mais il n'existe pas un moyen pour empêcher l'utilisateur de détruire cet
objet ???
--
Hamiral, qui pense qu'il va devoir se contenter d'un bon commentaire
(nécessaire mais pas suffisant)
Cela ne l'empêchera pas pour autant de faire un delete & foo.getBar().
Argh ! Mais il n'existe pas un moyen pour empêcher l'utilisateur de détruire cet objet ???
Oui, il n'y a pas moyen d'empêcher l'utilisateur de détruire cet objet.
-- Hamiral, qui pense qu'il va devoir se contenter d'un bon commentaire (nécessaire mais pas suffisant)
Vraiment ? Tes utilisateurs sont si mal éduqués ?
-- Franck, don't cancel my post (sic)
Pierre Barbier de Reuille
Franck Branjonneau wrote:
Cela ne l'empêchera pas pour autant de faire un delete & foo.getBar().
Argh ! Mais il n'existe pas un moyen pour empêcher l'utilisateur de détruire cet objet ???
Non, mais utiliser l'opérateur delete sur une référence renvoyée est suicidaire de la part de l'utilisateur ... En C++, on considère que le programmeur ne fait pas complètement n'importe quoi (même si ça arrive ;) ).
Pierre
Franck Branjonneau wrote:
Cela ne l'empêchera pas
pour autant de faire un delete & foo.getBar().
Argh !
Mais il n'existe pas un moyen pour empêcher l'utilisateur de détruire cet
objet ???
Non, mais utiliser l'opérateur delete sur une référence renvoyée est
suicidaire de la part de l'utilisateur ... En C++, on considère que le
programmeur ne fait pas complètement n'importe quoi (même si ça arrive ;) ).
Cela ne l'empêchera pas pour autant de faire un delete & foo.getBar().
Argh ! Mais il n'existe pas un moyen pour empêcher l'utilisateur de détruire cet objet ???
Non, mais utiliser l'opérateur delete sur une référence renvoyée est suicidaire de la part de l'utilisateur ... En C++, on considère que le programmeur ne fait pas complètement n'importe quoi (même si ça arrive ;) ).
Pierre
Hamiral
Franck Branjonneau wrote:
Oui, il n'y a pas moyen d'empêcher l'utilisateur de détruire cet objet.
Bon, tant pis. Je vais faire avec (ou plutôt sans).
-- Hamiral, qui pense qu'il va devoir se contenter d'un bon commentaire (nécessaire mais pas suffisant)
Vraiment ? Tes utilisateurs sont si mal éduqués ?
Eh bien, en l'occurrence je serai mon propre utilisateur :) Mais je cherchais surtout à mettre en place le meilleur mécanisme possible.
-- Hamiral
Franck Branjonneau wrote:
Oui, il n'y a pas moyen d'empêcher l'utilisateur de détruire cet
objet.
Bon, tant pis. Je vais faire avec (ou plutôt sans).
--
Hamiral, qui pense qu'il va devoir se contenter d'un bon commentaire
(nécessaire mais pas suffisant)
Vraiment ? Tes utilisateurs sont si mal éduqués ?
Eh bien, en l'occurrence je serai mon propre utilisateur :)
Mais je cherchais surtout à mettre en place le meilleur mécanisme possible.
Oui, il n'y a pas moyen d'empêcher l'utilisateur de détruire cet objet.
Bon, tant pis. Je vais faire avec (ou plutôt sans).
-- Hamiral, qui pense qu'il va devoir se contenter d'un bon commentaire (nécessaire mais pas suffisant)
Vraiment ? Tes utilisateurs sont si mal éduqués ?
Eh bien, en l'occurrence je serai mon propre utilisateur :) Mais je cherchais surtout à mettre en place le meilleur mécanisme possible.
-- Hamiral
Sylvain
Hamiral wrote on 15/09/2006 22:14:
Franck Branjonneau wrote:
Cela ne l'empêchera pas pour autant de faire un delete & foo.getBar().
Mais il n'existe pas un moyen pour empêcher l'utilisateur de détruire cet objet ???
si, en ayant un destructeur interdit d'accès:
class Bar { private: ~Bar() {} public: Bar() {} friend class Foo; };
le destructeur de Bar ("~Bar()") sera private si la classe Bar est réputée finale et protected (et virtual) dans le cas contraire. l'important est que Foo soit amie.
class Foo { private: Bar* bar; public: Foo() { // sera chargé d'instancier bar = new Bar; } ~Foo() {// sera chargé de libérer delete bar; } Bar& getBar(){ return *bar; } };
Cela ne l'empêchera pas
pour autant de faire un delete & foo.getBar().
Mais il n'existe pas un moyen pour empêcher l'utilisateur de détruire cet
objet ???
si, en ayant un destructeur interdit d'accès:
class Bar {
private:
~Bar() {}
public:
Bar() {}
friend class Foo;
};
le destructeur de Bar ("~Bar()") sera private si la classe Bar est
réputée finale et protected (et virtual) dans le cas contraire.
l'important est que Foo soit amie.
class Foo {
private:
Bar* bar;
public:
Foo() { // sera chargé d'instancier
bar = new Bar;
}
~Foo() {// sera chargé de libérer
delete bar;
}
Bar& getBar(){
return *bar;
}
};
Cela ne l'empêchera pas pour autant de faire un delete & foo.getBar().
Mais il n'existe pas un moyen pour empêcher l'utilisateur de détruire cet objet ???
si, en ayant un destructeur interdit d'accès:
class Bar { private: ~Bar() {} public: Bar() {} friend class Foo; };
le destructeur de Bar ("~Bar()") sera private si la classe Bar est réputée finale et protected (et virtual) dans le cas contraire. l'important est que Foo soit amie.
class Foo { private: Bar* bar; public: Foo() { // sera chargé d'instancier bar = new Bar; } ~Foo() {// sera chargé de libérer delete bar; } Bar& getBar(){ return *bar; } };