Algumas convenções

Enquanto o primeiro artigo sobre a criação de jogos não fica pronto, achei conveniente escrever esse aqui, para que partamos do mesmo ponto. Em primeiro lugar, estou assumindo que todos vocês:

  • Já estudaram C++ em algum momento de suas vidas;
  • Conhecem os conceitos básicos de programação, incluindo orientação à objetos;

Ainda não é o seu perfil? Então, vale a pena relembrar alguns links já passados no artigo sobre que linguagem de programação usar:

http://www.bdjogos.com/conteudo.php?link=capitulo_08.php (em português)
http://www.cplusplus.com/doc/tutorial/
http://www.inf.uni-konstanz.de/~kuehl/c++-faq/

Convenções de código

O C++ é uma linguagem antiga, se comparada ao Java ou ao C#. No decorrer dos anos, várias convenções de código foram criadas e adotadas. Eu, como todos os programadores, aderi a algumas delas (coincidentemente, são muito parecidas com as atuais convenções do Java):

  • Nomes de classes iniciam com letras maiúsculas, e o nome prossegue no estilo “camel case” (ou seja, com a primeira letra de cada outra palavra maiuscula). Se a classe começar com uma sigla, só a primeira letra da sigla se torna maiúscula. Exemplos: CameraMan, BigBoss, Player, SdlImage. Note que não uso prefixos ou underscore (_);
  • Nomes de variáveis iniciam com letras minúsculas, no resto, seguem o mesmo estilo das classes: uglyEnemy, sdlImage, life, playerPosition;
  • Chaves são colocadas na linha de baixo, seja no comando ou em métodos. E não uso chaves em ifs ou whiles com um só comando, a menos que isso torne o código mais claro (em ifs dentro de ifs, por exemplo). Exemplos:
//If só com um comando
if (x == 1)
    doSomething();
else
    doSomethingElse();

//Ifs aninhados
if (x==1)  //Esse if ficaria confuso sem as chaves.
{
    if (a == b)
       x++;
    else //Pois ficaria difícil dizer de quem é esse else
       x--;
}

//While com múltiplos comandos
while (gameIsPlaying)
{
    readInput();
    process();
    render();
}
  • Sou totalmente contra prefixos de qualquer tipo. Em nomes de classes, variáveis, parâmetros ou atributos. Entretanto, uso o prefixo _ para parâmetros de um construtor que tenham o mesmo nome de um atributo e o prefixo p para ponteiros. Os prefixos só são usados para evitar código ambíguo, portanto, uma classe que só trabalhe com ponteiros não precisa prefixa-los com p.
  • Acho que nem seria necessário dizer, mas identação está presente no código inteiro. Como padrão, uso 3 espaços.
  • Todo código que desenvolvo é em inglês (não um inglês perfeito, off course, mas eu tento). Por motivos didáticos, comentários serão deixados em português. Mas não se surpreenda se, ao baixar um de meus projetos prontos, você se deparar com um código integralmente em inglês. Motivo? É mais fácil para pedir a ajuda em fóruns internacionais;
  • Dou preferência ao paradigma orientado à objetos;
  • Dou preferência a um código seguro ao invés de um código rápido: isso inclui manter os atributos privados e acessa-los através de gets e sets, usar exceptions e validar parâmetros;
  • Dou preferência a clareza ao invés de performance. Assim, inteiros ou ponteiros não são implicitamente usados como booleanos, fujo de expressões que necessitem de profundo conhecimento da precedência dos operadores e não poupo na criação de classes ou métodos.
bool isPlaying = true;
int x = 10;
Enemy* anEnemy = NULL;

//Errado! Conversão implícita de um inteiro para booleano
//Segundo a convenção, o correto é while (x > 0) e,
//na primeira linha, x--;
while (x--)
{
   doSomething();
}

//Errado! Conversão implicita de um ponteiro para um booleano
if (!anEnemy)  //Pela convenção seria if (anEnemy == NULL)
{
    playVictory();
}

//Ok! Uso de um booleano.
//Note que não é necessário fazer while(isPlaying == true)
while (isPlaying)
{
     playGame();
}
  • Dou preferência ao uso da biblioteca padrão. O maior impacto disso é que prefiro std::string no lugar de char* e std::vector no lugar de arrays primitivos. Se você não está familiarizado com a biblioteca padrão, não se preocupe. Farei uma pequena revisão dos seus principais elementos no futuro.

That’s all folks!

No próximo artigo, veremos como inicializar a SDL e sobre como criar a janela de seu jogo.

Anúncios

Sobre Vinícius Godoy

Leia a biografia completa aqui: http://pontov.com.br/site/index.php/colaboradores/54-vinigodoy
Esse post foi publicado em C++, Desenvolv. de Jogos, Programação. Bookmark o link permanente.

