uso una son sirve setters que poo para metodos los incluya getters generar encapsulamiento ejemplo crear con como clase c++ accessor setter getter

c++ - una - que son los setters en java



Convenciones para métodos de acceso(getters y setters) en C++ (9)

  1. Ese es un buen estilo si solo queremos representar datos pure .

  2. No me gusta :) porque get_/set_ es realmente innecesario cuando podemos sobrecargarlos en C ++.

  3. STL usa este estilo, como std::streamString::str y std::ios_base::flags , ¡excepto cuando debe evitarse! cuando? Cuando el nombre del método entra en conflicto con el nombre de otro tipo, se get_/set_ estilo get_/set_ , como std::string::get_allocator debido a std::allocator .

Varias preguntas sobre los métodos de acceso en C ++ han sido formuladas en SO, pero ninguna pudo satisfacer mi curiosidad sobre el tema.

Intento evitar accesos siempre que sea posible, porque, como Stroustrup y otros programadores famosos, considero que una clase con muchos de ellos es señal de mal OO. En C ++, en la mayoría de los casos puedo agregar más responsabilidad a una clase o usar la palabra clave friend para evitarlos. Sin embargo, en algunos casos, realmente necesita acceso a miembros específicos de la clase.

Hay varias posibilidades:

1. No use accesadores en absoluto

Solo podemos hacer públicas las respectivas variables miembro. Este es un no-go en Java, pero parece estar bien con la comunidad de C ++. Sin embargo, estoy un poco preocupado por los casos en los que se debe devolver una copia explícita o una referencia de solo lectura (const) a un objeto, ¿es exagerado?

2. Usar métodos get / set estilo Java

No estoy seguro si es Java, pero me refiero a esto:

int getAmount(); // Returns the amount void setAmount(int amount); // Sets the amount

3. Utilice métodos objetivos get / set de estilo C

Esto es un poco raro, pero aparentemente cada vez más común:

int amount(); // Returns the amount void amount(int amount); // Sets the amount

Para que eso funcione, deberá encontrar un nombre diferente para su variable miembro. Algunas personas añaden un guión bajo, otras anteprenden "m_". No me gusta tampoco.

¿Qué estilo usas y por qué?


  1. No excluiría el acceso de los usuarios. Puede ser para algunas estructuras POD, pero las considero una buena opción (algunos usuarios también pueden tener lógica adicional).

  2. Realmente no importa la convención de nomenclatura, si eres coherente en tu código. Si está utilizando varias bibliotecas de terceros, es posible que utilicen diferentes convenciones de nomenclatura de todos modos. Entonces es una cuestión de gusto.


  1. Nunca uso este estilo Porque puede limitar el futuro de su diseño de clase y los geters o setters explícitos son igual de eficientes con un buen compilador.

    Por supuesto, en realidad los getters o setters explícitos en línea crean la misma dependencia subyacente en la implementación de la clase. Simplemente reducen la dependencia semántica. Aún tienes que recompilar todo si los cambias.

  2. Este es mi estilo predeterminado cuando uso métodos de acceso.

  3. Este estilo me parece demasiado "inteligente". Lo uso en raras ocasiones, pero solo en casos en los que realmente deseo que el acceso se sienta tanto como sea posible como una variable.

Creo que hay razones para simples bolsas de variables con posiblemente un constructor para asegurarse de que estén todas inicializadas en algo sensato. Cuando hago esto, simplemente lo hago una struct y lo dejo todo público.


2) es la mejor OMI, porque hace que tus intenciones sean más claras. set_amount(10) es más significativo que la amount(10) , y como un buen efecto secundario permite que un miembro nombre amount .

Las variables públicas suelen ser una mala idea, porque no hay encapsulamiento. Supongamos que necesita actualizar un caché o actualizar una ventana cuando se actualiza una variable. Es una lástima si tus variables son públicas. Si tiene un método establecido, puede agregarlo allí.


Déjame que te cuente acerca de una posibilidad adicional, que parece ser la más concisa.

Necesidad de leer y modificar

Simplemente declare esa variable pública:

class Worker { public: int wage = 5000; } worker.wage = 8000; cout << worker.wage << endl;

