Existe uma convenção de capitalização comum em C ++? [fechadas]

13

Eu trabalho bastante em Python e Java, e ambas as linguagens têm convenções bastante comuns (embora não universais) sobre como a capitalização deve ser usada nos identificadores: tanto PascalCasepara nomes de classes quanto ALL_CAPSpara constantes "globais", mas para outros identificadores a muitos códigos Java usam, mixedCaseenquanto muitos códigos Python usam underscore_delimiters. Sei que nenhuma linguagem ou biblioteca impõe uma capitalização específica, mas descobri que, quando me apego às convenções padrão do idioma que estou usando, meu código parece muito mais legível.

Agora estou iniciando um projeto em C ++ e gostaria de aplicar a mesma idéia. Existe alguma convenção mais comum para capitalização que eu deva conhecer?

David Z
fonte
O problema com o camelCase é que ele não funciona bem com o pré-processador. Não é um problema enorme, especialmente porque o pré-processador geralmente pode ser evitado.
#
Eu tive que enfrentar essa decisão apenas alguns dias atrás. No final, foi um acéfalo, já que a biblioteca padrão e o boost usam underscore_lowercase_delimiters. Como eu uso o boost como um impulsionador do STL, ele será espalhado por todo o meu código. Outras bibliotecas que eu uso, que são PascalCase (SFML), podem ser contidas mais facilmente, portanto, qualquer método é bastante padrão.
Max
@ Pubby8: por curiosidade: como o camelCase se choca com o pré-processador?
Joachim Sauer
@JoachimSauer Palavras individuais no camelCase podem ter um caso diferente, mas as macros não podem mudar de caso. Isso se torna um problema se você quiser uma macro que faça parte de uma palavra como argumento - talvez seja necessário fornecer os dois casos como argumentos: macro (x, X). É um problema muito pequeno, mas deve ser conhecido se você pretende usar o pré-processador.
Pubby

Respostas:

27

Existe alguma convenção mais comum para capitalização que eu deva conhecer?

O C ++ é baseado em C, que é antigo o suficiente para ter desenvolvido várias convenções de nomenclatura quando o C ++ foi inventado. Então, o C ++ adicionou alguns, e C também não ficou ocioso com o pensamento de novos. Acrescente a isso as muitas linguagens derivadas de C, que desenvolveram ainda mais as convenções de nomenclatura em C do inventor, até o ponto em que elas fertilizaram de novo em C e C ++ ... Em outras palavras: C ++ não possui uma, mas muitas dessas convenções.

No entanto, se você estiver procurando por uma convenção de nomenclatura, também poderá consultar a convenção de nomenclatura da biblioteca padrão , porque esta é a única que todos os desenvolvedores de C ++ terão que conhecer e estar acostumados.

No entanto, o que você usar, a regra mais importante é: Seja consistente!

Curiosamente, enquanto eu comecei com uma mistura de PascalCase e camelCase, e participei de vários projetos com convenções de nomes ainda mais numerosas, ao longo dos anos, descobri que fiquei cada vez mais preso à convenção standard_library_converter. Não me pergunte o porquê.

sbi
fonte
Obrigado pela informação ... então a biblioteca padrão é sublinhada, então? (pelo menos mais do que qualquer outra coisa?) Eu estava pensando nesse sentido, mas era meio difícil dizer por causa de coisas como iostream, nas quais metade dos nomes dos métodos parece ser o mesmo tipo de fragmento de palavras que o ANSI C :-P
David Z
5
@ David: A biblioteca iostreams provavelmente tem 25 anos e (exceto a biblioteca C ou curso) pode ser a parte mais antiga da biblioteca C ++ std. Felizmente, ninguém em sã consciência iria projetá-lo da maneira que é hoje em dia, e espero que mesmo aqueles que não estejam em sã consciência não escolheriam identificadores da maneira como são usados ​​na biblioteca de fluxos. (Vamos lá, existem funções nomeadas egptr, sputne uflowtambém underflow. Isso é hilário!) De qualquer forma, sim, a std lib hoje em dia usa all_lowercase_with_underscores.
S11:
@sbi Descobri que a biblioteca iostream não é mais considerada uma biblioteca padrão para C ++. E como você mencionou, seus identificadores não são úteis como uma convenção de programação ;-)
umlcat
2
@umlcat: A biblioteca iostreams (em seu modelo conforme aceito pelo C ++ 03) é definitivamente considerada parte da biblioteca padrão do C ++.
S11
Eu também segui o mesmo caminho. Acho que o motivo é CamelCase, que é um pouco mais fácil de digitar e eu queria ser preguiçoso por lá. Mais tarde, aprendi que gastei mais tempo lendo e refatorando meu código do que escrevendo, e o snake_case é mais fácil de ler. Portanto, trata-se de minimizar o gasto de energia. Agora estou brincando de usar nomes em minúsculas para as aulas. Não é convencional, no entanto, acho que alterná-lo e colocar maiúsculas em maiúsculas e minúsculas Instâncias e tipos minúsculos realmente melhora a legibilidade do meu código. Estou pensando que talvez este seja o caminho a seguir. Maiúscula o que é importante, como em humanês.
PSKocik
19

