Jeudi 16 avril : entre 9h00 et 12h00 DST2 ?
Un membre (méthode ou attribut) qualifié de protected est accessible dans les méthodes des classes héritées mais inaccessible ailleurs (lors d'un héritage public).
class A{
private:
int pri;
public:
int pu;
protected:
int pro;
}
class B: public A{
void A(){
//pri=1; //erreur
pu = 2; //ok
pro = 3; //ok
}
}
int main(){
A objet;
objet.pu; //0
//objet.pri; //erreur
//objet.pro; //erreur
}
Il existe d'autres qualificatifs d'héritage en plus de public.
| MEMBRES | public | protected | private | |
|---|---|---|---|---|
| HERITAGE | ||||
| public | public | protected | inaccessible | |
| private | private | private | inaccessible | |
| protected | protected | protected | inaccessible |
Si B hérite de A alors il y a une conversion implicite du type B* vers A*. Pour expliciter une conversion de A* vers B* on peut utiliser dynamic_cast<B*>.
class A{...};
class B : public A{...};
int main(){
A objA;
B objB;
A* pA = &obj B; //ok
A& rA = objB; //ok
//B* pB = &objA; //erreur
//B& rB = objA; //erreur
//B* pB2 = pA; //erreur (meme si l'objet pointé par pA est de type B)
B* pB3 = dynamic_cast<B*>(pA); //ok
B* pB4 = dynamic_cast<B*>(&objA); //ok mais renvoie nullptr
B& rB = dynamic_cast<B&>(*pA); //ok
}
Si expr pointe sur un objet de type B, alors dynamic_cast renvoie la valeur de expr (de type B*)
Sinon dynamic_cast renvoie la valeur nullptr de type B*.
On peut redéfinir des membres dans la classe héritée.
struct A{
int a = 1;
int b = 2;
void f(){cout << "A::f()" << endl;}
void g(){cout << "A::g()" << endl;}
void h(){cout << "A::h()" << endl;}
void t(){cout << "A::t()" << endl;}
void t(int){cout << "A::t(i)" << endl;}
}
struct B : public A{
int b = 3;
using A::t;
void g(){cout << "B::g" << endl;} //redefinition de g
void h(int){cout << "B::hi << endl;} //redefinition de h
void t(){cout << B::t << endl;} // redefinition de t
};
int main(){
B objB;
objB.b; //vaut 3
objB.A::b; //vaut 2
objB.A::g(); //A::g
objB.g(); //B::g
objB.f(); //A::f
obj.h(3); B::hi
obj.t(); //B::t
//obj.h(); //erreur : B::h(int) "efface" le A::h()
//obj.t(3); //ok grâce à using A::t
objB.A::h() //ok