Guia de estilo do Google em C ++. Parte 8

Parte 1. Introdução
...
Parte 8. Nomeação
Parte 9. Comentários
...



Ao escrever código, todos usamos as regras de design de código. Às vezes, suas próprias regras são inventadas; em outros casos, guias de estilo prontos são usados. Embora todos os programadores de C ++ leiam em inglês mais facilmente do que em seu idioma nativo, é mais agradável ter um manual no último.
Este artigo é uma tradução de parte do guia de estilo do Google em C ++ para o russo.
Artigo original (fork no github), tradução atualizada .

Nomeação


As regras básicas para o estilo de codificação estão nomeando. A aparência do nome imediatamente (sem procurar um anúncio) nos diz o que é: tipo, variável, função, constante, macro etc. As regras de nomenclatura podem ser arbitrárias, mas a consistência é importante e as regras devem ser seguidas.

Princípios gerais de nomeação


  • Use nomes que até as pessoas da outra equipe entenderão.
  • O nome deve falar da finalidade ou aplicabilidade do objeto.
  • Não economize no tamanho do nome, é melhor ter um nome mais longo e mais compreensível (mesmo para iniciantes).
  • Menos abreviações, especialmente se não forem familiares fora do projeto.
  • Use apenas abreviações conhecidas (a Wikipedia sabe sobre elas?).
  • Não encurte as palavras.

Em geral, o comprimento do nome deve corresponder ao tamanho do escopo. Por exemplo, n é um nome adequado dentro de uma função de 5 linhas; no entanto, ao descrever uma classe, isso pode ser um pouco curto.

class MyClass { public: int CountFooErrors(const std::vector<Foo>& foos) { int n = 0; //       for (const auto& foo : foos) { ... ++n; } return n; } void DoSomethingImportant() { std::string fqdn = ...; //      } private: const int kMaxAllowedConnections = ...; //     }; 

 class MyClass { public: int CountFooErrors(const std::vector<Foo>& foos) { int total_number_of_foo_errors = 0; //       for (int foo_index = 0; foo_index < foos.size(); ++foo_index) { //   `i` ... ++total_number_of_foo_errors; } return total_number_of_foo_errors; } void DoSomethingImportant() { int cstmr_id = ...; //   ( ) } private: const int kNum = ...; //       }; 

Observe que nomes típicos também são válidos: i para um iterador ou contador, T para um parâmetro de modelo.

No futuro, ao descrever as regras, “palavra” / “palavra” é tudo o que está escrito em inglês, sem espaços, incluindo abreviações. Em uma palavra, a primeira letra pode ser maiúscula (dependendo do estilo: " camel case " ou "Pascal case"), as letras restantes são minúsculas. Por exemplo, preferencialmente StartRpc () , preferencialmente StartRPC () .

Os parâmetros do modelo também seguem as regras de suas categorias: nomes de tipos, nomes de variáveis, etc.

Nomes de arquivos


Os nomes dos arquivos devem ser escritos apenas em letras minúsculas; você pode usar sublinhado ( _ ) ou hífen ( - ) para separá-los. Use o separador usado no projeto. Se não houver uma abordagem única, use "_".

Exemplos de nomes adequados:

  • my_useful_class.cc
  • my-useful-class.cc
  • myusefulclass.cc
  • myusefulclass_test.cc // _unittest e _regtest foram descontinuados.

Arquivos C ++ devem terminar em .cc , o cabeçalho deve estar em
.h . Os arquivos incluídos como texto devem terminar em .inc (consulte também a seção Cabeçalhos independentes ).

Não use nomes que já existem em / usr / include , como db.h.

Tente atribuir nomes específicos aos arquivos. Por exemplo, http_server_logs.h é melhor que logs.h. Quando os arquivos são usados ​​em pares, é melhor dar o mesmo nome a eles. Por exemplo, foo_bar.he foo_bar.cc (e contém a classe FooBar ).

Digite os nomes


Os nomes dos tipos começam com uma letra maiúscula, cada nova palavra também começa com uma letra maiúscula. Sublinhados não são usados: MyExcitingClass , MyExcitingEnum .

Nomes de todos os tipos - classes, estruturas, aliases, enumerações, parâmetros de modelo - são nomeados no mesmo estilo. Os nomes dos tipos começam com uma letra maiúscula, cada nova palavra também começa com uma letra maiúscula. Sublinhados não são usados. Por exemplo:

 // classes and structs class UrlTable { ... class UrlTableTester { ... struct UrlTableProperties { ... // typedefs typedef hash_map<UrlTableProperties *, std::string> PropertiesMap; // using aliases using PropertiesMap = hash_map<UrlTableProperties *, std::string>; // enums enum UrlTableErrors { ... 

Nomes de variáveis


Os nomes de variáveis ​​(incluindo parâmetros de função) e membros de dados são escritos em letras minúsculas com um sublinhado entre as palavras. Os membros dessas classes (não estruturas) são complementados por um sublinhado no final do nome. Por exemplo: a_local_variable , a_struct_data_member , a_class_data_member_ .

Nomes de variáveis ​​comuns


Por exemplo:

 std::string table_name; // OK -     

 std::string tableName; //  -   

Membros de dados da classe


Os membros dessas classes, estáticas e não estáticas, são chamados de variáveis ​​comuns com a adição de um sublinhado no final.

