2011-01-28 7 views
26

Agregar cualquier miembro no copiable a una clase evitaría la generación automática de la construcción de copias y el operador de asignación. ¿Por qué el impulso requiere herencia para usar no copiable?por qué boost :: noncopyable require inheritance

creo que no estoy solo en mi preferencia estilística de

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

en contraposición a

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

de Dave Abrahams es un tipo inteligente, por lo que probablemente consideraron esta posibilidad. ¿Qué me estoy perdiendo? ¿Qué logra la herencia?

Respuesta

33

Porque sizeof(boost::noncopyable)!=0. Entonces, en este caso, el tamaño de tu clase será más grande.

Here puede leer sobre la optimización de base vacía. (Consulte la sección "4.7: La optimización de miembros vacíos").

Editar: El hecho de que noncopyable no tiene constructores públicos lo hace inútil para cualquier otro uso, mientras que las clases con constructor público también podrían ser utilizadas para otros fines erróneos. Esta es otra razón, por qué impulsar elegir este enfoque.

+4

referencia obligatoria a la "Optimización de Base vacía" permitió a los compiladores para los que no entienden la respuesta :) –

+1

@Matthieu M. Hecho :). – UmmaGumma

+0

Estoy aceptando esta como la respuesta, pero también debería mencionar el hecho de que el enfoque de boost evita que las subclases proporcionen explícitamente la funcionalidad de copia. –

23

Si puede usar noncopyable como miembro, se requerirá un constructor y un destructor predeterminados públicos. Entonces las personas podrían crear instancias de noncopyable o incluso usarlo como una clase base polimórfica sin que el destructor sea virtual. La implementación sin miembros públicos simplemente asegura que se use únicamente como una clase de política.

+3

Creo que esta es la respuesta correcta, no la de EBO. –

4

Personalmente, prefiero la sintaxis de impulso. La herencia es una forma de agregar algunas propiedades o características a toda la clase, y no se puede copiar esta característica. El miembro no copiable parece complicado (en realidad no desea agregar ningún miembro, es un truco). La herencia se usa precisamente para lo que está diseñado.

4

La razón más obvia es que la clase derivada "isA" no es compilable, por lo que usar la herencia tiene más sentido. El hecho de que usarlo de esta manera no aumente el tamaño de la clase también es una consideración hoy en día (pero creo que el noncopiable precedió a la optimización de la clase base vacía).

+0

¿Cuándo diseñó el compilador los objetos de clase derivados como si el subobjeto base fuera un subobjeto miembro? Me parece que la reutilización del relleno de la cola del subobjeto base existió durante décadas (al menos uno). – curiousguy

0

Si se omite la designación private, se convierte casi como Inglés:

// 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 {};