Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Acces à une méthode

8 réponses
Avatar
Philippe MESMEUR
Salut =E0 tous, j'ai un petit probl=E8me qui m'intrigue beaucoup.

Soit une classe A qui propose une m=E9thode publique void Set(int a) et
une classe B qui d=E9rive "publiquement" de A et propose elle aussi une
methode Set dont la signature est cette fois ci void Set().

Comment =E0 partir de B faire appel =E0 la m=E9thode Set de A??? Plus
pr=E9cis=E9ment, voici un exemple de test:

class A
{
public :
void Set(int a)
{
this->a =3D a;
}
protected :
int a;
};

class B: public A
{
protected:
void Set()
{
a =3D 0;
}
};


int main(int argc, char * argv[])
{
B b;
b.Set(10);
return 0;
}

voici ma ligne de compilation

g++ test2.cpp -o test
test2.cpp: In function `int main(int, char**)':
test2.cpp:28: error: no matching function for call to `B::Set(int)'
test2.cpp:20: note: candidates are: void B::Set()

Si dans mon main je remplace la ligne "b.Set(10);" par "((A) b).Set
(10);" =E7a compile bien.

Merci d'avance pour votre aide

8 réponses

Avatar
espie
In article ,
Philippe MESMEUR wrote:
Salut à tous, j'ai un petit problème qui m'intrigue beaucoup.

Soit une classe A qui propose une méthode publique void Set(int a) et
une classe B qui dérive "publiquement" de A et propose elle aussi une
methode Set dont la signature est cette fois ci void Set().

Comment à partir de B faire appel à la méthode Set de A??? Plus
précisément, voici un exemple de test:



C'est precisement a ca que sert using.

un

using A::Set;

a l'interieur de B te permettra de faire participer A::Set a la surcharge.
Avatar
Philippe MESMEUR
Merci beaucoup pour votre réponse, ça fait exactement ce que je
voulais! Maintenant, je cherche à bien comprendre ce qui ce passe ;-)

D'après ce que j'ai pu lire, quand le compilateur cherche les
candidats à la résolution d'un appel de fonction, il les cherche dans
un seul et unique contexte. Donc comme il trouve un candidat à l'appel
de la fonction "Set" dans le contexte de la classe B, il ne va pas
chercher plus loin, dans la classe A.

Maintenant, j'imagine que le "using A::Set;" indique au compilateur
que la fonction A::Set fait parti des candidats à la résolution des
appels B::Set().

Pouvez vous m'expliquer si c'est bien ça? Et si tel est le cas,
pourquoi avoir introduit (ce qui me semble être une limitation) ce
principe de recherche dans un unique contexte les candidats à la
résolution d'un appel fonction? Ca me parait étrange, blizzard,
saugrenu ;-) mais j'imagine bien qu'il y a une raison bien précise
derrière tout ça


On 22 juil, 14:49, (Marc Espie) wrote:
In article .com>,
Philippe MESMEUR   wrote:

>Salut à tous, j'ai un petit problème qui m'intrigue beaucoup.

>Soit une classe A qui propose une méthode publique void Set(int a) et
>une classe B qui dérive "publiquement" de A et propose elle aussi une
>methode Set dont la signature est cette fois ci void Set().

>Comment à partir de B faire appel à la méthode Set de A??? Plus
>précisément, voici un exemple de test:

C'est precisement a  ca que sert using.

un

using A::Set;

a l'interieur de B te permettra de faire participer A::Set a la surcharge .


Avatar
Lucas Levrel
Le 23 juillet 2009, Philippe MESMEUR a écrit :

Maintenant, j'imagine que le "using A::Set;" indique au compilateur
que la fonction A::Set fait parti des candidats à la résolution des
appels B::Set().

