Bonjour à tous,
je cherche à appeler explicitement la version const d'une fonction membre.
C'est un cas un peu tordu que je résume ici:
J'ai 2 classes abstraites A et B, A utilise B, mais B est fournie par une
classe fille de A:
class B
{
public:
virtual string GetName() const = 0;
};
class A
{
public:
string GetName() const
{
return this->GetB().GetName();
}
protected:
virtual B & GetB() = 0;
};
GetB() est la fonction que les classes filles doivent supplanter afin de
fournir un B à A. Ok ? Bien.
Dans l'exemple ci-dessus, const GetName() qui appelle non const GetB() ne
vous aura pas échappé. Et voilà mon problème. Actuellement je contourne ça
ainsi :
protected:
virtual B & GetB() = 0;
virtual const B & GetB() const = 0;
};
Mais j'aimerais bien arriver à frabriquer l'accesseur const à partir du non
const et ainsi réduire le nombre de fonctions virtuelles pures (qui sont
identiques ici vu de la classe fille). Est-ce possible (propement, sans
const_cast, à moins qu'il soit justifié) ?
Merci.
class A { public: B* getB() {return doGetB();} B const *getB() const {return doGetB();} private: virtual B* doGetB() const = 0; };
class A1 : public A { private: virtual B* doGetB() const {return myB;} B *myB; };
int main() { A* a = new A1; A const * ac = new A1; B* b = a->getB(); B const *bc = ac->getB(); }
Sauf que dans mon cas A1 ne détient pas un pointeur:
class A1 : public A { private: virtual B* doGetB() const {return &myB;} B myB; };
erreur C2440 : Tu croyais pas que ça allait marcher quand même ?
Jepense me rabattre sur mon idée initiale : fournir une référence au constrcuteur :
class B{};
class A { public: A( B & b ) : b( b ) {}
B & getB() {return this->b;} B const & getB() const {return this->b;}
private: B & b; };
class A1 : public A { public: A1() : A( myB ) {}
private: B myB; };
Je me paye un warning comme quoi l'opérateur d'assignation n'a pas pu être généré :/ Je vais passer par un pointeur du coup.
J'avais pas noté le private doGetB dans ton exemple. C'est marrant ça, on peut supplanter une fonction virtuelle private. Ca brise pas un peu le rôle de private ça ? D'un côte si on met virtual c'est qu'on le cherche, mais... Je suppose que c'est valable pour les virtuelle pures non implémentées ne pouvant de toute façon pas être appelées depuis les classes filles donc on met private dans ces cas là ?
-- Aurélien REGAT-BARREL
Le code suivant compile :
class B{};
class A
{
public:
B* getB() {return doGetB();}
B const *getB() const {return doGetB();}
private:
virtual B* doGetB() const = 0;
};
class A1 : public A
{
private:
virtual B* doGetB() const {return myB;}
B *myB;
};
int main()
{
A* a = new A1;
A const * ac = new A1;
B* b = a->getB();
B const *bc = ac->getB();
}
Sauf que dans mon cas A1 ne détient pas un pointeur:
class A1 : public A
{
private:
virtual B* doGetB() const {return &myB;}
B myB;
};
erreur C2440 : Tu croyais pas que ça allait marcher quand même ?
Jepense me rabattre sur mon idée initiale : fournir une référence au
constrcuteur :
class B{};
class A
{
public:
A( B & b ) : b( b ) {}
B & getB() {return this->b;}
B const & getB() const {return this->b;}
private:
B & b;
};
class A1 : public A
{
public:
A1() : A( myB ) {}
private:
B myB;
};
Je me paye un warning comme quoi l'opérateur d'assignation n'a pas pu être
généré :/
Je vais passer par un pointeur du coup.
J'avais pas noté le private doGetB dans ton exemple. C'est marrant ça, on
peut supplanter une fonction virtuelle private. Ca brise pas un peu le rôle
de private ça ? D'un côte si on met virtual c'est qu'on le cherche, mais...
Je suppose que c'est valable pour les virtuelle pures non implémentées ne
pouvant de toute façon pas être appelées depuis les classes filles donc on
met private dans ces cas là ?
class A { public: B* getB() {return doGetB();} B const *getB() const {return doGetB();} private: virtual B* doGetB() const = 0; };
class A1 : public A { private: virtual B* doGetB() const {return myB;} B *myB; };
int main() { A* a = new A1; A const * ac = new A1; B* b = a->getB(); B const *bc = ac->getB(); }
Sauf que dans mon cas A1 ne détient pas un pointeur:
class A1 : public A { private: virtual B* doGetB() const {return &myB;} B myB; };
erreur C2440 : Tu croyais pas que ça allait marcher quand même ?
Jepense me rabattre sur mon idée initiale : fournir une référence au constrcuteur :
class B{};
class A { public: A( B & b ) : b( b ) {}
B & getB() {return this->b;} B const & getB() const {return this->b;}
private: B & b; };
class A1 : public A { public: A1() : A( myB ) {}
private: B myB; };
Je me paye un warning comme quoi l'opérateur d'assignation n'a pas pu être généré :/ Je vais passer par un pointeur du coup.
J'avais pas noté le private doGetB dans ton exemple. C'est marrant ça, on peut supplanter une fonction virtuelle private. Ca brise pas un peu le rôle de private ça ? D'un côte si on met virtual c'est qu'on le cherche, mais... Je suppose que c'est valable pour les virtuelle pures non implémentées ne pouvant de toute façon pas être appelées depuis les classes filles donc on met private dans ces cas là ?
-- Aurélien REGAT-BARREL
drkm
"Aurélien REGAT-BARREL" writes:
Sauf que dans mon cas A1 ne détient pas un pointeur:
class A1 : public A { private: virtual B* doGetB() const {return &myB;} B myB; };
erreur C2440 : Tu croyais pas que ça allait marcher quand même ?
Sauf que dans mon cas A1 ne détient pas un pointeur:
class A1 : public A { private: virtual B* doGetB() const {return &myB;} B myB; };
erreur C2440 : Tu croyais pas que ça allait marcher quand même ?
Donc, tu veux modifier un objet constant ?
--drkm
Loïc Joly
Aurélien REGAT-BARREL wrote: [...]
Sauf que dans mon cas A1 ne détient pas un pointeur:
class A1 : public A { private: virtual B* doGetB() const {return &myB;} B myB; };
Et A1 n'est pas modifiable (je parle de son code source, pas d'un A1 const ;)) ? J'avais cru que si...
[...]
erreur C2440 : Tu croyais pas que ça allait marcher quand même ?
Ils sont sympas, les messages d'erreur de ton compilo.. ;)
J'avais pas noté le private doGetB dans ton exemple. C'est marrant ça, on peut supplanter une fonction virtuelle private. Ca brise pas un peu le rôle de private ça ? D'un côte si on met virtual c'est qu'on le cherche, mais... Je suppose que c'est valable pour les virtuelle pures non implémentées ne pouvant de toute façon pas être appelées depuis les classes filles donc on met private dans ces cas là ?
Vi, et ce cas là est le cas le plus courant d'une fonction virtuelle. L'idiome, qui permet de faire du design by contract en C++, est d'ailleur assez cher à James.
Pour plus d'info, lire par exemple : http://www.gotw.ca/publications/mill18.htm
-- Loïc
Aurélien REGAT-BARREL wrote:
[...]
Sauf que dans mon cas A1 ne détient pas un pointeur:
class A1 : public A
{
private:
virtual B* doGetB() const {return &myB;}
B myB;
};
Et A1 n'est pas modifiable (je parle de son code source, pas d'un A1
const ;)) ? J'avais cru que si...
[...]
erreur C2440 : Tu croyais pas que ça allait marcher quand même ?
Ils sont sympas, les messages d'erreur de ton compilo.. ;)
J'avais pas noté le private doGetB dans ton exemple. C'est marrant ça, on
peut supplanter une fonction virtuelle private. Ca brise pas un peu le rôle
de private ça ? D'un côte si on met virtual c'est qu'on le cherche, mais...
Je suppose que c'est valable pour les virtuelle pures non implémentées ne
pouvant de toute façon pas être appelées depuis les classes filles donc on
met private dans ces cas là ?
Vi, et ce cas là est le cas le plus courant d'une fonction virtuelle.
L'idiome, qui permet de faire du design by contract en C++, est
d'ailleur assez cher à James.
Pour plus d'info, lire par exemple :
http://www.gotw.ca/publications/mill18.htm
Sauf que dans mon cas A1 ne détient pas un pointeur:
class A1 : public A { private: virtual B* doGetB() const {return &myB;} B myB; };
Et A1 n'est pas modifiable (je parle de son code source, pas d'un A1 const ;)) ? J'avais cru que si...
[...]
erreur C2440 : Tu croyais pas que ça allait marcher quand même ?
Ils sont sympas, les messages d'erreur de ton compilo.. ;)
J'avais pas noté le private doGetB dans ton exemple. C'est marrant ça, on peut supplanter une fonction virtuelle private. Ca brise pas un peu le rôle de private ça ? D'un côte si on met virtual c'est qu'on le cherche, mais... Je suppose que c'est valable pour les virtuelle pures non implémentées ne pouvant de toute façon pas être appelées depuis les classes filles donc on met private dans ces cas là ?
Vi, et ce cas là est le cas le plus courant d'une fonction virtuelle. L'idiome, qui permet de faire du design by contract en C++, est d'ailleur assez cher à James.
Pour plus d'info, lire par exemple : http://www.gotw.ca/publications/mill18.htm
-- Loïc
Aurelien REGAT-BARREL
Vi, et ce cas là est le cas le plus courant d'une fonction virtuelle. L'idiome, qui permet de faire du design by contract en C++, est d'ailleur assez cher à James.
Pour plus d'info, lire par exemple : http://www.gotw.ca/publications/mill18.htm
Ok merci j'irai lire ça.
-- Aurélien REGAT-BARREL
Vi, et ce cas là est le cas le plus courant d'une fonction virtuelle.
L'idiome, qui permet de faire du design by contract en C++, est d'ailleur
assez cher à James.
Pour plus d'info, lire par exemple :
http://www.gotw.ca/publications/mill18.htm
Vi, et ce cas là est le cas le plus courant d'une fonction virtuelle. L'idiome, qui permet de faire du design by contract en C++, est d'ailleur assez cher à James.
Pour plus d'info, lire par exemple : http://www.gotw.ca/publications/mill18.htm