2009-06-29 13 views

risposta

73

Quando una classe è (intesa come) una classe astratta, un costruttore protetto ha esattamente ragione. In questa situazione non vuoi che gli oggetti siano istanziati dalla classe ma usino solo per ereditarli.

Esistono altri casi di utilizzo, ad esempio quando un determinato insieme di parametri di costruzione deve essere limitato alle classi derivate.

+7

+1 Ma non necessariamente deve essere una classe astratta. È spesso il caso però. – ralphtheninja

+4

Non è sufficiente dichiarare una funzione come virtuale pura per la definizione di una classe base? O quanto sopra è in assenza di pura funzione virtuale. Che cos'è un evento di creazione per una classe derivata di una classe astratta? –

+0

@Henk Holterman lo fa di certo - vedere la sezione 10.4 del ++ standard C, dal titolo "classi astratte" –

11

un uso potrebbe essere modelli di fabbrica

6

Un costruttore protetto significa che solo i membri derivati ​​possono costruire le istanze della classe (e le istanze derivate) che utilizzano tale costruttore. Questo suona un po 'pollo-e-uovo, ma a volte è utile quando si implementano le fabbriche di classi.

+3

Tecnicamente, questo si applica solo se TUTTI i sensori sono protetti. Le classi di amici – MSalters

+1

possono anche chiamare il costruttore protetto (non solo le classi derivate). –

+0

...e l'uso di una classe friend che chiama il costruttore protetto sarebbe nel caso di un oggetto che ha membri che sono costanti (impostati dal costruttore) ma che devono essere pubblici, ma che non devono mai essere impostati da nessun altro accesso pubblico, garantisce che l'oggetto non verrà creato da qualche altra parte e quindi i dati non verranno modificati da nessun'altra parte. – osirisgothra

3

Per consentire a una sottoclasse di utilizzare un costruttore che non dovrebbe essere accessibile direttamente a un programma di creazione di istantanee.

3

Si può usare per limitare le classi che potrebbero creare, ad esempio:

class Level 
{ 
private: 

Level(); 
¨Level(); 

friend class LevelManager; 
}; 

L'unica classe che può creare un'istanza di esso è la classe LevelManager, così saprete sempre che il livello l'istanza viene creata nel LevelManager.

+0

Mentre vero, si tratta di un costruttore privato, non protetto. – David

+0

ahaha scusa, ho letto male. Devo cancellare il mio post? –

7

I costruttori non pubblici sono utili quando ci sono requisiti di costruzione che non possono essere garantiti unicamente dal costruttore. Ad esempio, se un metodo di inizializzazione deve essere chiamato subito dopo il costruttore, o se l'oggetto deve registrarsi con qualche oggetto contenitore/gestore, questo deve essere fatto al di fuori del costruttore. Limitando l'accesso al costruttore e fornendo solo un metodo di fabbrica, è possibile garantire che qualsiasi istanza ricevuta da un utente soddisfi tutte le sue garanzie. Questo è anche comunemente usato per implementare un Singleton, che è in realtà solo un'altra garanzia della classe (che ci sarà solo una singola istanza).

Il motivo per cui il costruttore è protetto, anziché privato, è lo stesso per rendere qualsiasi altro metodo o campo protetto invece che privato: in modo che possa essere ereditato dai bambini. Forse vuoi un metodo factory, non virtuale virtuale nella classe base, che restituisce riferimenti alle istanze delle classi derivate; le classi derivate ovviamente vogliono l'accesso ai costruttori genitori, ma non si vuole ancora crearli al di fuori della propria fabbrica.

2

Per i metodi di fabbrica con effetti collaterali.

class mine { 

    private: 
    mine() {}; 

    protected: 
    mine(int id) : m_id(id) {}; 

    int m_id; 
    static int m_count; 

    public: 
    static mine* CreateOneOfMe() { 
     return mine(m_count++); 
    } 

    int GetId() { return m_id; } 

}; 

Questo crea istanze della classe e garantisce che ognuna di esse ha un ID intero incrementale univoco. Si noti che se il costruttore che si desidera utilizzare non è l'impostazione predefinita, è necessario nascondere anche il valore predefinito.

5

Un costruttore protetto può essere utilizzato per rendere una classe effettivamente astratta quando nessuno dei suoi metodi è puro-virtuale.

Non è abbastanza astratto nel senso del C++ poiché le classi di amici possono ancora usarlo senza sovrascrivere, ma poi dovresti dichiararle.

Problemi correlati