2011-01-14 12 views
6

Sé cuál es la diferencia y cómo funcionan ambos, pero esta pregunta es más sobre el estilo de codificación.Puntero vs variable en la clase

Cada vez que estoy codificando hago muchas clases, todas tienen variables y algunas de ellas son punteros y algunas son variables normales. Por lo general prefieren las variables a punteros si que los miembros dura tanto como lo hace la clase pero entonces mi código se convierte de esta manera:

engine->camera.somevar->x; 
// vs 
engine->camera->somevar->x; 

no me gusta el punto en el medio. O con variables privadas:

foo_.getName(); 
// vs 
foo_->gatName(); 

Creo que el punto "desaparece" en un código largo. Encuentro que -> es más fácil de leer en algunos casos.

Mi pregunta sería si utiliza punteros incluso si la variable se creará en el constructor y se eliminará en el destructor. ¿Hay algún consejo de estilo en este caso?

P.S. Creo que el punto se ve mejor en algunos casos.

Respuesta

5

En primer lugar, es una mala forma de exponer las variables miembro.

En segundo lugar, su clase probablemente nunca debería tener punteros de contenedor. Ligera corolario: las clases que contienen lógica comercial nunca deben tener punteros (ya que esto significa que también contienen código de administración de puntero y el código de administración del puntero debe dejarse a las clases que no tienen lógica comercial pero están diseñadas específicamente para administrar punteros (punteros inteligentes y contenedores)

Las clases de administración de punteros (punteros inteligentes/contenedores) se deben diseñar para gestionar un único puntero. Gestionar más de uno es mucho más difícil de lo esperado y todavía no he encontrado una situación donde complejidad adicional valió la pena.

Finalmente, los miembros del público no deben exponer la implementación subyacente (usted sho uld no proporciona acceso a los miembros incluso a través de getters/setters). Esto vincula la interfaz a la implementación. En su lugar, su interfaz pública debe proporcionar un conjunto de acciones que se pueden realizar en el objeto. es decir, los métodos son verbs.

En C++ es raro ver punteros.
Generalmente están ocultos dentro de otras clases. Pero deberías acostumbrarte a usar una mezcla de -> y . ya que todo depende del contexto y de lo que intentas transmitir. Siempre que el código esté limpio y legible, no importa demasiado.

Una adición personales:

me gusta la continuación _ al final de su identificador hace que el. disapear foo_.getName() creo que se vería mucho mejor como foo.getName()

+0

Bueno, pero ¿qué pasa con los miembros frente a los punteros inteligentes (en el código de implementación)? – user396672

+0

@ user396672: ¿Qué hay de ellos? Un puntero inteligente es solo un objeto como cualquier otro. Su trabajo es administrar un solo puntero. –

+0

bueno, algunas clases tienen variables públicas y no veo ninguna razón para hacerlas privadas. Solo realizo variables privadas si el trabajo de clase puede corromperse por el uso no válido de ellas. Si están en la clase solo para que la estructura del programa sea más agradable, por qué no. Por ejemplo, el ejemplo con motor. Cuando codigo cualquier juego (hago juegos de mierda a veces. Es muy divertido), hago un "motor" de puntero externo porque lo usan muchos otros objetos. Y ese motor generalmente contiene cosas como la cámara en el ámbito público. Lo hago porque otros objetos tienen que acceder a la clase de cámara y no pueden arruinar el motor. – Pijusn

0

Si la estructura "incrustada" tiene exactamente la misma duración que la estructura "principal" y no se hace referencia en ningún otro lugar, prefiero tenerla como miembro, en lugar de usar un puntero. El código producido es ligeramente más eficiente, ya que guarda una cantidad de llamadas al asignador de memoria y evita una serie de desreferencias del puntero.

También es más fácil de manejar, ya que se reduce la posibilidad de errores relacionados con el puntero.

Si, por otro lado, existe la más mínima posibilidad de que la estructura incrustada se pueda referenciar en otro lugar, prefiero usar una estructura y punteros separados. De esta forma, no tendré que refactorizar mi código si resulta que la estructura incrustada debe extraerse de su matriz.

EDIT:

supongo que eso significa que por lo general voy con la alternativa puntero :-)

EDIT 2:

Y sí, mi respuesta es suponiendo que realmente quiere (o tiene) para elegir entre los dos, es decir, que escriba código de estilo C. La forma adecuada de acceder a miembros de la clase orientada a objetos es a través de funciones get/set.

Mis comentarios sobre si incluir una instancia de clase real o un puntero/referencia a uno son probablemente todavía válidos, sin embargo.

+0

miembros, sin embargo, pueden dar lugar a grandes objetos y causar problemas de fragmentación de memoria aparezca – user396672

0

Lo ideal es que no uses ninguno de estos métodos: debes usar los métodos getter/setter. El rendimiento alcanzado es mínimo (el compilador probablemente lo optimice, de todos modos).

La segunda consideración es que usar punteros es una idea generalmente peligrosa, porque en algún momento es probable que la arruine.

Si ninguno de estos te desconcierta, entonces diría que todo lo que queda es una cuestión de preferencia personal.

+2

captadores/setters es un mal diseño, ya que expone la implementación y, por lo tanto, te une a ella (es menos acoplamiento que exponer variables, pero aún deja mucho que desear). –

+0

¿Qué deja que desear que no está cubierto en esto, por ejemplo? http://stackoverflow.com/questions/2747721/getters-and-setters-are-bad-oo-design En otras palabras, ¿por qué sienten que NUNCA existe una situación en la que sean útiles? – Kricket

+0

Nunca digas nunca. El artículo que vincula y el que los vincula también cubren el tema en detalle. Pero todo se reduce al acoplamiento. Cuanto más ajustado esté el código, más difícil será mantener y/o modificar/actualizar. Los Getters/Setters introducen un acoplamiento adicional que generalmente no se necesita. –

1

Usted no debe hacer su elección debido a encontrar '->' más fácil de leer :) usando una variable miembro es generalmente mejor ya que no puede cometer errores con usted puntero.

Dicho esto, el uso de una variable miembro te obliga a exponer tu implementación, por lo tanto, tienes que usar referencias. Pero luego debe inicializar en su constructor, que no siempre es posible ...

Una solución es usar std :: auto_ptr o boost :: scoped_ptr de un puntero inteligente similar. Allí obtendrá la ventaja de ambas soluciones, con muy pocos inconvenientes.

MY2C

EDIT:

Algunos enlaces útiles:
Article on std::auto_ptr
boost::scoped_ptr
Pimpl : private implementation