2011-01-28 16 views
26

L'aggiunta di qualsiasi membro non registrabile a una classe impedirebbe la generazione automatica di costruzione copia e l'operatore di assegnazione. Perché boost richiede che l'ereditarietà non sia utilizzabile?perché boost :: noncopyable richiede ereditarietà

penso io non sono solo nella mia preferenza stilistica per

class MyUtility : public MyBase 
{ 
    noncopyable guard; 
    ... 
}; 

al contrario di

class MyUtility : public MyBase , private noncopyable 
{ 
    ... 
}; 

Dave Abrahams è un ragazzo intelligente, così ha probabilmente considerato questa possibilità. Cosa mi manca? Cosa fa l'ereditarietà?

risposta

33

Perché sizeof(boost::noncopyable)!=0. Quindi in questo caso la dimensione della tua classe sarà più grande.

Here è possibile leggere sull'ottimizzazione della base vuota. (guarda la sezione "4.7: The Empty Member Optimization").

Modifica: Il fatto, che non è copiabile non ha costruttori pubblici lo rende inutile per qualsiasi altro uso, mentre le classi con costruttore pubblico potrebbero anche essere utilizzate per altri scopi errati. Questa è un'altra ragione, perché boost ha scelto questo approccio.

+4

obbligatorio riferimento alla "Ottimizzazione base vuota" ha permesso di compilatori per coloro che non hanno capito la risposta :) –

+1

@Matthieu M. Fatto :). – UmmaGumma

+0

L'ho accettato come risposta, ma dovrebbe anche menzionare il fatto che l'approccio di boost impedisce alla sottoclasse di fornire esplicitamente la funzionalità di copia. –

23

Se fosse possibile utilizzare noncopyable come membro, richiederebbe un costruttore e un distruttore di default pubblici. Quindi le persone potrebbero creare istanze di noncopyable o persino usarlo come una classe di base polimorfa senza che il distruttore sia virtuale. L'implementazione senza membri pubblici garantisce semplicemente che venga utilizzata esclusivamente come una classe politica.

+3

Penso che questa sia la risposta giusta, non quella sull'EBO. –

4

Personalmente, preferisco la sintassi di boost. L'ereditarietà è un modo per aggiungere alcune proprietà o funzionalità all'intera classe e non è possibile applicare una funzione simile. Il membro non registrabile sembra difficile (in realtà non vuoi aggiungere nessun membro, è un trucco). L'ereditarietà viene utilizzata precisamente per ciò per cui è stata progettata.

4

Il motivo più ovvio è che la classe derivata "isA" non è negoziabile, quindi l'utilizzo dell'ereditarietà ha più senso. Il fatto che usarlo in questo modo non aumenti le dimensioni della classe è una considerazione anche oggi (ma penso che noncopiable abbia preceduto l'ottimizzazione della classe base vuota).

+0

Quando il lay-out del compilatore ha derivato oggetti di classe come se il sottobobject di base fosse un membro subobject? Mi sembra che il riutilizzo del padding di coda del subobject di base sia esistito per decenni (almeno uno). – curiousguy

0

Se si omette la designazione private, diventa quasi come l'inglese:

// English: this is my car, it is not copyable 
class MyCar: noncopyable {}; 

// my truck is noncopyable, did i mention it's also a vehicle? 
class MyTruck: noncopyable, public MyVehicle {}; 

// My airplane is a vehicle, BTW it's not copyable 
class MyAirplane: public MyVehicle, noncopyable {}; 
Problemi correlati