9 respostas para Algumas convenções

  1. mikma disse:

    Perfeito!! Estou iniciando e estou aprendendo todos estes conceitos.
    Obrigado e Parabéns novamente.

  2. MarkAmeba disse:

    Aew finalmente vamos começar a ter mais códigos, mesmo me complicando com ponteiros e o OO do C++ estou tentando me adaptar.
    Por minha sorte a maioria das convenções são parecidas com o do Java então não vou ter tanto problema (espero).
    Estamos a espera de mais posts, mais agora com conteúdo didático.
    Abraço
    Mark^^

  3. Guedes disse:

    Olá Vinícius,
    Você afirma que o comando abaixo está errado, mas nos livros avançado de C++ é ensinado a usar o ! (negação) em ponteiros, pois a comparação é muito mais rápida que usar o == (igual).
    # if (!anEnemy) //O correto é if (anEnemy == NULL)
    Pode por favor descrever mais sobre sua afirmação?

  4. vinigodoy disse:

    Oi Guedes, ótima observação. Estou falando que é errado segundo a convenção que adoto. Na prática, não há nada errado em usar a outra forma, é só uma questão de estilo mesmo. 🙂

    Primeiramente, não há diferença significativa em termos de performance. A maior parte dos compiladores disponíveis hoje em dia (e testei isso no MinGW e no Visual C++) é esperta o suficiente para gerar exatamente o mesmo código para os dois casos.

    Ainda que não gerasse, duvido muito que esse tipo de otimização em microcódigo gerasse algum tipo de ganho significativo. Primeiro, porque a comparações envolvendo ponteiros dessa forma são bastante esporádicas. Segundo, porque a maior parte dos gargalos está em algoritmos mal implementados, IO e na parte gráfica.

    Por fim, também achei conveniente adotar essa convenção porque tenho certeza de que terei leitores Java e leitores pouco experientes com C++, que certamente se sentirão mais à vontade com ela. 😉

  5. MarkAmeba disse:

    “Por fim, também achei conveniente adotar essa convenção porque tenho certeza de que terei leitores Java e leitores pouco experientes com C++, que certamente se sentirão mais à vontade com ela.”

    Os leitores como eu^^
    E como muitas pessoas que chegam até aqui vem do GUJ acho que se acostumarão mais facil.

  6. dudeabot disse:

    sobre os atributos de classe, o que venho utilizando ultimamente é o seguinte

    propriedades da classe prefixadas com m, por exemplo

    class Enemy{
    
    public:
       int mLife;
       void setLife(int life){
          mLife=life;
       }
    };

    é um padrão também usado na Ogre e que venho me acostumando com ele 🙂

    ourta questão, é a da identação, acredito que na maioria dos compiladores é o TAB, eu uso o Visual C++ Express (está longe de ser um Eclipse da vida 😉 ), e para identar o código automaticamente seleciona-se o código e faz-se a combinação CTRL+K CTRL+F

    vlw, e parabéns pelo blog!

  7. vinigodoy disse:

    Obrigado pelo comentário! Eu realmente não vejo benefício nenhum em prefixar um atributo da classe, exceto no caso de atributos gráficos em janelas, como textfields e labels. Se fosse prefixar alguma coisa, seria melhor o parâmetro. Mas, o importante é ter uma convenção, seja ela qual for, não?

    Mas, se for para manter padrão com a convenção de alguma coisa, ótimo. É uma boa idéia preferir um código mais uniforme.

    Pelo menos, esse é um prefixo simples e fácil de lembrar.

    E, definitivamente, uma das grandes vantagens do Java é que eles optaram por criar e divulgar uma convenção de código única. No C++, você corre o risco de usar a Ogre com essa convenção, associada com uma Engine de física com outra convenção e uma biblioteca de IA com uma terceira…

    Existe um problema em usar TAB: Se você trocar para um editor com a tabulação de tamanho diferente, ferra todo o código. A maior parte dos editores suporta usar TAB ou espaços, geralmente configurável através de opção. E, diferente do que você falou, eu tenho visto hoje em dia eles configurados para espaços (code::blocks, eclipse, netbeans e o do Delphi já aderiram à esse padrão). Não duvido que o Visual suporte isso também.

  8. Bruno Márcio disse:

    E aí, Vinícius!
    Estava procurando por um estilo de código, e achei ótimo o seu estilo. Gostaria de mais detalhes sobre documentação do código, comentários, etc. Manda um e-mail para mim por favor. Valeu!

  9. Pingback: Detalhes da Programação – Ferramenta SQL (Parte 1) « Blog Rodrigo Tavares – De Java para C++

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s