 class TableInfo { ... private: std::string table_name_; // OK -    static Pool<TableInfo>* pool_; // OK. }; 

Membros de dados da estrutura


Os membros dos dados da estrutura, estáticos e não estáticos, são referidos como variáveis ​​regulares. Nenhum sublinhado é adicionado a eles no final.

 struct UrlTableProperties { std::string name; int num_entries; static Pool<UrlTableProperties>* pool; }; 

Consulte também Estruturas versus Classes , que descreve quando usar estruturas, quando classes.

Nomes das constantes


Os objetos são declarados como constexpr ou const, para que o valor não seja alterado durante a execução. Os nomes das constantes começam com o símbolo "k" e, em seguida, vêm o nome em um estilo misto (letras maiúsculas e minúsculas). Sublinhado pode ser usado em casos raros quando letras maiúsculas não podem ser usadas para separação. Por exemplo:

 const int kDaysInAWeek = 7; const int kAndroid8_0_0 = 24; // Android 8.0.0 

Todos os objetos constantes semelhantes com um tipo estático de armazenamento (ou seja, estático ou global, para obter mais detalhes aqui: Duração do Armazenamento ) também são nomeados. Esta convenção é opcional para variáveis ​​em outros tipos de armazenamento (por exemplo, objetos constantes automáticos).

Nomes de funções


As funções comuns são nomeadas em um estilo misto (letras maiúsculas e minúsculas); As funções de acesso à variável (acessador e mutador) devem ter um estilo semelhante à variável de destino.

Normalmente, o nome de uma função começa com uma letra maiúscula e cada palavra no nome é maiúscula.

 void AddTableEntry(); void DeleteUrl(); void OpenFileOrDie(); 

(Regras semelhantes se aplicam a constantes em uma classe ou área de namespace que fazem parte da API e devem se parecer com funções (e o fato de não serem funções não é crítica))

Acessores e mutadores (funções get e set) podem ser nomeados como as variáveis ​​correspondentes. Eles geralmente correspondem a variáveis ​​de membro reais, mas isso não é necessário. Por exemplo, int count () e void set_count (int count) .

Namespace Namespace


O espaço para nome é chamado em minúsculas. O espaço para nome de nível superior é baseado no nome do projeto. Evite colisões de seus nomes e outros namespaces conhecidos.

Um espaço para nome de nível superior geralmente é o nome de um projeto ou equipe (que criou o código). O código deve estar localizado em um diretório (ou subdiretório) com um nome correspondente ao espaço para nome.

Não esqueça a regra de não usar abreviações - isso também se aplica aos espaços para nome. É improvável que o código interno exija uma referência ao espaço para nome, portanto, as abreviações são supérfluas.

Evite usar nomes conhecidos para namespaces aninhados. Colisões entre nomes podem causar surpresas durante a montagem. Em particular, não crie namespaces aninhados denominados std . Identificadores exclusivos de projeto ( websearch :: index , websearch :: index_util ) são recomendados em vez de inseguros contra colisões websearch :: util .

Para espaços de nomes internos / internos , podem ocorrer colisões quando outro código é adicionado (auxiliares internos tendem a se repetir em equipes diferentes). Nesse caso, usar um nome de arquivo para nomear um espaço para nome ajuda muito. ( websearch :: index :: frobber_internal para uso em frobber.h )

Nomes de enumeração


As enumerações (com restrições de escopo e sem escopo) devem ser referidas como constantes ou macros . Ou seja: kEnumName ou ENUM_NAME .

É preferível nomear os valores individuais no enumerador como constantes. No entanto, é permitido referir-se como macros. O nome da própria enumeração UrlTableErrors (e AlternateUrlTableErrors ) é um tipo. Conseqüentemente, um estilo misto é usado.

 enum UrlTableErrors { kOk = 0, kErrorOutOfMemory, kErrorMalformedInput, }; enum AlternateUrlTableErrors { OK = 0, OUT_OF_MEMORY = 1, MALFORMED_INPUT = 2, }; 

Até janeiro de 2009, o estilo de nomear valores de enumeração era semelhante ao das macros. Isso criou problemas com nomes de macro duplicados e valores de enumeração. A aplicação de um estilo constante resolve o problema e é preferível usar um estilo constante no novo código. No entanto, não há necessidade de reescrever o código antigo (ainda não há problemas de duplicação).

Nomes de macro


Você não vai definir macros ? Apenas no caso (se você estiver indo), eles devem ficar assim:
MY_MACRO_THAT_SCARES_SMALL_CHILDREN_AND_ADULTS_ALIKE .

Por favor, leia como definir macros ; Normalmente, macros não devem ser usadas. No entanto, se você absolutamente precisar deles, nomeie-os em letras maiúsculas com sublinhados.

 #define ROUND(x) ... #define PI_ROUNDED 3.0 

Exceções de nomeação


Se você precisar nomear algo que tenha análogos no código C ou C ++ existente, siga o estilo usado no código.

bigopen ()
nome da função derivado de open ()

uint
definição semelhante aos tipos padrão

bigpos
estrutura ou classe derivada de pos

sparse_hash_map
Entidade semelhante a STL; siga o estilo stl

LONGLONG_MAX
constante como INT_MAX

Nota: Os links podem levar a seções do manual que ainda não foram traduzidas.

Source: https://habr.com/ru/post/pt477722/


All Articles