Muitos códigos C ++ usam convenções sintáticas para marcar variáveis de membro. Exemplos comuns incluem
- m_ memberName para membros públicos (onde os membros públicos são usados)
- _ memberName para membros privados ou todos os membros
Outros tentam impor o uso deste-> membro sempre que uma variável de membro é usada.
Na minha experiência, a maioria das bases de código maiores falha ao aplicar essas regras de forma consistente.
Em outros idiomas, essas convenções são muito menos difundidas. Só o vejo ocasionalmente em código Java ou C #. Eu acho que nunca vi isso no código Ruby ou Python. Portanto, parece haver uma tendência com linguagens mais modernas para não usar marcação especial para variáveis-membro.
Essa convenção ainda é útil hoje em C ++ ou é apenas um anacronismo? Especialmente porque é usado de maneira inconsistente nas bibliotecas. Os outros idiomas não mostraram que se pode prescindir de prefixos de membros?
fonte
self._something = 1
.this->member
no código Python. Em Python, normalmente seriaself.member
e não é apenas uma convenção, é exigido pela linguagem.Respostas:
Você precisa ter cuidado ao usar um sublinhado à esquerda. Um sublinhado à esquerda antes de uma letra maiúscula em uma palavra ser reservada. Por exemplo:
_Foo
_EU
são todas as palavras reservadas enquanto
_foo
_eu
não são. Há outras situações em que sublinhados à esquerda antes de letras minúsculas não são permitidos. No meu caso específico, achei o _L reservado pelo Visual C ++ 2005 e o conflito criou alguns resultados inesperados.
Estou em dúvida sobre o quanto é útil marcar variáveis locais.
Aqui está um link sobre quais identificadores são reservados: Quais são as regras sobre o uso de um sublinhado em um identificador C ++?
fonte
Sou a favor de prefixos bem feitos .
Eu acho que a notação húngara (do sistema) é responsável pela maior parte do "mau rap" que os prefixos recebem.
Essa notação é inútil em linguagens fortemente tipadas, por exemplo, em C ++ "lpsz" para dizer que sua string é um ponteiro longo para uma string terminada em nulo, quando: arquitetura segmentada é história antiga, as strings C ++ são por ponteiros de convenção comuns para terminação nula matrizes de caracteres e não é tão difícil saber que "customerName" é uma string!
No entanto, eu uso prefixos para especificar o uso de uma variável (essencialmente "Aplicativos Húngaro", embora prefira evitar o termo Húngaro por ter uma associação ruim e injusta com o Sistema Húngaro), e esse é um método muito útil para economizar tempo e abordagem de redução de erros .
Eu uso:
Onde desejo esclarecer o tipo , uso sufixos padrão (por exemplo, List, ComboBox, etc).
Isso torna o programador ciente do uso da variável sempre que a vê / usa. Provavelmente, o caso mais importante é "p" para ponteiro (porque o uso muda de var. Para var-> e você precisa ter muito mais cuidado com ponteiros - NULLs, aritmética de ponteiros etc.), mas todos os outros são muito úteis.
Por exemplo, você pode usar o mesmo nome de variável de várias maneiras em uma única função: (aqui um exemplo de C ++, mas se aplica igualmente a muitos idiomas)
Você pode ver aqui:
Outro ponto importante dos iteradores "iName" é que nunca indexo uma matriz com o índice errado e, se eu copiar um loop dentro de outro loop, não preciso refatorar uma das variáveis de índice do loop.
Compare este exemplo irrealisticamente simples:
(difícil de ler e geralmente leva ao uso de "i" onde "j" foi planejado)
com:
(que é muito mais legível e elimina toda a confusão sobre a indexação. Com o preenchimento automático nos IDEs modernos, isso também é rápido e fácil de digitar)
O próximo benefício é que os trechos de código não exigem que nenhum contexto seja entendido. Posso copiar duas linhas de código em um e-mail ou documento, e qualquer pessoa que esteja lendo esse trecho pode dizer a diferença entre todos os membros, constantes, ponteiros, índices etc. Não preciso adicionar "ah, e tenha cuidado porque 'data' é um ponteiro para um ponteiro ", porque é chamado 'ppData'.
E pelo mesmo motivo, não preciso desviar os olhos de uma linha de código para entender. Não preciso pesquisar o código para descobrir se 'data' é um local, parâmetro, membro ou constante. Não preciso mover minha mão para o mouse para poder passar o ponteiro do mouse sobre 'dados' e esperar uma dica (que às vezes nunca aparece) aparecer. Assim, os programadores podem ler e entender o código significativamente mais rápido, porque não perdem tempo pesquisando para cima e para baixo ou esperando.
O prefixo 'm' também evita a notação feia e prolixo "this->", e a inconsistência que ela garante (mesmo se você for cuidadoso, geralmente acabará com uma mistura de "this-> data" e 'data' na mesma classe, porque nada impõe uma ortografia consistente do nome).
A notação 'this' tem como objetivo resolver a ambiguidade - mas por que alguém escreveria deliberadamente um código que pode ser ambíguo? Ambigüidade vai levar a um bug, mais cedo ou mais tarde. E em alguns idiomas 'this' não pode ser usado para membros estáticos, então você deve introduzir 'casos especiais' no seu estilo de codificação. Prefiro ter uma única regra de codificação simples que se aplique a todos os lugares - explícita, inequívoca e consistente.
O último grande benefício é com o Intellisense e o preenchimento automático. Tente usar o Intellisense em um Windows Form para encontrar um evento - você precisa percorrer centenas de métodos misteriosos de classe base que você nunca precisará chamar para encontrar os eventos. Mas se cada evento tivesse um prefixo "e", eles seriam listados automaticamente em um grupo em "e". Assim, a prefixação trabalha para agrupar os membros, consts, eventos etc. na lista do intellisense, tornando muito mais rápido e fácil encontrar os nomes que você deseja. (Geralmente, um método pode ter entre 20 e 50 valores (locais, parâmetros, membros, consts, eventos) acessíveis em seu escopo. Mas, depois de digitar o prefixo (eu quero usar um índice agora, digito 'i. .. '), são apresentadas apenas 2-5 opções de preenchimento automático. A' digitação extra '
Sou um programador preguiçoso, e a convenção acima me poupa muito trabalho. Posso codificar mais rapidamente e cometo muito menos erros, porque sei como todas as variáveis devem ser usadas.
Argumentos contra
Então, quais são os contras? Os argumentos típicos contra prefixos são:
"Esquemas de prefixo são ruins / maus" . Concordo que "m_lpsz" e seu tipo são mal pensados e totalmente inúteis. É por isso que aconselho usar uma notação bem projetada, projetada para suportar seus requisitos, em vez de copiar algo inapropriado para o seu contexto. (Use a ferramenta certa para o trabalho).
"Se eu mudar o uso de algo, tenho que renomeá-lo" . Sim, é claro que sim, é disso que trata a refatoração e por que os IDEs têm ferramentas de refatoração para fazer esse trabalho de maneira rápida e indolor. Mesmo sem prefixos, alterar o uso de uma variável quase certamente significa que seu nome deve ser alterado.
"Prefixos me confundem" . Como todas as ferramentas até você aprender a usá-lo. Quando seu cérebro se acostumar com os padrões de nomeação, ele filtrará as informações automaticamente e você não se importará mais com os prefixos. Mas você tem que usar um esquema como esse solidamente por uma semana ou duas antes de se tornar realmente "fluente". E é aí que muitas pessoas olham para o código antigo e começam a se perguntar como conseguiram sem um bom esquema de prefixo.
"Eu posso apenas olhar o código para resolver essas coisas" . Sim, mas você não precisa perder tempo procurando em outro lugar no código ou lembrando-se de cada pequeno detalhe quando a resposta é certa no local em que seu olho já está focado.
(Algumas) informações podem ser encontradas apenas aguardando uma dica de ferramenta aparecer na minha variável . Sim. Onde houver suporte, para alguns tipos de prefixo, quando o código for compilado corretamente, após uma espera, você poderá ler uma descrição e encontrar as informações que o prefixo teria transmitido instantaneamente. Eu sinto que o prefixo é uma abordagem mais simples, mais confiável e mais eficiente.
"É mais digitado" . Realmente? Mais um personagem inteiro? Ou é: com as ferramentas de preenchimento automático do IDE, muitas vezes reduz a digitação, porque cada caractere de prefixo reduz significativamente o espaço de pesquisa. Pressione "e" e os três eventos de sua classe aparecerão no intellisense. Pressione "c" e as cinco constantes serão listadas.
"Eu posso usar em
this->
vez dem
" . Bem, sim, você pode. Mas esse é apenas um prefixo muito mais feio e mais detalhado! Somente ele apresenta um risco muito maior (especialmente em equipes) porque, para o compilador, é opcional e, portanto, seu uso é frequentemente inconsistente.m
por outro lado, é breve, claro, explícito e não opcional, por isso é muito mais difícil cometer erros ao usá-lo.fonte
z
seja muito útil em uma linguagem como C ++, onde esse tipo de detalhe de implementação de baixo nível deve ser encapsulado em uma classe, mas em C (onde terminação zero é uma distinção importante) eu concordo com você. Na IMO, qualquer esquema que usamos deve ser adaptado conforme necessário para melhor atender às nossas próprias necessidades - Portanto, se a terminação zero afeta o uso da variável, não há nada de errado em declarar "z" um prefixo ú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.
Eu discordo de todo o coração. Se eu usar um ponteiro errado, ele simplesmente não será compilado (void*
pode ser uma exceção para ponteiros duplos). E todo o->
mais.
é o suficiente para me dizer que é um ponteiro. Além disso, se você estiver usando o preenchimento automático, seu editor provavelmente terá dicas de ferramentas de declaração, eliminando a necessidade de prefixar informações variáveis. Independentemente, boa resposta.Eu geralmente não uso um prefixo para variáveis de membro.
Eu costumava usar um
m
prefixo, até que alguém apontou que "C ++ já tem um prefixo padrão para o acesso de membros:this->
.Então é isso que eu uso agora. Ou seja, quando há ambiguidade , adiciono o
this->
prefixo, mas geralmente não existe ambiguidade e posso me referir diretamente ao nome da variável.Para mim, esse é o melhor dos dois mundos. Eu tenho um prefixo que posso usar quando preciso e estou livre para deixá-lo de fora sempre que possível.
Obviamente, o contrário óbvio disso é "sim, mas você não pode ver rapidamente se uma variável é ou não um membro da classe".
Para o que eu digo "e daí? Se você precisa saber disso, sua classe provavelmente tem muito estado. Ou a função é muito grande e complicada".
Na prática, descobri que isso funciona extremamente bem. Como um bônus adicional, permite-me promover uma variável local para um membro da classe (ou vice-versa) facilmente, sem ter que renomeá-la.
E o melhor de tudo, é consistente! Não preciso fazer nada de especial nem lembrar de convenções para manter a consistência.
A propósito, você não deve usar sublinhados de destaque para os alunos. Você fica desconfortavelmente próximo dos nomes reservados pela implementação.
O padrão reserva todos os nomes começando com sublinhado duplo ou sublinhado, seguido de letra maiúscula. Ele também reserva todos os nomes começando com um único sublinhado no espaço para nome global .
Portanto, um membro da classe com um sublinhado à esquerda seguido de uma letra minúscula é legal, mas mais cedo ou mais tarde você fará o mesmo com um identificador que começa com maiúscula ou violará uma das regras acima.
Portanto, é mais fácil evitar os sublinhados principais. Use um sublinhado postfix, ou um
m_
ou apenasm
prefixo, se desejar codificar o escopo no nome da variável.fonte
this->
se você precisar especificar que é uma variável membro, ou não, isso também é bom.this->
significa.Prefiro sublinhados postfix, como:
fonte
vector<int> v_;
e escritav_.push_back(5)
é muito feio demaisUltimamente, tenho tendido a preferir o prefixo m_ em vez de não ter nenhum prefixo, o motivo não é tanto o fato de ser importante sinalizar variáveis de membro, mas evita a ambiguidade, digamos que você tenha um código como:
void set_foo(int foo) { foo = foo; }
A causa não funciona, apenas uma é
foo
permitida. Portanto, suas opções são:this->foo = foo;
Eu não gosto, pois causa sombreamento de parâmetro, você não pode mais usar
g++ -Wshadow
avisos, também é mais tempo digitar entãom_
. Você também ainda encontra conflitos de nomenclatura entre variáveis e funções quando tem umaint foo;
e aint foo();
.foo = foo_;
oufoo = arg_foo;
Utilizo isso há algum tempo, mas torna as listas de argumentos feias, a documentação não deveria lidar com a desambigüidade de nomes na implementação. Os conflitos de nomeação entre variáveis e funções também existem aqui.
m_foo = foo;
A documentação da API permanece limpa, você não tem ambiguidade entre funções e variáveis-membro e é mais curto para digitar
this->
. A única desvantagem é que isso torna as estruturas do POD feias, mas como as estruturas do POD não sofrem com a ambiguidade do nome em primeiro lugar, não é necessário usá-lo com elas. Ter um prefixo exclusivo também facilita algumas operações de pesquisa e substituição.foo_ = foo;
A maioria das vantagens se
m_
aplica, mas eu a rejeito por razões estéticas, um sublinhado à direita ou à esquerda apenas faz a variável parecer incompleta e desequilibrada.m_
apenas parece melhor. O usom_
também é mais extensível, como você pode usarg_
para globais es_
estáticos.PS: A razão pela qual você não vê
m_
no Python ou no Ruby é porque as duas linguagens aplicam o próprio prefixo, o Ruby usa@
para variáveis de membro e o Python exigeself.
.fonte
foo
apenas para membros e, em vez disso, use uma letra ou nomes abreviados para parâmetros ou outros locais / pessoas comuns, comoint f
; ou (b) prefixe os parâmetros ou outros locais com alguma coisa. bom ponto rem_
e pods, no entanto; Independentemente, cheguei à preferência de seguir essas duas diretrizes.Ao ler uma função de membro, saber quem "possui" cada variável é absolutamente essencial para entender o significado da variável. Em uma função como esta:
... é fácil ver de onde vêm as maçãs e as bananas, mas e as uvas, melões e batatas? Devemos procurar no espaço para nome global? Na declaração de classe? A variável é membro desse objeto ou membro da classe deste objeto? Sem saber a resposta para essas perguntas, você não consegue entender o código. E, em uma função mais longa, mesmo as declarações de variáveis locais como maçãs e bananas podem se perder no shuffle.
Anexar um rótulo consistente para globais, variáveis de membro e variáveis de membro estáticas (talvez g_, m_ e s_ respectivamente) esclarece instantaneamente a situação.
Isso pode levar algum tempo para se acostumar - mas então, o que na programação não? Houve um dia em que até {e} pareciam estranhos para você. E depois que você se acostuma, eles ajudam a entender o código muito mais rapidamente.
(Usar "this->" no lugar de m_ faz sentido, mas é ainda mais demorado e visualmente perturbador. Não a vejo como uma boa alternativa para marcar todos os usos de variáveis-membro.)
Uma possível objeção ao argumento acima seria estender o argumento para tipos. Também pode ser verdade que conhecer o tipo de uma variável "é absolutamente essencial para entender o significado da variável". Se é assim, por que não adicionar um prefixo a cada nome de variável que identifica seu tipo? Com essa lógica, você acaba com a notação húngara. Mas muitas pessoas acham a notação húngara trabalhosa, feia e inútil.
húngaro fazconte-nos algo novo sobre o código. Agora entendemos que existem várias conversões implícitas na função Foo :: bar (). O problema com o código agora é que o valor das informações adicionadas pelos prefixos húngaros é pequeno em relação ao custo visual. O sistema do tipo C ++ inclui muitos recursos para ajudar os tipos a trabalharem bem juntos ou para gerar um aviso ou erro do compilador. O compilador nos ajuda a lidar com tipos - não precisamos de notação para isso. Podemos inferir com bastante facilidade que as variáveis em Foo :: bar () provavelmente são numéricas e, se isso é tudo o que sabemos, é bom o suficiente para obter uma compreensão geral da função. Portanto, o valor de conhecer o tipo preciso de cada variável é relativamente baixo. No entanto, a feiúra de uma variável como "s_dSpuds" (ou mesmo apenas "dSpuds") é grande. Assim,
fonte
Não sei dizer o quanto isso é generalizado, mas falando pessoalmente, sempre (e sempre) prefixo minhas variáveis de membro com 'm'. Por exemplo:
É a única forma de prefixo que eu uso (sou uma notação muito anti-húngara), mas ela me manteve em boa posição ao longo dos anos. Como um aparte, geralmente detesto o uso de sublinhados em nomes (ou em qualquer outro lugar), mas faço uma exceção para nomes de macro de pré-processador, pois eles geralmente são todos em maiúsculas.
fonte
a
cenário - você não está fazendo certo de outra maneira.mApData
(m
prefixo, o nome da variável éapData
).O principal motivo para um prefixo de membro é distinguir entre uma função de membro local e uma variável de membro com o mesmo nome. Isso é útil se você usar getters com o nome da coisa.
Considerar:
A variável de membro não pôde ser chamada full_name nesse caso. Você precisa renomear a função de membro para get_full_name () ou decorar a variável de membro de alguma forma.
fonte
foo.name()
é muito mais legível do quefoo.get_name()
na minha opinião.Eu não acho que uma sintaxe tenha valor real sobre outra. Tudo se resume, como você mencionou, à uniformidade nos arquivos de origem.
O único ponto em que acho essas regras interessantes é quando preciso de duas coisas nomeadas idênticas, por exemplo:
Eu o uso para diferenciar os dois. Além disso, quando envolvo chamadas, como na DLL do Windows, o RecvPacket (...) da DLL pode ser agrupado em RecvPacket (...) no meu código. Nessas ocasiões, o uso de um prefixo como "_" pode tornar os dois parecidos, fácil de identificar qual é qual, mas diferente para o compilador
fonte
Algumas respostas se concentram na refatoração, em vez de convenções de nomenclatura, como o caminho para melhorar a legibilidade. Não acho que um possa substituir o outro.
Conheço programadores que se sentem desconfortáveis com o uso de declarações locais; eles preferem colocar todas as declarações no topo de um bloco (como em C), para saber onde encontrá-las. Descobri que, onde o escopo permite, declarar variáveis onde são usadas pela primeira vez diminui o tempo que gasto olhando para trás para encontrar as declarações. (Isso é verdade para mim, mesmo para pequenas funções.) Isso facilita a compreensão do código que estou vendo.
Espero que seja claro o suficiente como isso se relaciona às convenções de nomenclatura de membros: quando os membros são uniformemente prefixados, nunca preciso olhar para trás; Eu sei que a declaração nem será encontrada no arquivo de origem.
Tenho certeza de que não comecei a preferir esses estilos. No entanto, com o tempo, trabalhando em ambientes onde eles eram usados de forma consistente, eu otimizei meu pensamento para tirar proveito deles. Eu acho que é possível que muitas pessoas que atualmente se sentem desconfortáveis com eles também venham a preferi-los, dado o uso consistente.
fonte
Essas convenções são exatamente isso. A maioria das lojas usa convenções de código para facilitar a legibilidade do código, para que qualquer pessoa possa ver facilmente um pedaço de código e decifrar rapidamente entre itens como membros públicos e privados.
fonte
class
es todos de cujos membros sãoprivate
/protected
ou PODstruct
s cujas variáveis sãopublic
(e geralmente tambémconst
). Portanto, nunca preciso me perguntar sobre o nível de acesso de qualquer membro.Isso geralmente ocorre porque não há prefixo . O compilador precisa de informações suficientes para resolver a variável em questão, seja um nome exclusivo por causa do prefixo ou por meio da
this
palavra - chave.Então, sim, acho que os prefixos ainda são úteis. Eu, por exemplo, preferiria digitar '_' para acessar um membro em vez de 'this->'.
fonte
struct Foo { int x; Foo(int x) : x(x) { ... } };
Foo(int x, bool blee) : x(x) { if (blee) x += bleecount; } // oops, forgot this->
eu prefiro chamar de meu variáveis de membro algo útil e, em seguida, dar parâmetros do construtor que correspondem lhes nomes abreviados:Foo(int f) : foo(f) {...}
Outros idiomas usarão convenções de codificação, apenas tendem a ser diferentes. O C #, por exemplo, provavelmente possui dois estilos diferentes que as pessoas tendem a usar, um dos métodos C ++ (_variable, mVariable ou outro prefixo, como notação húngara), ou o que eu me refiro como o método StyleCop.
No final, torna-se o que as pessoas sabem e o que parece melhor. Pessoalmente, acho que o código é mais legível sem a notação húngara, mas pode ser mais fácil encontrar uma variável com intellisense, por exemplo, se a notação húngara estiver anexada.
No meu exemplo acima, você não precisa de um prefixo m para variáveis-membro porque prefixa seu uso com isso. indica a mesma coisa em um método imposto pelo compilador.
Isso não significa necessariamente que os outros métodos sejam ruins, as pessoas seguem o que funciona.
fonte
Quando você tem um método grande ou blocos de código, é conveniente saber imediatamente se você usa uma variável local ou um membro. é para evitar erros e para uma melhor clareza!
fonte
-Wshadow
IMO, isso é pessoal. Não estou colocando nenhum prefixo. De qualquer forma, se o código é público, acho que deveria ter alguns prefixos, para que seja mais legível.
Muitas vezes, grandes empresas estão usando suas próprias 'regras de desenvolvedor'.
Aliás, o mais engraçado e inteligente que eu vi foi o DRY KISS (não se repita. Mantenha as coisas simples, estúpidas). :-)
fonte
Como outros já disseram, a importância é ser coloquial (adaptar os estilos e convenções de nomenclatura à base de código na qual você está escrevendo) e ser consistente.
Durante anos, trabalhei em uma grande base de código que usa tanto a convenção "this->" quanto uma notação de sublinhado postfix para variáveis-membro. Ao longo dos anos, também trabalhei em projetos menores, alguns dos quais não tinham nenhum tipo de convenção para nomear variáveis de membros e outros que tinham convenções diferentes para nomear variáveis de membros. Desses projetos menores, eu sempre achei aqueles que careciam de convenção eram os mais difíceis de entrar rapidamente e entender.
Eu sou muito reticente quanto a nomes. Vou agonizar sobre o nome a ser atribuído a uma classe ou variável, a ponto de, se não conseguir algo que me pareça "bom", optarei por chamá-lo de algo sem sentido e fornecer um comentário descrevendo o que realmente é. é. Dessa forma, pelo menos o nome significa exatamente o que pretendo que signifique - nada mais e nada menos. E, muitas vezes, após usá-lo por um tempo, eu descubro que o nome deve realmente ser e pode voltar e modificar ou refactor adequadamente.
Um último ponto sobre o tópico de um IDE fazendo o trabalho - tudo isso é bom e bom, mas os IDEs geralmente não estão disponíveis em ambientes nos quais realizo o trabalho mais urgente. Às vezes, a única coisa disponível nesse momento é uma cópia do 'vi'. Além disso, já vi muitos casos em que o preenchimento de código IDE propagou estupidez, como ortografia incorreta nos nomes. Portanto, prefiro não ter que confiar em uma muleta IDE.
fonte
A idéia original para prefixos em variáveis de membro C ++ era armazenar informações de tipo adicionais que o compilador não conhecia. Assim, por exemplo, você pode ter uma string com um comprimento fixo de caracteres e outra variável e terminada com um '\ 0'. Para o compilador, são ambos
char *
, mas se você tentar copiar de um para o outro, terá um grande problema. Então, em cima da minha cabeça,char *aszFred = "Hi I'm a null-terminated string";
char *arrWilma = {'O', 'o', 'p', 's'};
onde "asz" significa que esta variável é "string ascii (terminação zero) e" arr "significa que essa variável é uma matriz de caracteres.
Então a mágica acontece. O compilador ficará perfeitamente satisfeito com esta declaração:
strcpy(arrWilma, aszFred);
Mas você, como humano, pode olhar e dizer "ei, essas variáveis não são realmente do mesmo tipo, eu não posso fazer isso".
Infelizmente, muitos lugares usam padrões como "m_" para variáveis-membro, "i" para números inteiros, não importa como usados, "cp" para ponteiros de caracteres. Em outras palavras, eles estão duplicando o que o compilador sabe e dificultando a leitura do código ao mesmo tempo. Acredito que essa prática perniciosa deve ser proibida por lei e sujeita a penalidades severas.
Finalmente, há dois pontos que devo mencionar:
fonte
Nosso projeto sempre usou "its" como prefixo para dados de membros e "the" como prefixo para parâmetros, sem prefixo para locais. É um pouco fofo, mas foi adotado pelos primeiros desenvolvedores do nosso sistema porque eles o viram usado como uma convenção por algumas bibliotecas de fontes comerciais que estávamos usando na época (XVT ou RogueWave - talvez ambos). Então você obteria algo como isto:
A grande razão que vejo para os prefixos de escopo (e não outros - eu odeio a notação húngara) é que ela evita que você tenha problemas escrevendo códigos nos quais pensa estar se referindo a uma variável, mas na verdade está se referindo a outra variável com o mesmo nome definido no escopo local. Também evita o problema de criar nomes de variáveis para representar o mesmo conceito, mas com escopos diferentes, como no exemplo acima. Nesse caso, você teria que criar um prefixo ou nome diferente para o parâmetro "theName" de qualquer maneira - por que não fazer uma regra consistente que se aplique a todos os lugares.
Apenas usar isso-> não é realmente bom o suficiente - não estamos tão interessados em reduzir a ambiguidade quanto em reduzir erros de codificação, e mascarar nomes com identificadores com escopo local pode ser um problema. É verdade que alguns compiladores podem ter a opção de emitir avisos para casos em que você mascara o nome em um escopo maior, mas esses avisos podem se tornar um incômodo se você estiver trabalhando com um grande conjunto de bibliotecas de terceiros que escolheram nomes para variáveis não utilizadas que ocasionalmente colidem com as suas.
Quanto ao próprio - eu sinceramente acho mais fácil digitar do que os sublinhados (como datilógrafo de toque, evito sublinhados sempre que possível - esticando demais as linhas da página inicial) e acho mais legível do que um sublinhado misterioso.
fonte
Eu o uso porque o Intellisense do VC ++ não pode dizer quando mostrar membros particulares ao acessar fora da classe. A única indicação é um pequeno símbolo de "cadeado" no ícone do campo na lista do Intellisense. Apenas facilita a identificação de membros privados (campos). Também é um hábito do C # para ser honesto.
fonte
Eu acho que, se você precisar de prefixos para distinguir os membros da classe dos parâmetros da função de membro e variáveis locais, a função é muito grande ou as variáveis são nomeadas incorretamente. Se não couber na tela, para que você possa ver facilmente o que é o que, refatorar.
Dado que eles geralmente são declarados longe de onde são usados, acho que as convenções de nomenclatura para constantes globais (e variáveis globais, embora a IMO raramente exija a necessidade de usá-las) fazem sentido. Mas, caso contrário, não vejo muita necessidade.
Dito isto, eu costumava colocar um sublinhado no final de todos os alunos da classe particular. Como todos os meus dados são privados, isso implica que os membros tenham um sublinhado à direita. Normalmente, não faço mais isso em novas bases de código, mas como programador, você trabalha principalmente com código antigo, ainda faço muito isso. Não tenho certeza se minha tolerância a esse hábito vem do fato de que eu costumava fazer isso sempre e ainda o faço regularmente ou se realmente faz mais sentido do que a marcação de variáveis-membro.
fonte
No python, os sublinhados duplos principais são usados para emular membros privados. Para mais detalhes, veja esta resposta
fonte
É útil diferenciar entre variáveis-membro e variáveis locais devido ao gerenciamento de memória. Em termos gerais, as variáveis de membro alocadas em heap devem ser destruídas no destruidor, enquanto as variáveis locais alocadas em heap devem ser destruídas nesse escopo. A aplicação de uma convenção de nomenclatura a variáveis-membro facilita o gerenciamento correto da memória.
fonte
O código completo recomenda m_varname para variáveis de membro.
Embora eu nunca tenha achado a notação m_ útil, eu daria peso à opinião de McConnell na construção de um padrão.
fonte
Eu quase nunca uso prefixos na frente dos meus nomes de variáveis. Se você estiver usando um IDE decente o suficiente, poderá refatorar e encontrar referências facilmente. Eu uso nomes muito claros e não tenho medo de ter nomes de variáveis longos. Nunca tive problemas com o escopo dessa filosofia.
A única vez que eu uso um prefixo seria na linha de assinatura. Vou prefixar os parâmetros para um método com _ para que eu possa programar defensivamente em torno deles.
fonte
Você nunca deve precisar desse prefixo. Se esse prefixo oferecer alguma vantagem, seu estilo de codificação geralmente precisa ser corrigido, e não é o prefixo que impede que seu código seja claro. Os nomes de variáveis incorretos típicos incluem "outro" ou "2". Você não corrige isso exigindo que seja mais, consertando-o fazendo com que o desenvolvedor pense sobre o que essa variável está fazendo lá no contexto dessa função. Talvez ele quis dizer remoteSide, ou newValue, ou secondTestListener ou algo nesse escopo.
É um anacronismo eficaz que ainda é propagado longe demais. Pare de prefixar suas variáveis e dê a elas nomes próprios cuja clareza reflita quanto tempo eles são usados. Até 5 linhas você pode chamar de "i" sem confusão; além de 50 linhas, você precisa de um nome bastante longo.
fonte
Eu gosto de nomes de variáveis para dar apenas um significado aos valores que eles contêm e deixar como eles são declarados / implementados fora do nome. Eu quero saber o que o valor significa, ponto final. Talvez eu tenha feito mais do que uma quantidade média de refatoração, mas acho que incorporar como algo é implementado no nome torna a refatoração mais tediosa do que precisa. Os prefixos que indicam onde ou como os membros do objeto são declarados são específicos da implementação.
Na maioria das vezes, eu não me importo se Red é um enum, uma estrutura ou qualquer outra coisa, e se a função é tão grande que não consigo me lembrar se a cor foi declarada localmente ou é um membro, provavelmente é hora de quebrar a função em unidades lógicas menores.
Se a sua complexidade ciclomática é tão grande que você não pode acompanhar o que está acontecendo no código sem pistas específicas da implementação incorporadas nos nomes das coisas, provavelmente você precisará reduzir a complexidade da sua função / método.
Principalmente, eu apenas uso 'this' em construtores e inicializadores.
fonte
Uso m_ para variáveis-membro apenas para aproveitar o Intellisense e a funcionalidade IDE relacionada. Ao codificar a implementação de uma classe, posso digitar m_ e ver a caixa de combinação com todos os m_ membros agrupados.
Mas eu poderia viver sem m sem problemas, é claro. É apenas o meu estilo de trabalho.
fonte
this->
De acordo com as NORMAS DE CODIFICAÇÃO DO VEÍCULO AÉREO COMUM STRIKE FIGHTER AIR (dezembro de 2005):
Assim, o prefixo "m" se torna inútil, pois todos os dados devem ser privados.
Mas é um bom hábito usar o prefixo p antes de um ponteiro, pois é uma variável perigosa.
fonte
Muitas dessas convenções são de uma época sem editores sofisticados. Eu recomendaria o uso de um IDE adequado que permita colorir todos os tipos de variáveis. A cor é muito mais fácil de detectar do que qualquer prefixo.
Se você precisar obter ainda mais detalhes sobre uma variável, qualquer IDE moderno poderá mostrar isso movendo o cursor ou cursor sobre ele. E se você usar uma variável de maneira errada (por exemplo, um ponteiro com o operador.), Você receberá um erro de qualquer maneira.
fonte