Le C++ traite l'héritage comme un problème de porter de noms et commence par associer un nom à sa définition. Les problèmes de typage et de contrôle d'accès ne viendront qu'après. D'autre part, rien n'interdit à une classe d'utiliser un nom déjà utilisé dans une de ces classes de base, dans ce cas elle occulte les définitions présentes dans les classe de base.
class A{ int a; public : void f(); int g(); }; class B: public A{ int a; // cache A::a public : int f(int); // cache A::f }; class B b;Le nom
b.a
sera associé à la définition de la classe B
;
la déclaration de int a;
dans la classe B
occulte la déclaration
de int a;
dans la classe de base A
.
Attention il s'agit
uniquement d'un problème de portée : la donnée membre A::a
existe
toujours pour l'objet b
, et d'ailleurs le nom b.A::a
lui sera
associée, et l'objet b
aura deux données membres A::a
et
a
(ou B::a
), il se trouve par ailleurs, dans cet exemple, que
l'objet b
n'a pas le droit d'accéder à A::a
, mais c'est un autre
problème.
De même, b.f(3)
sera associé à int B::f(int)
. Cette déclaration
occulte le nom f
, et donc pour le compilateur il n'existera pas de
définition de fonction pouvant correspondre à b.f()
, alors que, bien sûr,
a.A::f()
sera associé à la définition de void f(void)
dans la
classe A
.
Enfin, b.g()
sera associé à int g()
de la classe de base
A
.