Domanda

Mentre ho visto rari casi in cui privato era necessaria l'eredità, non ho mai riscontrato un caso in cui protetto è necessaria l'eredità.Qualcuno ha un esempio?

È stato utile?

Soluzione

Le persone qui sembrano confondere l'ereditarietà della classe protetta e i metodi protetti.

FWIW, non ho mai visto nessuno usare l'ereditarietà della classe protetta e, se ricordo bene, penso che Stroustrup considerasse addirittura il livello "protetto" un errore in C++.C'è ben poco che non puoi fare se rimuovi quel livello di protezione e fai affidamento solo su pubblico e privato.

Altri suggerimenti

Esiste un caso d'uso molto raro di ereditarietà protetta.È dove vuoi usarlo covarianza:

struct base { 
    virtual ~base() {} 
    virtual base & getBase() = 0;
}; 

struct d1 : private /* protected */ base { 
    virtual base & getBase() { 
        return this; 
    } 
}; 

struct d2 : private /* protected */ d1 {
    virtual d1 & getBase () { 
        return this; 
    } 
}; 

Il frammento precedente tentava di nascondere la sua classe base e di fornire visibilità controllata delle basi e delle loro funzioni, per qualsiasi motivo, fornendo una funzione "getBase".

Tuttavia, fallirà nella struttura d2, Da d2 non lo sa d1 è derivato da base.Così, covariance non funzionerà.Una via d'uscita è derivarli protetti, in modo che l'eredità sia visibile in d2.

Un esempio simile di utilizzo di this è quando si deriva da std::ostream, ma non vuoi che persone a caso scrivano nel tuo stream.Puoi fornire un file virtuale getStream funzione che restituisce std::ostream&.Questa funzione potrebbe preparare il flusso per l'operazione successiva.Ad esempio inserendo determinati manipolatori.

std::ostream& d2::getStream() {
    this->width(10);
    return *this;
}

logger.getStream() << "we are padded";

Domande frequenti su C++ Lite menziona un caso in cui l’uso dell’ereditarietà privata è una soluzione legittima (cfr [24.3.] Quale dovrei preferire:composizione o eredità privata?).È quando vuoi chiamare la classe derivata dall'interno di una classe base privata tramite una funzione virtuale (in questo caso derivedFunction()):

class SomeImplementationClass
{
protected:
    void service() {
        derivedFunction();
    }

    virtual void derivedFunction() = 0;      

    // virtual destructor etc
};

class Derived : private SomeImplementationClass
{
    void someFunction() {
        service();
    }

    virtual void derivedFunction() {
        // ...
    }

    // ...
};

Ora se vuoi derivare dalla classe Derived e vuoi usare Base::service() dall'interno della classe derivata (ad esempio, vuoi spostare Derived::someFunction() alla classe derivata), il modo più semplice per ottenere ciò è modificare l'ereditarietà privata di Base all'eredità protetta.

Mi dispiace, non riesco a pensare a un esempio più concreto.Personalmente mi piace rendere pubbliche tutte le eredità in modo da evitare di perdere tempo con le discussioni "devo rendere la relazione di eredità protetta o privata".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top