Una gran cantidad de código C ++ utiliza convenciones sintácticas para marcar las variables miembro. Ejemplos comunes incluyen
- m_ memberName para miembros públicos (donde se usan miembros públicos)
- _ memberName para miembros privados o todos los miembros
Otros intentan imponer el uso de este-> miembro cada vez que se usa una variable miembro.
En mi experiencia, la mayoría de las bases de código más grandes fallan al aplicar tales reglas de manera consistente.
En otros idiomas, estas convenciones están mucho menos extendidas. Lo veo solo ocasionalmente en código Java o C #. Creo que nunca lo he visto en código Ruby o Python. Por lo tanto, parece haber una tendencia con lenguajes más modernos para no usar marcado especial para las variables miembro.
¿Sigue siendo útil esta convención hoy en día en C ++ o es solo un anacronismo? Especialmente porque se usa de manera tan inconsistente en las bibliotecas. ¿No se muestran los otros idiomas que uno puede prescindir de los prefijos de miembro?
fuente
self._something = 1
.this->member
en el código Python. En Python, normalmente seríaself.member
y no es solo una convención, sino que es requerido por el lenguaje.Respuestas:
Debes tener cuidado al usar un guión bajo destacado. Un guión bajo antes de una letra mayúscula en una palabra está reservado. Por ejemplo:
_Foo
_L
son todas palabras reservadas mientras
_foo
_l
no son. Hay otras situaciones en las que los guiones bajos antes de las letras minúsculas no están permitidos. En mi caso específico, encontré que _L estaba reservado para Visual C ++ 2005 y el choque creó algunos resultados inesperados.
Estoy cerca de lo útil que es marcar las variables locales.
Aquí hay un enlace sobre qué identificadores están reservados: ¿Cuáles son las reglas sobre el uso de un guión bajo en un identificador de C ++?
fuente
Estoy totalmente a favor de los prefijos bien hechos .
Creo que la notación húngara (Sistema) es responsable de la mayor parte del "mal rap" que obtienen los prefijos.
Esta notación es en gran medida inútil en lenguajes fuertemente tipados, por ejemplo, en C ++ "lpsz" para decirle que su cadena es un puntero largo a una cadena terminada en nulo, cuando: la arquitectura segmentada es historia antigua, las cadenas C ++ son, por convención común, punteros a terminación nula ¡matrices de caracteres, y no es realmente tan difícil saber que "customerName" es una cadena!
Sin embargo, sí uso prefijos para especificar el uso de una variable (esencialmente "Aplicaciones húngaras", aunque prefiero evitar el término húngaro debido a que tiene una asociación mala e injusta con el sistema húngaro), y esto es muy útil para ahorrar tiempo y enfoque de reducción de errores .
Yo suelo:
Cuando deseo aclarar el tipo , uso sufijos estándar (por ejemplo, Lista, ComboBox, etc.).
Esto hace que el programador sea consciente del uso de la variable cada vez que la ve / usa. Podría decirse que el caso más importante es "p" para el puntero (porque el uso cambia de var. A var-> y debe ser mucho más cuidadoso con los punteros: NULL, aritmética de punteros, etc.), pero todos los demás son muy útiles.
Por ejemplo, puede usar el mismo nombre de variable de múltiples maneras en una sola función: (aquí un ejemplo de C ++, pero se aplica igualmente a muchos lenguajes)
Puedes ver aquí:
Otro gran punto de los iteradores de "iName" es que nunca indexo una matriz con el índice incorrecto, y si copio un ciclo dentro de otro ciclo no tengo que refactorizar una de las variables de índice del ciclo.
Compare este ejemplo irrealistamente simple:
(que es difícil de leer y a menudo conduce al uso de "i" donde se pretendía "j")
con:
(que es mucho más legible y elimina toda confusión sobre la indexación. Con el autocompletado en IDE modernos, esto también es rápido y fácil de escribir)
El siguiente beneficio es que los fragmentos de código no requieren ningún contexto para ser entendido. Puedo copiar dos líneas de código en un correo electrónico o un documento, y cualquiera que lea ese fragmento puede notar la diferencia entre todos los miembros, constantes, punteros, índices, etc. No tengo que agregar "oh, y tenga cuidado porque 'data' es un puntero a un puntero ", porque se llama 'ppData'.
Y por la misma razón, no tengo que mover mis ojos de una línea de código para entenderlo. No tengo que buscar a través del código para encontrar si 'datos' son locales, parámetros, miembros o constantes. No tengo que mover mi mano hacia el mouse para poder pasar el puntero sobre 'datos' y luego esperar a que aparezca una información sobre herramientas (que a veces nunca aparece). Por lo tanto, los programadores pueden leer y comprender el código significativamente más rápido, porque no pierden el tiempo buscando arriba y abajo o esperando.
El prefijo 'm' también evita la notación "this->" fea y prolija (IMHO) y la inconsistencia que garantiza (incluso si tiene cuidado, generalmente terminará con una mezcla de 'this-> data' y 'datos' en la misma clase, porque nada impone una ortografía coherente del nombre).
'esta' notación está destinada a resolver la ambigüedad , pero ¿por qué alguien escribiría deliberadamente código que puede ser ambiguo? La ambigüedad será conducir a un error, tarde o temprano. Y en algunos idiomas 'esto' no se puede usar para miembros estáticos, por lo que debe introducir 'casos especiales' en su estilo de codificación. Prefiero tener una sola regla de codificación simple que se aplique en todas partes: explícita, inequívoca y coherente.
El último beneficio importante es con Intellisense y autocompletado. Intente utilizar Intellisense en un formulario de Windows para encontrar un evento; debe desplazarse por cientos de métodos misteriosos de clase base a los que nunca necesitará llamar para encontrar los eventos. Pero si cada evento tuviera un prefijo "e", aparecerían automáticamente en un grupo bajo "e". Por lo tanto, el prefijo funciona para agrupar los miembros, concursos, eventos, etc. en la lista de intellisense, lo que hace que sea mucho más rápido y fácil encontrar los nombres que desea. (Por lo general, un método puede tener alrededor de 20-50 valores (locales, parámetros, miembros, concursos, eventos) que son accesibles en su alcance. Pero después de escribir el prefijo (quiero usar un índice ahora, entonces escribo 'i. .. '), se me presentan solo 2-5 opciones de autocompletar.
Soy un programador perezoso, y la convención anterior me ahorra mucho trabajo. Puedo codificar más rápido y cometo muchos menos errores porque sé cómo se deben usar todas las variables.
Argumentos en contra
Entonces, ¿cuáles son los contras? Los argumentos típicos contra los prefijos son:
"Los esquemas de prefijos son malos / malos" . Estoy de acuerdo en que "m_lpsz" y sus personajes están mal pensados y son completamente inútiles. Es por eso que aconsejaría usar una notación bien diseñada diseñada para cumplir con sus requisitos, en lugar de copiar algo que sea inapropiado para su contexto. (Use la herramienta adecuada para el trabajo).
"Si cambio el uso de algo, tengo que cambiarle el nombre" . Sí, por supuesto que sí, de eso se trata la refactorización, y por qué los IDE tienen herramientas de refactorización para hacer este trabajo de manera rápida y sin dolor. Incluso sin prefijos, cambiar el uso de una variable casi con certeza significa que su nombre debe cambiarse.
"Los prefijos solo me confunden" . Al igual que todas las herramientas hasta que aprenda a usarlas. Una vez que su cerebro se haya acostumbrado a los patrones de nomenclatura, filtrará la información automáticamente y realmente no le importará que los prefijos ya estén allí. Pero tiene que usar un esquema como este sólidamente durante una semana o dos antes de que realmente se vuelva "fluido". Y es entonces cuando muchas personas miran el código antiguo y comienzan a preguntarse cómo se las arreglaron sin un buen esquema de prefijos.
"Solo puedo mirar el código para resolver esto" . Sí, pero no necesita perder el tiempo buscando en otra parte del código o recordando cada pequeño detalle cuando la respuesta está justo en el punto en que su ojo ya está enfocado.
(Parte de) esa información se puede encontrar simplemente esperando que aparezca una información sobre herramientas en mi variable . Si. Cuando sea compatible, para algunos tipos de prefijos, cuando su código se compila limpiamente, después de una espera, puede leer una descripción y encontrar la información que el prefijo habría transmitido instantáneamente. Siento que el prefijo es un enfoque más simple, más confiable y más eficiente.
"Es más escribir" . De Verdad? ¿Un personaje entero más? O lo es: con las herramientas de autocompletado IDE, a menudo reducirá la escritura, porque cada carácter de prefijo reduce significativamente el espacio de búsqueda. Presione "e" y los tres eventos en su clase aparecerán en intellisense. Presione "c" y las cinco constantes se enumeran.
"Puedo usar en
this->
lugar dem
" . Bueno, si puedes. ¡Pero ese es un prefijo mucho más feo y más detallado! Solo conlleva un riesgo mucho mayor (especialmente en equipos) porque para el compilador es opcional y, por lo tanto, su uso es con frecuencia inconsistente.m
por otro lado es breve, claro, explícito y no opcional, por lo que es mucho más difícil cometer errores al usarlo.fuente
z
sea muy útil en un lenguaje como C ++ donde ese tipo de detalle de implementación de bajo nivel debería encapsularse en una clase, pero en C (donde la terminación cero es una distinción importante) estoy de acuerdo con usted. OMI, cualquier esquema que usemos debe adaptarse según sea necesario para satisfacer nuestras propias necesidades. Por lo tanto, si la terminación cero afecta el uso de la variable, no hay nada de malo en declarar "z" como un prefijo útil.The most important case is "p" for pointer (because the usage changes from var. to var-> and you have to be much more careful with pointers.
Estoy totalmente en desacuerdo. Si uso mal un puntero, simplemente no se compilará (void*
aunque puede ser una excepción para los punteros dobles). Y todo lo->
demás.
es suficiente para decirme que es un puntero. Además, si está utilizando autocompletar, su editor probablemente tenga información sobre herramientas de declaración, lo que elimina la necesidad de prefijar información variable. De todos modos, buena respuesta.Generalmente no uso un prefijo para las variables miembro.
Solía usar un
m
prefijo, hasta que alguien señalado que "C ++ ya tiene un prefijo estándar para el acceso de miembros:this->
.Entonces eso es lo que uso ahora. Es decir, cuando hay ambigüedad , agrego el
this->
prefijo, pero generalmente no existe ambigüedad, y puedo referirme directamente al nombre de la variable.Para mí, eso es lo mejor de ambos mundos. Tengo un prefijo que puedo usar cuando lo necesito, y soy libre de omitirlo siempre que sea posible.
Por supuesto, el contador obvio de esto es "sí, pero no se puede ver de un vistazo si una variable es un miembro de la clase o no".
A lo que digo "¿y qué? Si necesitas saber eso, tu clase probablemente tiene demasiado estado. O la función es demasiado grande y complicada".
En la práctica, he descubierto que esto funciona extremadamente bien. Como beneficio adicional, me permite promocionar una variable local a un miembro de la clase (o al revés) fácilmente, sin tener que cambiarle el nombre.
Y lo mejor de todo, ¡es consistente! No tengo que hacer nada especial ni recordar ninguna convención para mantener la coherencia.
Por cierto, no debes usar guiones bajos para los miembros de tu clase. Te acercas incómodamente a los nombres reservados por la implementación.
El estándar reserva todos los nombres que comienzan con un guión bajo o guión bajo seguido de mayúscula. También reserva todos los nombres que comienzan con un solo guión bajo en el espacio de nombres global .
Por lo tanto, un miembro de la clase con un guión bajo seguido de una letra minúscula es legal, pero tarde o temprano harás lo mismo con un identificador que comience con mayúscula o, de lo contrario, romperás una de las reglas anteriores.
Por lo tanto, es más fácil evitar los guiones bajos. Utilice un guión bajo de prefijo , o un prefijo
m_
o simplementem
si desea codificar el alcance en el nombre de la variable.fuente
this->
si necesita especificar que es una variable miembro, o no, eso también es bueno.this->
significa.Prefiero los subrayados de postfix, como tales:
fuente
vector<int> v_;
y escribirv_.push_back(5)
es bastante feo tambiénÚltimamente he estado tendiendo a preferir el prefijo m_ en lugar de no tener ningún prefijo, las razones no son tanto importantes como para marcar las variables miembro, sino que evitan la ambigüedad, digamos que tiene un código como:
void set_foo(int foo) { foo = foo; }
La causa no funciona, solo se
foo
permite una . Entonces sus opciones son:this->foo = foo;
No me gusta, ya que causa sombreado de parámetros, ya no puede usar
g++ -Wshadow
advertencias, también es más largo escribir entoncesm_
. También te encuentras con conflictos de nombres entre variables y funciones cuando tienes ayint foo;
aint foo();
.foo = foo_;
ofoo = arg_foo;
Lo he estado usando durante un tiempo, pero hace que las listas de argumentos sean feas, la documentación no debería tener que ver con la desambiguación del nombre en la implementación. Los conflictos de nombres entre variables y funciones también existen aquí.
m_foo = foo;
La documentación de API se mantiene limpia, no obtienes ambigüedad entre las funciones y las variables miembro y es más corto de escribir en ese momento
this->
. La única desventaja es que hace que las estructuras POD sean feas, pero como las estructuras POD no sufren la ambigüedad del nombre en primer lugar, no es necesario usarlo con ellas. Tener un prefijo único también facilita algunas operaciones de búsqueda y reemplazo.foo_ = foo;
La mayoría de las ventajas de
m_
aplicar, pero la rechazo por razones estéticas, un guión bajo o de cola solo hace que la variable se vea incompleta y desequilibrada.m_
solo se ve mejor. El usom_
también es más extensible, ya que puede usarlog_
para globales ys_
para estadísticas.PD: La razón por la que no se ve
m_
en Python o Ruby es porque ambos idiomas imponen su propio prefijo, Ruby usa@
para las variables miembro y Python lo requiereself.
.fuente
foo
solo para miembros y en su lugar usar nombres simples o cortos para parámetros u otros locales / descartables, comoint f
; o (b) prefija los parámetros u otros locales con algo. buen punto rem_
y vainas, sin embargo; Independientemente, he llegado a preferir seguir ambas pautas, en su mayor parte.Al leer una función miembro, saber quién "posee" cada variable es absolutamente esencial para comprender el significado de la variable. En una función como esta:
... es bastante fácil ver de dónde provienen las manzanas y los plátanos, pero ¿qué pasa con las uvas, melones y papas? ¿Deberíamos buscar en el espacio de nombres global? En la declaración de clase? ¿Es la variable un miembro de este objeto o un miembro de la clase de este objeto? Sin saber la respuesta a estas preguntas, no puede entender el código. Y en una función más larga, incluso las declaraciones de variables locales como manzanas y plátanos pueden perderse en la confusión.
Al anteponer una etiqueta consistente para globales, variables miembro y variables miembro estáticas (quizás g_, m_ y s_ respectivamente) se aclara la situación al instante.
Al principio, esto puede llevar un tiempo acostumbrarse, pero luego, ¿qué no tiene la programación? Hubo un día en que incluso {y} te parecían extraños. Y una vez que te acostumbras a ellos, te ayudan a entender el código mucho más rápido.
(Usar "this->" en lugar de m_ tiene sentido, pero es aún más largo y visualmente perjudicial. No lo veo como una buena alternativa para marcar todos los usos de las variables miembro).
Una posible objeción al argumento anterior sería extender el argumento a los tipos. También podría ser cierto que conocer el tipo de variable "es absolutamente esencial para comprender el significado de la variable". Si es así, ¿por qué no agregar un prefijo a cada nombre de variable que identifica su tipo? Con esa lógica, terminas con la notación húngara. Pero mucha gente encuentra la notación húngara laboriosa, fea y poco útil.
Húngaro haceCuéntanos algo nuevo sobre el código. Ahora entendemos que hay varios modelos implícitos en la función Foo :: bar (). El problema con el código ahora es que el valor de la información agregada por los prefijos húngaros es pequeño en relación con el costo visual. El sistema de tipos C ++ incluye muchas características para ayudar a los tipos a funcionar bien juntos o para generar una advertencia o error del compilador. El compilador nos ayuda a lidiar con los tipos; no necesitamos notación para hacerlo. Podemos inferir fácilmente que las variables en Foo :: bar () son probablemente numéricas, y si eso es todo lo que sabemos, es lo suficientemente bueno para obtener una comprensión general de la función. Por lo tanto, el valor de conocer el tipo preciso de cada variable es relativamente bajo. Sin embargo, la fealdad de una variable como "s_dSpuds" (o incluso "dSpuds") es excelente. Entonces,
fuente
No puedo decir qué tan amplio es, pero hablando personalmente, siempre (y siempre he) prefijado mis variables miembro con 'm'. P.ej:
Es la única forma de prefijo que uso (soy una notación muy antihúngara) pero me ha sido de gran utilidad a lo largo de los años. Como comentario aparte, generalmente detesto el uso de guiones bajos en los nombres (o en cualquier otro lugar), pero hago una excepción para los nombres de macro de preprocesador, ya que generalmente son mayúsculas.
fuente
a
en ese escenario; de lo contrario, no lo estás haciendo bien.mApData
(m
prefijo, entonces el nombre de la variable esapData
).La razón principal de un prefijo de miembro es distinguir entre una función miembro local y una variable miembro con el mismo nombre. Esto es útil si usa getters con el nombre de la cosa.
Considerar:
La variable miembro no podría llamarse full_name en este caso. Debe cambiar el nombre de la función miembro a get_full_name () o decorar la variable miembro de alguna manera.
fuente
foo.name()
es mucho más legible quefoo.get_name()
en mi opinión.No creo que una sintaxis tenga un valor real sobre otra. Todo se reduce, como usted mencionó, a la uniformidad en los archivos de origen.
El único punto donde encuentro interesantes tales reglas es cuando necesito 2 cosas nombradas de manera idéntica, por ejemplo:
Lo uso para diferenciar los dos. También cuando envuelvo llamadas, como desde Windows Dll, RecvPacket (...) del Dll podría estar envuelto en RecvPacket (...) en mi código. En estas ocasiones en particular, usar un prefijo como "_" podría hacer que los dos se parezcan, sean fáciles de identificar cuál es cuál, pero diferentes para el compilador
fuente
Algunas respuestas se centran en refactorizar, en lugar de nombrar convenciones, como la forma de mejorar la legibilidad. No siento que uno pueda reemplazar al otro.
Conozco programadores que se sienten incómodos con el uso de declaraciones locales; prefieren colocar todas las declaraciones en la parte superior de un bloque (como en C), para que sepan dónde encontrarlas. Descubrí que, cuando el alcance lo permite, declarar variables donde se usan por primera vez disminuye el tiempo que paso mirando hacia atrás para encontrar las declaraciones. (Esto es cierto para mí incluso para funciones pequeñas). Eso me facilita la comprensión del código que estoy viendo.
Espero que quede bastante claro cómo se relaciona esto con las convenciones de nomenclatura de miembros: cuando los miembros tienen un prefijo uniforme, nunca tengo que mirar atrás; Sé que la declaración ni siquiera se encontrará en el archivo fuente.
Estoy seguro de que no comencé a preferir estos estilos. Sin embargo, con el tiempo, trabajando en entornos donde se usaban constantemente, optimicé mi pensamiento para aprovecharlos. Creo que es posible que muchas personas que actualmente se sienten incómodas con ellos también los prefieran, dado el uso constante.
fuente
Esas convenciones son solo eso. La mayoría de las tiendas usan convenciones de código para facilitar la legibilidad del código para que cualquiera pueda ver fácilmente un fragmento de código y descifrar rápidamente entre elementos como los miembros públicos y privados.
fuente
class
de cuyos miembros sonprivate
/protected
o PODstruct
s cuyas variables sonpublic
(y a menudo tambiénconst
). Por lo tanto, nunca necesito preguntarme sobre el nivel de acceso de un miembro determinado.Eso es generalmente porque no hay prefijo . El compilador necesita suficiente información para resolver la variable en cuestión, ya sea un nombre único debido al prefijo o mediante la
this
palabra clave.Entonces, sí, creo que los prefijos siguen siendo útiles. Yo, por mi parte, preferiría escribir '_' para acceder a un miembro en lugar de 'this->'.
fuente
struct Foo { int x; Foo(int x) : x(x) { ... } };
Foo(int x, bool blee) : x(x) { if (blee) x += bleecount; } // oops, forgot this->
. Prefiero llamar a mis variables miembro algo útil y luego darles parámetros de constructor que coincidan con los nombres abreviados:Foo(int f) : foo(f) {...}
Otros lenguajes usarán convenciones de codificación, solo tienden a ser diferentes. C #, por ejemplo, tiene probablemente dos estilos diferentes que las personas tienden a usar, ya sea uno de los métodos de C ++ (_variable, mVariable u otro prefijo como la notación húngara), o lo que yo llamo el método StyleCop.
Al final, se convierte en lo que la gente sabe y lo que se ve mejor. Personalmente, creo que el código es más legible sin la notación húngara, pero puede ser más fácil encontrar una variable con intellisense, por ejemplo, si se adjunta la notación húngara.
En mi ejemplo anterior, no necesitas un prefijo m para las variables miembro porque prefijas tu uso con esto. indica lo mismo en un método forzado por el compilador.
Esto no significa necesariamente que los otros métodos sean malos, las personas se adhieren a lo que funciona.
fuente
Cuando tiene un método grande o bloques de código, es conveniente saber de inmediato si utiliza una variable local o un miembro. ¡Es para evitar errores y para una mejor claridad!
fuente
-Wshadow
OMI, esto es personal. No estoy poniendo ningún prefijo en absoluto. De todos modos, si se pretende que el código sea público, creo que debería tener algunos prefijos, por lo que puede ser más legible.
A menudo, las grandes empresas utilizan sus propias "reglas de desarrollo".
Por cierto, el más divertido pero más inteligente que vi fue DRY KISS (No te repitas. Mantenlo simple, estúpido). :-)
fuente
Como ya han dicho otros, la importancia es ser coloquial (adaptar estilos y convenciones de nombres a la base de código en la que está escribiendo) y ser coherente.
Durante años, he trabajado en una gran base de código que usa tanto la convención "this->" como el postfix notación de subrayado para las variables miembro. A lo largo de los años también he trabajado en proyectos más pequeños, algunos de los cuales no tenían ningún tipo de convención para nombrar variables miembro, y otros que tenían diferentes convenciones para nombrar variables miembro. De esos proyectos más pequeños, he encontrado consistentemente que los que carecían de cualquier convención son los más difíciles de abordar y comprender rápidamente.
Soy muy anal-retentivo sobre los nombres. Agonizaré sobre el nombre que se atribuirá a una clase o variable hasta el punto de que, si no puedo encontrar algo que siento que es "bueno", elegiré nombrarlo como algo sin sentido y proporcionar un comentario que describa lo que realmente es es. De esa manera, al menos el nombre significa exactamente lo que pretendo que signifique: nada más y nada menos. Y a menudo, después de usarlo por un tiempo, descubro cuál debería ser realmente el nombre y puedo retroceder y modificar o refactorizar adecuadamente.
Un último punto sobre el tema de un IDE haciendo el trabajo: todo es bueno y bueno, pero los IDE a menudo no están disponibles en entornos donde he realizado el trabajo más urgente. A veces, lo único disponible en ese momento es una copia de 'vi'. Además, he visto muchos casos donde la finalización del código IDE ha propagado la estupidez, como la ortografía incorrecta en los nombres. Por lo tanto, prefiero no tener que depender de una muleta IDE.
fuente
La idea original para los prefijos en las variables miembro de C ++ era almacenar información de tipo adicional que el compilador no conocía. Entonces, por ejemplo, podría tener una cadena que tiene una longitud fija de caracteres, y otra que es variable y terminada por un '\ 0'. Para el compilador, ambos son
char *
, pero si intentas copiar de uno a otro, te encontrarás con grandes problemas. Entonces, fuera de mi cabeza,char *aszFred = "Hi I'm a null-terminated string";
char *arrWilma = {'O', 'o', 'p', 's'};
donde "asz" significa que esta variable es "cadena ascii (terminada en cero) y" arr "significa que esta variable es una matriz de caracteres.
Entonces sucede la magia. El compilador estará perfectamente satisfecho con esta declaración:
strcpy(arrWilma, aszFred);
Pero usted, como humano, puede mirarlo y decir "oye, esas variables no son realmente del mismo tipo, no puedo hacer eso".
Desafortunadamente, muchos lugares usan estándares como "m_" para las variables miembro, "i" para enteros, sin importar cómo se usen, "cp" para los punteros de caracteres. En otras palabras, están duplicando lo que el compilador sabe y haciendo que el código sea difícil de leer al mismo tiempo. Creo que esta práctica perniciosa debería estar prohibida por ley y sujeta a severas sanciones.
Finalmente, hay dos puntos que debo mencionar:
fuente
Nuestro proyecto siempre ha usado "its" como prefijo para los datos de los miembros y "the" como prefijo para los parámetros, sin prefijo para los locales. Es un poco cursi, pero fue adoptado por los primeros desarrolladores de nuestro sistema porque vieron que algunas bibliotecas comerciales de origen lo utilizamos como una convención en ese momento (XVT o RogueWave, tal vez ambas). Entonces obtendrías algo como esto:
La gran razón que veo para los prefijos de alcance (y no para otros, odio la notación húngara) es que evita que te metas en problemas escribiendo código donde crees que te estás refiriendo a una variable, pero realmente te estás refiriendo a otra variable con el mismo nombre definido en el ámbito local. También evita el problema de crear nombres de variables para representar ese mismo concepto, pero con diferentes ámbitos, como en el ejemplo anterior. En ese caso, tendría que encontrar algún prefijo o nombre diferente para el parámetro "theName" de todos modos, ¿por qué no hacer una regla coherente que se aplique en todas partes?
Simplemente usar esto-> no es lo suficientemente bueno: no estamos tan interesados en reducir la ambigüedad como en reducir los errores de codificación, y enmascarar nombres con identificadores de ámbito local puede ser una molestia. De acuerdo, algunos compiladores pueden tener la opción de generar advertencias para casos en los que haya enmascarado el nombre en un ámbito más amplio, pero esas advertencias pueden convertirse en una molestia si está trabajando con un gran conjunto de bibliotecas de terceros que han elegido nombres para variables no utilizadas que ocasionalmente chocan con las suyas.
En cuanto a la it / the en sí: honestamente, me resulta más fácil escribir que los guiones bajos (como mecanógrafo táctil, evito los guiones bajos siempre que sea posible, demasiado estiramiento de las filas de inicio), y me parece más legible que un guión misterioso.
fuente
Lo uso porque Intellisense de VC ++ no puede decir cuándo mostrar miembros privados cuando acceden fuera de la clase. La única indicación es un pequeño símbolo de "bloqueo" en el icono de campo en la lista Intellisense. Simplemente facilita la identificación de miembros privados (campos) más fácil. También es un hábito de C # para ser honesto.
fuente
Creo que, si necesita prefijos para distinguir a los miembros de la clase de los parámetros de la función miembro y las variables locales, la función es demasiado grande o las variables tienen un nombre incorrecto. Si no cabe en la pantalla para que pueda ver fácilmente qué es qué, refactorice.
Dado que a menudo se declaran lejos de donde se usan, creo que las convenciones de nomenclatura para las constantes globales (y las variables globales, aunque en la OMI rara vez es necesario usarlas) tienen sentido. Pero por lo demás, no veo mucha necesidad.
Dicho esto, solía poner un guión bajo al final de todos los miembros de la clase privada. Como todos mis datos son privados, esto implica que los miembros tienen un guión bajo. Por lo general, ya no hago esto en nuevas bases de código, pero dado que, como programador, trabajas principalmente con código antiguo, todavía lo hago mucho. No estoy seguro de si mi tolerancia a este hábito proviene del hecho de que solía hacerlo siempre y todavía lo hago regularmente o si realmente tiene más sentido que el marcado de las variables miembro.
fuente
En python, los guiones bajos dobles se utilizan para emular a miembros privados. Para más detalles ver esta respuesta
fuente
Es útil diferenciar entre las variables miembro y las variables locales debido a la gestión de la memoria. En términos generales, las variables miembro asignadas al almacenamiento dinámico deben destruirse en el destructor, mientras que las variables locales asignadas al almacenamiento dinámico deben destruirse dentro de ese ámbito. La aplicación de una convención de nomenclatura a las variables miembro facilita la gestión correcta de la memoria.
fuente
Code Complete recomienda m_varname para las variables miembro.
Si bien nunca pensé que la notación m_ fuera útil, le daría peso a la opinión de McConnell en la construcción de un estándar.
fuente
Casi nunca uso prefijos delante de mis nombres de variables. Si está utilizando un IDE lo suficientemente decente, debería poder refactorizar y encontrar referencias fácilmente. Utilizo nombres muy claros y no temo tener nombres largos y variables. Nunca he tenido problemas con el alcance tampoco con esta filosofía.
La única vez que uso un prefijo sería en la línea de firma. Prefijaré los parámetros a un método con _ para poder programar a la defensiva alrededor de ellos.
fuente
Nunca deberías necesitar ese prefijo. Si dicho prefijo le ofrece alguna ventaja, su estilo de codificación en general necesita arreglarse, y no es el prefijo lo que impide que su código sea claro. Los nombres típicos de variables malas incluyen "otro" o "2". No arregla eso al exigir que sea más, lo arregla haciendo que el desarrollador piense qué está haciendo esa variable allí en el contexto de esa función. Quizás se refería a remoteSide, o newValue, o secondTestListener o algo en ese ámbito.
Es un anacronismo efectivo que todavía se propaga demasiado. Deja de prefijar tus variables y dales nombres propios cuya claridad refleje cuánto tiempo se usan. Hasta 5 líneas podría llamarlo "i" sin confusión; más allá de 50 líneas necesitas un nombre bastante largo.
fuente
Me gusta que los nombres de las variables solo den un significado a los valores que contienen, y dejen el nombre de cómo se declaran / implementan. Quiero saber qué significa el valor, punto. Tal vez he realizado más de una cantidad promedio de refactorización, pero encuentro que incorporar cómo se implementa algo en el nombre hace que la refactorización sea más tediosa de lo que debe ser. Los prefijos que indican dónde o cómo se declaran los miembros del objeto son específicos de la implementación.
La mayoría de las veces, no me importa si el Rojo es una enumeración, una estructura o lo que sea, y si la función es tan grande que no puedo recordar si el color se declaró localmente o es un miembro, probablemente sea hora de romper la función en unidades lógicas más pequeñas.
Si su complejidad ciclomática es tan grande que no puede realizar un seguimiento de lo que sucede en el código sin pistas específicas de implementación integradas en los nombres de las cosas, lo más probable es que necesite reducir la complejidad de su función / método.
Principalmente, solo uso 'this' en constructores e inicializadores.
fuente
Uso m_ para las variables miembro solo para aprovechar Intellisense y la funcionalidad IDE relacionada. Cuando estoy codificando la implementación de una clase, puedo escribir m_ y ver el cuadro combinado con todos los miembros de m_ agrupados.
Pero podría vivir sin m_ sin problemas, por supuesto. Es solo mi estilo de trabajo.
fuente
this->
Según las NORMAS DE CODIFICACIÓN DEL VEHÍCULO AÉREO DE COMBATE DE HUELGA CONJUNTA (diciembre de 2005):
Por lo tanto, el prefijo "m" se vuelve inútil ya que todos los datos deben ser privados.
Pero es una buena costumbre usar el prefijo p antes de un puntero, ya que es una variable peligrosa.
fuente
Muchas de esas convenciones son de una época sin editores sofisticados. Recomendaría usar un IDE adecuado que le permita colorear todo tipo de variable. El color es mucho más fácil de detectar que cualquier prefijo.
Si necesita obtener aún más detalles sobre una variable, cualquier IDE moderno debería poder mostrárselo moviendo el cursor o el cursor sobre él. Y si utiliza una variable de forma incorrecta (por ejemplo, un puntero con el operador.) Obtendrá un error, de todos modos.
fuente