Acces à une méthode

Le
Philippe MESMEUR
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:

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

class B: public A
{
protected:
void Set()
{
a = 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);" ça compile bien.

Merci d'avance pour votre aide
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
espie
Le #19807161
In article Philippe MESMEUR
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.
Philippe MESMEUR
Le #19812111
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 Philippe MESMEUR  
>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 .


Lucas Levrel
Le #19813171
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
Fabien LE LEZ
Le #19814891
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.
Mickaël Wolff
Le #19819891
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
Jean-Marc Bourguet
Le #19820051
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.



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
Lucas Levrel
Le #19820791
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
espie
Le #19821181
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...
Publicité
Poster une réponse
Anonyme