Solo necesito leer

class Worker { int _wage = 5000; public: inline int wage() { return _wage; } } worker.wage = 8000; // error !! cout << worker.wage() << endl;

La desventaja de este enfoque es que necesita cambiar todo el código de llamada (agregue paréntesis, eso es) cuando desea cambiar el patrón de acceso.


Desde mi punto de vista, como sentado con 4 millones de líneas de código C ++ (y eso es solo un proyecto) desde una perspectiva de mantenimiento, diría:

  • Está bien no usar getters / setters si los miembros son inmutables (es decir, const ) o simples sin dependencias (como una clase de puntos con miembros X e Y).

  • Si el miembro es private solo, también se puede omitir getters / setters. También cuento que los miembros de pimpl -classes internos son private si la unidad .cpp es pequeña.

  • Si el miembro es public o protected ( protected es tan malo como public ) y no const , no simple o tiene dependencias entonces use getters / setters.

Como persona de mantenimiento, mi principal razón para querer tener getters / setters es porque entonces tengo un lugar para poner break points / logging / algo más.

Prefiero el estilo de la alternativa 2. ya que es más fácil de buscar (un componente clave en la escritura del código que se puede mantener).


En general, creo que no es una buena idea tener demasiados getters y setters utilizados por demasiadas entidades en el sistema. Es solo una indicación de un mal diseño o una encapsulación incorrecta.

Habiendo dicho eso, si tal diseño necesita ser refactorizado, y el código fuente está disponible, preferiría usar el patrón de Diseño de Visitantes. La razón es:

a. Le da a una clase la oportunidad de decidir a quién permitir el acceso a su estado privado

segundo. Le da a la clase la oportunidad de decidir qué acceso permitir a cada una de las entidades que están interesadas en su estado privado

do. Documenta claramente dicho acceso externo a través de una interfaz de clase clara

La idea básica es:

a) Rediseñe si es posible,

b) Refactorizar de tal manera que

  1. Todo el acceso al estado de clase es a través de una interfaz individualista bien conocida

  2. Debería ser posible configurar algún tipo de hacer y no hacer para cada interfaz, por ejemplo, se debe permitir todo acceso desde la entidad externa GOOD , todo acceso desde la entidad externa BAD debe ser rechazado y la entidad externa OK debe poder obtener pero no establecido (por ejemplo)


He visto la idealización de clases en lugar de tipos integrales para referirse a datos significativos.

Algo como esto a continuación generalmente no hace un buen uso de las propiedades de C ++:

struct particle { float mass; float acceleration; float velocity; } p;

¿Por qué? Porque el resultado de p.mass * p.acceleration es un float y no forza como se esperaba.

La definición de clases para designar un propósito (incluso si es un valor, como la cantidad mencionada anteriormente) tiene más sentido y nos permite hacer algo como:

struct amount { int value; amount() : value( 0 ) {} amount( int value0 ) : value( value0 ) {} operator int()& { return value; } operator int()const& { return value; } amount& operator = ( int const newvalue ) { value = newvalue; return *this; } };

Puede acceder al valor en cantidad implícitamente por el operador int. Además:

struct wage { amount balance; operator amount()& { return balance; } operator amount()const& { return balance; } wage& operator = ( amount const& newbalance ) { balance = newbalance; return *this; } };

Uso de Getter / Setter:

void wage_test() { wage worker; (amount&)worker = 100; // if you like this, can remove = operator worker = amount(105); // an alternative if the first one is too weird int value = (amount)worker; // getting amount is more clear }

Este es un enfoque diferente, no significa que sea bueno o malo, sino diferente.


Una posibilidad adicional podría ser:

int& amount();

No estoy seguro de que lo recomiende, pero tiene la ventaja de que la notación inusual puede evitar que los usuarios modifiquen los datos.

str.length() = 5; // Ok string is a very bad example :)

A veces es quizás la mejor opción para hacer:

image(point) = 255;

Otra posibilidad otra vez, use la notación funcional para modificar el objeto.

edit::change_amount(obj, val)

De esta forma, la función peligrosa / edición se puede eliminar en un espacio de nombres separado con su propia documentación. Este parece venir de forma natural con la programación genérica.