Lorsque vous appelez a.foo();
, le compilateur passe par la résolution de surcharge pour trouver la meilleure fonction à utiliser. Lorsqu'il construit l'ensemble de surcharge, il trouve
void foo() const
et
void foo()
Maintenant, puisque a
n'est pas const
, la version non-const est la meilleure correspondance, alors le compilateur choisit void foo()
. Ensuite, les restrictions d'accès sont mises en place et vous obtenez une erreur du compilateur, car void foo()
est privée.
N'oubliez pas, dans la résolution de surcharge, il ne s'agit pas de 'trouver la meilleure fonction utilisable'. Il s'agit de 'trouver la meilleure fonction et essayer de l'utiliser'. Si cela ne peut pas se faire en raison de restrictions d'accès ou d'une suppression, alors vous obtenez une erreur du compilateur.
En d'autres termes, pourquoi la résolution de surcharge vient avant le contrôle d'accès?
Eh bien, examinons :
struct Base
{
void foo() { std::cout << "Base\n"; }
};
struct Derived : Base
{
void foo() { std::cout << "Derived\n"; }
};
struct Foo
{
void foo(Base * b) { b->foo(); }
private:
void foo(Derived * d) { d->foo(); }
};
int main()
{
Derived d;
Foo f;
f.foo(&d);
}
Imaginons maintenant que je n'avais pas réellement l'intention de rendre void foo(Derived * d)
privée. Si le contrôle d'accès passait en premier, alors ce programme se compilerait et s'exécuterait et Base
serait imprimé. Cela pourrait être très difficile à repérer dans une grande base de code. Comme le contrôle d'accès vient après la résolution de surcharge, j'obtiens une belle erreur du compilateur me disant que la fonction que je veux appeler ne peut pas être appelée, et je peux trouver le bug beaucoup plus facilement.
3 votes
En C++, sans effort supplémentaire comme l'utilisation de l'idiome PIMPL, il n'existe pas de véritable partie "privée" de la classe. C'est juste l'un des problèmes (ajouter une surcharge de méthode "privée" et casser la compilation du code ancien compte comme un problème à mes yeux, même si celui-ci est trivial à éviter en ne le faisant tout simplement pas) causés par cela.
0 votes
Est-ce qu'il existe un code du monde réel où l'on s'attend à pouvoir appeler une fonction constante mais que sa contrepartie non-constante serait partie de l'interface privée ? Cela me semble être une mauvaise conception d'interface.
0 votes
Cela répond-il à votre question? Sur un objet non-constant, pourquoi C++ n'appelle-t-il pas la version constante d'une méthode avec des surcharges public-const et private-nonconst?