Ereditarietà multipla

Una estensione naturale del concetto di ereditarietà finora visto è quella di avere più di una classe padre. Per esempio, considerate un aeroplano: esso è un oggetto volante ma è anche un veicolo, perciò deve avere entrambe le caratteristiche.

Dichiarazione

Per indicare la relazione di ereditarietà multipla, basta aggiungere alla lista dei padri quelli che vuoi, ciascuno preceduto da una delle keyword public, protected o private (per la spiegazione dei vari tipi di ereditarietà ti rimando qui:
class father1
{
  int a;
};
class father2
{
  int b;
};
class Child : public father1, private father2
{
  int c;
};
Notare che l'ereditarietà semplice è semplicemente un caso particolare dell'ereditarietà multipla.

Problemi con l'ereditarietà multipla

Date un'occhiata a questo codice:
class GrandFather
{
protected:
  int a;
};
class Father1 : public GrandFather
{
protected:
  int b;
};
class Father2 : public GrandFather
{
protected:
  int c;
};
class Child : public Father1,
              public Father2
{
protected:
  int d;
  void foo();
};
La variabile a della classe GrandFather è ereditata da entrambe le classi Father1 e Father2. Quando viene creata la classe Child, avrà due distinte variabili a ereditate o una sola? Per default ne avrà due. Per indicare l'una o all'altra devi aggiungere Father1:: o Father2:: prima di riferirti alla variabile a.
void Child::foo()
{
  d = Father1::a;
// Oppure
  d = Father2::a;
}
Ma puoi anche far sì che nella classe Child le variabili a ereditate da Father1 e Father2 siano le stesse. Basta mettere la keyword virtual dopo la parola chiave public, protected o private, e nessun membro verrà duplicato. In questo modo puoi ridurre la quantità di memoria necessaria all'applicazione.
class GrandFather
{
protected:
  int a;
};

class Father1 : public GrandFather
{
protected:
  int b;
};

class Father2 : public GrandFather
{
protected:
  int c;
};

class Child : public virtual Father1,
              public virtual Father2
{
protected:
  int d;
  void foo();
};

void Child::foo()
{
  d = a;            // OK
  d = Father1::a;   // In questo caso è la stessa dell'istruzione precedente
  d = Father2::a;   // In questo caso è la stessa dell'istruzione precedente
}

C++