Vamos primeiro concordar que TODAS AS MAIÚSCULAS são uma desgraça e devem ser minimizadas.

Em C e C ++, portanto, é usado como uma convenção para macros, e somente macros, porque as macros são igualmente feias, para não dizer mal.

O C inicial não tinha const, portanto, as constantes tinham que ser expressas como macros. Além disso, naqueles dias, os programas eram muito mais curtos, para que as práticas que hoje são ruins possam ser usadas (por exemplo, o IIRC Brian Kernighan escreveu código com muitas macros não maiúsculas). E também, naqueles dias, existiam teclados que não tinham letras minúsculas; Eu usei um desses, no computador norueguês Tandberg EC-10, por volta de 1980 ou 1979, acho que sim.

Então, Java pegou a convenção maiúscula para constantes desde o início C. Enquanto isso, e talvez até antes disso (não tenho certeza da cronologia aqui), C obteve constantes. No entanto, embora alguns programadores C estivessem presos à convenção anterior por necessidade de constantes como macros maiúsculas, os programadores C ++ eram mais sensíveis.

O grande problema hoje em dia é quando as pessoas aprendem Java primeiro, ou C (com convenções da idade média) primeiro, e depois chegam ao C ++, levando essa convenção em maiúscula com elas.

Então,

    int const answer = 42;    // Nice, good, OK.
    const int ANSWER = 0x2A;  // Ouch!
    #define COMPANYNAME_ANSWER 052  // Oh kill me, please.

Bem, você deve ter pensado que eu mencionei teclados apenas em letras maiúsculas. Ah não. Porque essa é apenas a limitação da tecnologia mais antiga e mais arcaica que impulsionou as convenções de nomenclatura ou pelo menos afetou o quão errado / certo eles pareciam. Em seguida, houve o problema da transmissão serial de 7 bits, que causou problemas correspondentes aos códigos de caracteres (codificação de caracteres de newsletters) usados, o que significava que você precisava se restringir às letras do alfabeto inglês de A a Z.

Na verdade, eu recomendo ainda fazer isso. É onde estamos! Nós não temos mais.

No momento, a partir de 2011, o C ++ padrão suporta Unicode geral em nomes (e o faz desde 1998), enquanto as implementações reais do C ++ não. Em particular, o compilador g ++ é desafiado por caracteres nacionais. Ela decorre dessa limitação tecnológica da Idade das Trevas.

Então,

    double blueberryJamViscosity  = 0.0;    // OK
    double blåbærsyltetøyViskositet = 0.0;  // Ouch!

Por fim, sobre sublinhados versus letras maiúsculas intercaladas,

  • Reserve um formulário facilmente reconhecido para nomes de tipos.
  • Reserve TODAS AS MAIÚSCULAS para macros.
  • Ser consistente.

Eu acho que é isso, realmente, exceto para regras como "geralmente evite o nome de uma letra, exceto (loop, parâmetro do modelo, blá, blá)" e "evite usar l, facilmente confundido com 1" e "evitar maiúsculas, facilmente confundido" com 0 ". Além disso, é claro, evite usar nomes reservados, como começando com sublinhado seguido por maiúsculo, contendo dois sublinhados sucessivos ou começando com sublinhado e estar no espaço de nomes global.

Saúde e saúde