Pouvez vous m'expliquer si c'est bien ça? Et si tel est le cas,
pourquoi avoir introduit (ce qui me semble être une limitation) ce
principe de recherche dans un unique contexte les candidats à la
résolution d'un appel fonction? Ca me parait étrange, blizzard,
saugrenu ;-) mais j'imagine bien qu'il y a une raison bien précise
derrière tout ça



Peut-être au cas où tu veuilles définir un B::Set(int) différent de
A::Set(int) ?
--
LL
Avatar
Fabien LE LEZ
On Thu, 23 Jul 2009 01:28:56 -0700 (PDT), Philippe MESMEUR
:

Maintenant, j'imagine que le "using A::Set;" indique au compilateur
que la fonction A::Set fait parti des candidats à la résolution des
appels B::Set().

Pouvez vous m'expliquer si c'est bien ça? Et si tel est le cas,
pourquoi avoir introduit (ce qui me semble être une limitation) ce
principe de recherche dans un unique contexte les candidats à la
résolution d'un appel fonction?



Je pense que c'est le "principe de moindre surprise".

Imagine le cas suivant : tu crées une classe dérivée d'une classe
fournie par une bibliothèque.

class MaClasse: public Biblio
{
public:
void f (double);
};

int main()
{
MaClasse m;
m.f(3.14); // OK, MaClasse::f() est appelée
m.f(42); // ?
}

Dans le deuxième cas, tu t'aperçois d'un truc bizarre à l'exécution.
Après quelques efforts, tu as fini par trouver le problème :
MaClasse::f() n'est pas appelée. Ah ben pourquoi ?
Avec un peu de chance, tu vas penser à aller voir le .h fourni par la
bibliothèque et... Bah oui, "Biblio" contient une fonction
"void f(int)".

Je crois que c'est pour éviter ce genre de cas (voire des cas encore
plus tordus) que cette règle a été établie.
Avatar
Mickaël Wolff
Lucas Levrel a écrit :
Peut-être au cas où tu veuilles définir un B::Set(int) différent de
A::Set(int) ?



Je ne vois pas où tu veux en venir, puisque même si le compilateur
faisait la liste de toutes les fonctions membres héritées, B::Set(int)
serait bien celle utilisée dans le contexte d'une instance de B.
D'ailleurs, ça m'a toujours étonné cette résolution tronquée des
fonctions réécrites à travers l'héritage.

Je me demande si c'est volontaire, et ce qui a justifié cette décision.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Seeking for a position <http://lupusmic.org/pro/>
Avatar
Jean-Marc Bourguet
Mickaël Wolff writes:

Lucas Levrel a écrit :
Peut-être au cas où tu veuilles définir un B::Set(int) différent de
A::Set(int) ?



Je ne vois pas où tu veux en venir, puisque même si le compilateur
faisait la liste de toutes les fonctions membres héritées, B::Set(int)
serait bien celle utilisée dans le contexte d'une instance de
B. D'ailleurs, ça m'a toujours étonné cette résolution tronquée des
fonctions réécrites à travers l'héritage.

Je me demande si c'est volontaire, et ce qui a justifié cette décision.



Les classes sont des portées.

Une définition dans une portée masque les définitions dans les portées
englobantes.

En passant, c'est donc vrai aussi pour les namespaces même si on tombe
dessus moins souvent.

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Lucas Levrel
Le 24 juillet 2009, Jean-Marc Bourguet a écrit :

Une définition dans une portée masque les définitions dans les portées
englobantes.



OK. J'avais oublié ça, et comme j'évite de le faire je croyais que ça
gueulerait à la compilation (au moins un warning). Merci pour le rappel.

--
LL
Avatar
espie
Il y a aussi le fait, de maniere plus pratique, que private/public ne change
pas la visibilite, mais l'accessibilite. Donc si tu as une classe a laquelle
tu rajoutes une methode private A::set(int); que tu herites publiquement
de A dans B, et que B possede une methode B::set(long);
tu n'as pas envie que, d'un coup,

b.set('c');

devienne ambigu...