Chapitre 21 : Heritages 2

Jeudi 16 avril : entre 9h00 et 12h00 DST2 ?

Protected

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).

EXEMPLE
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

Conversion explicite

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*>.

EXEMPLE
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*.

Redéfinition de membres

On peut redéfinir des membres dans la classe héritée.

EXEMPLE
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