Alf P. Steinbach
fonte
Alf, ISTR Stroustrup mencionando em D&E C a cópia constdo C ++, portanto isso deve ter acontecido há muito tempo e muito antes do Java, provavelmente para o C89.
S11
2
Ah, e um sincero +1por "Seja consistente!" Ao ler, me pergunto por que esqueci de mencionar essa regra, a mais importante, em minha resposta, quando foi a que nunca esqueci de contar aos meus alunos. Suponho que você me perdoe se eu adicionar agora à minha resposta como uma reflexão tardia?
S11
2

Geralmente costumo seguir a convenção que mais vejo nas bases de código existentes para o idioma. No caso de C ++, normalmente vejo camelCase. No caso de Ruby ou PHP, costumo ver coisas como essas.

Realisticamente falando, porém, o mais importante é que você escolha uma convenção de estilo que não seja totalmente insana (dOnT_dO_tHiS) e seja consistente com ela. Faça com que o estilo não seja alterado no código para um projeto específico. Se você estiver trabalhando em um projeto existente, convém seguir o estilo que já existe.

DeM0nFiRe
fonte
1

Bem, há sistemas húngaros que é realmente comum até agora, mas eu prefiro cortar minha própria garganta do que recomendar. O Apps Húngaro é melhor, pois suas marcas anotativas são realmente indicativas de semântica, embora eu sinta que é um pouco interessada em abreviações quando uma palavra curta serviria. (Para usar o exemplo dessa página da Wikipedia, por que usar rwpara row quandorow há apenas um caractere mais? Não é como se houvesse uma escassez global de vogais.)

Realisticamente, porém, o mais importante é seguir as convenções das pessoas com quem você está trabalhando . Realmente. A maioria das convenções funciona bem o suficiente, especialmente se usada de forma consistente. A inconsistência é pior (ainda mais que os sistemas húngaros, que eu odeio). E se você estiver por conta própria, use o que quiser.

Donal Fellows
fonte
1

Pelo que vi, isso varia entre os projetos.

Os sublinhados incorporados são provavelmente mais tradicionais / mais usados ​​em C no Unix. A biblioteca padrão também segue isso, portanto deve quase certamente ser tratada como padrão, a ser usada, a menos que haja código existente suficiente usando outra convenção para forçar absolutamente o uso dessa outra convenção.

O Windows (por exemplo) usa camel case para a maioria de suas funções; portanto, muitas pessoas que desenvolvem para o Windows fazem o mesmo. Isso também é bastante comum entre pessoas que estão realmente mais acostumadas a outras linguagens e tenta tratar o C ++ como se fosse apenas uma variante estranha de outra coisa.

Jerry Coffin
fonte
1

Eu usei a biblioteca padrão e o boost como referências para convenções de nomenclatura. No entanto, há um problema com esta solução.

A biblioteca padrão usa uma convenção de nomenclatura projetada para tentar reduzir colisões com seu código. Parte da solução é usar todas as letras minúsculas. Daí o uso de sublinhados em vez de camelCase.

Acho que o camelCase é legível. PascalCase é frequentemente usado para nomes de classe, pois representa o equivalente a um nome próprio. No entanto, quebrarei essa regra para functores que são mais representativos de um verbo.

Eu tento não usar macros. No entanto, quando eu faço, as macros são criadas para parecerem funções quando podem. Eu também uso valores const ou enumerações em vez de constantes manifestas, evitando ainda todas as letras maiúsculas. Normalmente prefixo esses símbolos com um 'k' para indicar que eles são constantes.

// instead of a manifest constant
#define HOURS 24

// use const
const int kHours = 24; 

// or enum
enum {
    kHours   = 24,
    kMinutes = 60
};
Bill Door
fonte
0

Esta referência descreve uma convenção de nomenclatura bastante semelhante à que eu já usei com sucesso em pelo menos três empresas nas quais trabalhei no passado.

Ao contrário de uma resposta anterior, eu evitaria seguir a convenção de nomenclatura da Biblioteca Padrão C ++ em meu próprio código, por nenhum outro motivo, a fim de evitar colisões de nomes com a Biblioteca Padrão.

Esta resposta do SO anterior sobre um tópico relacionado também pode ser interessante: /programming/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier

Gnawme
fonte
Umm, você pode usar a mesma convenção de nomeação sem usar os mesmos nomes ... e se você realmente quer os mesmos nomes, você ainda está protegido por namespaces, por exemplo std::stringvs. gnawme::string.
Einpoklum