C++ Eredità


Esempio

Le classi / le strutture possono avere relazioni di ereditarietà.

Se una classe / struct B eredita da una classe / struct A , ciò significa che B ha come padre A Diciamo che B è una classe / struct derivata da A , e A è la classe base / struct.

struct A
{
public:
    int p1;
protected:
    int p2;
private:
    int p3;
};

//Make B inherit publicly (default) from A
struct B : A
{
};

Esistono 3 forme di ereditarietà per una classe / struttura:

  • public
  • private
  • protected

Si noti che l'ereditarietà predefinita è la stessa della visibilità predefinita dei membri: public se si utilizza la parola chiave struct e private per la parola chiave class .

È anche possibile che una class derivi da una struct (o viceversa). In questo caso, l'ereditarietà predefinita è controllata dal figlio, quindi una struct che deriva da una class verrà predefinita per ereditarietà pubblica e una class che deriva da una struct avrà un'ereditarietà privata per impostazione predefinita.

eredità public :

struct B : public A // or just `struct B : A`
{
    void foo()
    {
        p1 = 0; //well formed, p1 is public in B
        p2 = 0; //well formed, p2 is protected in B
        p3 = 0; //ill formed, p3 is private in A
    }
};

B b;
b.p1 = 1; //well formed, p1 is public
b.p2 = 1; //ill formed, p2 is protected
b.p3 = 1; //ill formed, p3 is inaccessible

eredità private :

struct B : private A
{
    void foo()
    {
        p1 = 0; //well formed, p1 is private in B
        p2 = 0; //well formed, p2 is private in B
        p3 = 0; //ill formed, p3 is private in A
    }
};

B b;
b.p1 = 1; //ill formed, p1 is private
b.p2 = 1; //ill formed, p2 is private
b.p3 = 1; //ill formed, p3 is inaccessible

eredità protected :

struct B : protected A
{
    void foo()
    {
        p1 = 0; //well formed, p1 is protected in B
        p2 = 0; //well formed, p2 is protected in B
        p3 = 0; //ill formed, p3 is private in A
    }
};

B b;
b.p1 = 1; //ill formed, p1 is protected
b.p2 = 1; //ill formed, p2 is protected
b.p3 = 1; //ill formed, p3 is inaccessible

Si noti che, sebbene l'ereditarietà protected sia consentita, l'uso effettivo di esso è raro. Un'istanza di come l'ereditarietà protected viene utilizzata nell'applicazione è nella specializzazione parziale della classe base (di solito indicata come "polimorfismo controllato").

Quando OOP era relativamente nuovo, l'eredità (pubblica) veniva spesso detta per modellare una relazione "IS-A". In altre parole, l'ereditarietà pubblica è corretta solo se un'istanza della classe derivata è anche un'istanza della classe base.

Questo è stato successivamente ridefinito nel Principio di sostituzione di Liskov : l'ereditarietà pubblica dovrebbe essere utilizzata solo quando / se un'istanza della classe derivata può essere sostituita per un'istanza della classe base in qualsiasi circostanza possibile (e comunque ha senso).

In genere si dice che l'ereditarietà privata incarna un rapporto completamente diverso: "è implementato in termini di" (a volte chiamato una relazione "HAS-A"). Ad esempio, una classe Stack può ereditare privatamente da una classe Vector . L'ereditarietà privata ha una somiglianza molto maggiore con l'aggregazione che con l'eredità pubblica.

L'ereditarietà protetta non viene quasi mai utilizzata e non esiste un accordo generale sul tipo di relazione che incarna.