2010-04-16 20 views
6

En uno de mis proyectos, tengo algunas clases que representan entidades que no pueden cambiar una vez creadas, también conocido como. clases inmutables.Clases inmutables en C++

Ejemplo: una clase RSAKey que representa una clave RSA que solo tiene métodos const. No tiene sentido cambiar la instancia existente: si necesita otra, simplemente cree una.

Mis objetos a veces son pesados ​​e impuse el uso de punteros inteligentes para evitar copia profunda.

Hasta ahora, tengo el siguiente patrón para mis clases:

class RSAKey : public boost::noncopyable, public boost::enable_shared_from_this<RSAKey> 
{ 
    public: 

    /** 
    * \brief Some factory. 
    * \param member A member value. 
    * \return An instance. 
    */ 
    static boost::shared_ptr<const RSAKey> createFromMember(int member); 

    /** 
    * \brief Get a member. 
    * \return The member. 
    */ 
    int getMember() const; 

    private: 

    /** 
    * \brief Constructor. 
    * \param member A member. 
    */ 
    RSAKey(int member); 

    /** 
    * \brief Member. 
    */ 
    const int m_member; 
}; 

lo que sólo puede obtener un puntero (bueno, un puntero inteligente ) a un RSAKey const. Para mí, tiene sentido, porque tener una referencia no const a la instancia es inútil (solo tiene métodos const).

¿Vieron algún problema con respecto a este patrón? ¿Las clases inmutables son algo común en C++ o acabo de crear un monstruo?

¡Gracias por sus consejos!

+1

Una sugerencia: si su clase no es copiable e inmutable, también puede hacer 'm_member' const. –

+0

Gracias. Es const en mi código. Lo olvidé cuando escribí el ejemplo. Editado;) – ereOn

+0

Solo tenga cuidado cuando use 'boost :: shared_ptr' para no construir más de un puntero compartido usando el mismo' RSAKey * ', o ellos no compartirán la propiedad sobre el objeto entre sí y será eliminado cuando todavía hay punteros compartidos que hacen referencia a él. De hecho, desalentaría el uso de 'boost :: shared_ptr' por esa razón, a menos que realmente sepas lo que haces, y utiliza una clase de punteros compartida que almacena el contador de referencias dentro de los objetos (por ejemplo, Qt's, o crea los tuyos propios). – HelloGoodbye

Respuesta

1

Se ve bien conmigo.

Al marcar cada objeto const de fábrica, se obvia el marcado de cada miembro de datos const, pero en este ejemplo solo hay uno.

+1

@Potatoswatter, ¿por qué tu respuesta es * wiki * de la comunidad? (Ni siquiera sabía que las respuestas podían ser * wiki de la comunidad * por su cuenta). Sólo me preguntaba. – ereOn

+0

@ereOn: Porque no siento que estoy contribuyendo nada. Si alguien quiere agregar contenido real a mi publicación, siéntete libre. Es más bien un maniquí, así que puedes aceptar que tienes razón al final. – Potatoswatter

9

Esto parece exagerado. Cuando solo tiene miembros const, el objeto no se puede cambiar de todos modos. Si no desea permitir la copia, simplemente haga que el constructor de copias y el operador de asignación sean privados.

+0

Esto ya se hace heredando de boost :: noncopyable. – ereOn

+5

boost: noncopyable es más explícito. Al mirar la interfaz, verá inmediatamente ": public boost :: noncopyable", mientras que es posible que no observe el constructor de copia privada y el operador de asignación. –

+1

Pero eso trae consigo la sobrecarga de acoplamiento considerable de Boost, cuando ya existe un modismo perfectamente bueno, que oculta el constructor de copia y el operador de asignación de copia. ¿Cuál es el beneficio para el programador? (Los beneficios para los promulgadores de Boost son obvios) – DannyT