2013-03-18 9 views
9

Voglio rendere una classe di base astratta non copiabile e imporre che tutte le classi che ne derivano siano non copiabili. Il codice seguente utilizza il noncopyable di Boost come definito in noncopyable.hpp ma consente comunque a D, la classe derivata, di definire un costruttore di copie.Proibire la definizione di un costruttore di copie in una classe ereditata

class noncopyable 
{ 
    protected: 
     noncopyable() {} 
     ~noncopyable() {} 
    private: // emphasize the following members are private 
     noncopyable(const noncopyable&); 
     const noncopyable& operator=(const noncopyable&); 
}; 

class D : noncopyable 
{ 
    public: 
     D() { } 
     D(const D&) { } 
}; 

int main() 
{ 
    D a; 
    D b(a); 

    return 0; 
} 

Questo codice viene compilato ed eseguito (http://ideone.com/g4gGLm), quando mi aspettavo di gettare un errore di compilazione su D's costruttore di copia. Forse ho interpretato male ciò che questa classe noncopyable è destinata a fare. In tal caso, esiste un modo per forzare le classi derivate a non definire un costruttore di copie? (La risposta può usare C++ 11, ma preferibilmente non potenzia)

risposta

3

È necessario eliminare il costruttore di copie di D. In questo momento si consente la costruzione di copie di D's non tentando di copiare-costruire la classe base. Le seguenti varianti non verranno compilate:

class E: noncopyable 
{ 
}; 
E e, e2(e); 

class F: noncopyable 
{ 
public: 
    F(const F &init): noncopyable(init) 
    {} 
}; 
+0

Ora capisco cosa non è realizzabile (grazie al tuo esempio di classe E). Grazie – steve9164

12

Il motivo per cui questo funziona è perché D(const D&) chiama il costruttore predefinito della classe base, non il costruttore di copie. (Contro-intuitivo in un primo momento, ma ha senso considerare tutti i costruttori si comportano come questo)

Poiché il costruttore di copia non viene chiamato, una copia dell'oggetto di base non viene creato a meno che non esplicitamente chiedere uno:

D(const D& d) : noncopyable(d) { } 

che causerebbe effettivamente un errore. Di conseguenza, il problema è un problema: non è in corso la copia di noncopyable.

Non sono a conoscenza di alcun modo diretto per forzare una classe derivata a non consentire la copia, né consiglierei di usarne uno se esistesse.

+0

Perché non si consiglia di non consentire la copia? – steve9164

+1

@ steve9164 non stava dicendo che non raccomanderei di scrivere codice non leggibile solo allo scopo di forzare le classi derivate a non consentire la copia. –

+0

Se il codice risultante era illeggibile, allora sì sono d'accordo che probabilmente non ne vale la pena – steve9164

Problemi correlati