Linee Guida per la programmazione C++ con Irrlicht (2)

Autore : Manuel Montini (aka. Jekrom)

scarica il seguente tutorial in formato pdf 

scarica il codice di esempio del tutorial in formato rar

Se trovate delle imperfezioni, errori o se avete commenti da fare, non esitate a scrivermi:D

Nota: Per la corretta indentazione del codice, fate riferimento al file pdf in quanto il testo contenuto nella pagina web potrebbe risultare sfasato.

INTRODUZIONE

Ancora un altro tutorial di quelli noiosi, ma prometto che dal prossimo si cominceranno a edere argomenti molto più divertenti, quindi se ritenete che anche questo non faccia per voi, nonponetevi il problema e saltatelo tranquillamente, ma credo che una lettura per curiosità non possa he fare del gran bene.

Oggi parliamo del codice C++ e più nello specifico andremo a definire alcuni formalismi he sarebbe bene utilizzare per una scrittura di codice corretto e chiaro. Non sono degli standard, ma sono i più usati dai programmatori di tutto il mondo, quindi non date tutta la colpa solo a me.

Ok… Gooooooooooooo!!!

Legenda

Per semplicità elencherò qui il significato dei termini che dopo saranno riportati:
Upper Case = Lettera Maiuscola (es. A, B, C, X, Y, Z)
Lower Case = Lettera Minuscola (es. a, b, c, x, y, z)
Mixed Case = Maiuscole e Minuscole mescolate ( es. HelloWorld, editHtmlText)
Underscore = Trattino Basso ( _ )
Scope = Lo scope è l'area di vita di una variabile all'interno del codice.
Small scope = variabili che hanno vita solo all'interno del blocco (ad esempio un
contatore dentro un ciclo for, all'uscita del ciclo la variabile “muore”).
Large Scope= variabili che hanno una larga visibilità (ad esempio una variabile globale che
“muore” con la fine del programma.
Header file = File di tipo *.h
Source file = File di tipo *.cpp

Convenzioni sui nomi

Sarebbe bene seguire il più possibile queste convenzioni in quanto facilitano la comprensione el codice da parte di terzi e vi assicuro che imparare ad utilizzare e leggere questi “must” aiuta molto anche il programmatore più esperto.

1. I nomi dei tipi di dato possono essere in mixed case ma devono iniziare sempre con uppercase.

es. Line, SavingAccount 

2. Le variabili possono essere in mixed case ma devono iniziare con lower case.

es. line, savingAccount

(Si può notare come le convenzioni 1 e 2 rendano più semplice distinguere la variabile dal suo tipo)

3. I nomi delle costanti(enumerati inclusi) devono essere tutti i upper case, usando underscore per separare le parole.

es. COLOR_RED, MAX_ITERACTION, PI 

4. I nomi dei metodi o delle funzioni devono essere dei verbi!!! possono essere in mixed case, ma devono iniziare con lower case.

es. getName(), computeTotalWidth()

5. Le variabili delle classi private devono avere underscore come suffisso.

es. class SomeClass{
private:
int length_;
}

In questo modo riusciamo a risolvere molto semplicemente il problema di trovare dei nomi ragionevoli per i parametri di metodi e costruttori

es. void setLength( int length ) { length_ = length; } 

6. Le variabili generiche devono avere lo stesso nome dei loro tipi.

es. void connect(Database* database) // NO Database* db
// NO Database* oracleDB

Si riduce la complessità del codice e si riesce a capire all'istante di che tipo è la variabile (pensate cosa significa definire una variabile alla riga 200 chiamandola Database* prova; e poi cercare di capire il significato alla riga 7356).

Le variabili non-generiche hanno una regola, la variabile deve essere chiamata combinando la regola al tipo:

es. Point startingPoint, centerPoint; Name loginName;

Immediatamente un programmatore vede il tipo della variabile ed il suo utilizzo.

7. I nomi delle variabili devono essere scritti in inglese.

Dimenticatevi variabili con nomi come

float prova1   

8. Le variabili con large scope devono avere nomi lunghi, le variabili con small scope devono avere nomi corti. (tornate all'inizio se non ricordate cosa è lo scope di una variabile)

Perchè si usa questa convenzione? Semplicemente perchè un programmatore sa che può utilizzare variabile a nome corto per piccole parti di programma per memorizzare dati temporanei.

Si assume che per gli interi vengano usati i nomi : i, j, k, n, m
Si assume che per gli interi vengano usati i nomi : c, d

9. I nomi degli oggetti sono impliciti e devono essere evitati nel nome del metodo.

es. line.getLength(); // NO: line.getLineLenth() !!! 

10. I termini get/set devono essere usati solo dove gli attributi sono acceduti direttamente.

es. vector.getElement( 2 );
vector.setElement( 2, value );

11. I nomi al plurale vanno usati quando si indica delle collezioni di oggetti.

es. vector<Point> points; int values[];

12. Il prefisso “is” deve essere usato per variabili booleane e metodi.

es. isSet, isVisible
bool isOpen() ;

Evitare di usare nomi negativi per i booleani: invece di isNoError è preferibile usare isError.

Questo per quello che riguarda i nomi è tutto quello che può servirci, in realtà ci sono molte altre convenzioni, ma per ora direi che queste 12 siano perfette per iniziare a creare del codice più leggibile…

Ora che guardiamo??? Le convenzioni per i Files naturalmente :D

Convenzione per i File

13. I nomi dei file dovono essere in mixed case ed iniziare in upper case.

es. MyPlayer.cpp
MyPlayer.h 

14. Una classe deve essere dichiarata in un header file e definita in un source file, dove il nome della classe deve essere lo stesso del nome del file.

es.MyPlayer.cpp, MyPlayer.h
class MyPlayer
{
...
}

15. Tutte le definizioni devono essere nel source file.

es. class MyPlayer
{
public:
int getValue() {return value_;} //NO!!!
private:
int value_;
}

16. Scrivere codice entro le 80 colonne, altrimenti andare a capo, evitare caratteri speciali come il TAB e il page break.

Questi sono accorgimenti che potrete utilizzare o meno, 80 è il numero delle colonne comunemente usate da tutti gli editor, che spesso non supportano bene caratteri speciali come il TAB, quindi se volete che il vostro codice sia letto perfettamente da tutti, cercate di seguire queste regole (io non le seguo praticamente mai, ma quando passo da Dev-C++, al kwrite, ad Anjuta, ad Eclipse e al VIM viassicuro che impazzisco… per non parlare di EMACS!!! )

17. Gli header file devono contenere una include guard.

es. #ifndef COM_COMPANY_MODULE_CLASSNAME_H#define COM_COMPANY_MODULE_CLASSNAME_H
.
.
#endif //COM_COMPANY_MODULE_CLASSNAME_H

Fatelo sempre per evitare problemi di compilazione, spesso un novizio non sa come risolvere questo tipo di problemi, quindi mettete sempre questo tipo di guardie, la sruttura di queste guardie è flessibile, potetescriverle come volete, suggerisco di ricostruire la struttura attraverso l'albero dei sorgenti in modo tale da evitare conflitti con i nomi.

Ok per i file poca roba, ma se seguiamo queste regole, insieme con quelle descritte nel primo tutorial, ci troviamo in mano un codice molto strutturato e modulare che ci permette una migliore lettura dell'insieme. Ok alcune piccole convenzioni sugli statement, per poi concludere il tutorial con la parte relativa al layout dei costrutti ed ai commenti… proseguiamo.

Convenzione per gli statements

18. Le parti di una classe devono essere ordinate per public, protected e private. Tutte le sezioni devono esser definite esplicitamente, non lasciate che decida il compilatore.

Qui l'ordine è molto importante, perchè le persone che desiderano solo utilizzare la classe, possono fermarsi appena terminata la lettura della sezione pubblica.

19. La conversione dei tipi deve essere castata esplicitamente.

es. floatValue = static_cast<float>(intValue); // NO: floatValue = intValue; !!!

Questo perchè si mostra che la conversione è voluta e non che è frutto di un errore e quindi di un possibile baco!!! E quello che noi vogliamo evitare ancora prima di andare in fase di compilazione è la presenza di bachi stupidi, sopratutto se si parla di tipi.

20. L'uso di variabili globali deve essere davvero limitato.

21. Non utilizzare test impliciti per lo 0 quando si usano variabili booleane o puntatori.

es. if (nLines != 0) // NO: if (nLines)


22. Le variabili devono essere dichiarate nel minore scope possibile.

Sempre per facilitare la correzione di eventuali errori, dato che è più semplice controllare il buon funzionamento di una variabile a small scope.

23. Le variabili di loop devono essere inizializzate subito prima del loop.

es. isDone = false;
while (!isDone) { . . }

24. Usare while(true) per i cicli infiniti.

es. while (true) { . . }
 for (;;) { // NO!!! . . }
 while (1) { // NO!!! . . }

25. Nei condizionali il caso nominale deve essere gestito all'interno del ramo “if”, mentre le eccezioni a questo caso devono essere gestite dentro l'“else”

es. bool isOk = readFile (filename); if (isOk) { . . } else { . . }

26. Evitate di inserire statement eseguibili all'interno del condizionale.

es. File* fileHandle = open(filname, “w”);if (fileHandle) { . . } // NO: if (!(fileHandle = open(filname, “w”))) { . . }

Ok e finalmente siamo all'ultima parte. Lo so che mi state odiando e se siete giunti fino a qui mi congratulo con voi. Vediamo ora qualche convenzione sui Layout ed in fine soffermiamoci sui commenti, ovvero quella cosa che i programmatori odiano con tutto il loro cuore, ma che se utilizzati bene ci salvano la vita in fase di debugging.

Layouts e Commenti

27. L'indentazione di base dovrebbe essere di 2 , 3 o 4 spazi. Per esperienza ritengo che di 3 sia decisamente la migliore e la più leggibile.

es. for ( i = 0; i < nElements; i++ ) a[i] = 0;

28. Il layout dei blocchi deve essere scritto come illustrato nell'esempio 1 qui sotto (raccomandato) oppure nell'esempio 2. Le funzioni e le classi devono essere come nell'esempio2.

es1.
while (!done) {
doSomething();
done = moreToDo();
}
es2.
While (!done)
{
doSomething();
done = moreToDo();
}
es3.
while (!done) // NO!!!!!
{
doSomething();
done = moreToDo();
}

29. La dichiarazione della classe deve avere la seguente struttura.

Class MyClass : public BaseClass { public:
...
protected:
 		...
private:
...
}

Rispettate l'identazione, l'ordine, le righe vuote tra l'uno e l'altro e sopratutto ricordate di utilizzare la struttura di parentesi come nell'esempio 2 visto sopra.

30. Tralascio gli statement del for e del while e passiamo allo switch.

Lo switch deve avere la seguente forma.
 switch (condition) {
case ABC :
statements;
break;
case DEF :
statements;
break;
default :
statements;
break;
}

Rispettare gli spazi tra un case e l'altro e sopratutto… INDENTATION!!!

31. Un singolo statement di if-else, while e for può essere scritto senza parentesi graffe, ma secondo me è bene metterle sempre!

32. Separate i metodi con tre righe bianche.

33. Utilizzate sempre un allineamento di questo tipo per le variabili:

AsciiFile* 	file;
int 		nPoints;
float 		x, y;

34. Il codice ingannevole non deve essere commentato, DEVE ESSERE RISCRITTO!!!

Utilizzando queste convenzioni avrete un codice che si autocommenta, quindi potete lasciare i commenti effettivamente dove servono.

35. Commentate sempre ogni passaggio che non vi sembra chiaro, sicuramente ne avrete vantaggio in fase di pulizia degli errori.

Ok 35 mi sembrano sufficenti, probabilmente sono molti di più gli accorgimenti di prendere, ma di sicuro questi possono aiutarvi a costruire un codice pulito e chiaro. Ricordatevi che un videogioco non è un programmino di 20 righe di codice da inserire tutto dentro il main, e ricordatevi che potreste non essere gli unici sviluppatori, quindi… MEDITATE GENTE :D

Ok concludo il tutorial augurandomi di essere stato utile. Non mi fucilate se non vi trovate d'accordo con qualche cosa, questi accorgimenti sono frutto di anni di esperienza, ma naturalmente ognuno ha la sua e quindi potrebbe trovare alcune cose sbagliate. Spero non ci siano troppi errori nel testo, in ogni caso segnalatemeli e saranno corretti speditivamente :D

Ciao e a presto!!!
Manuel <aka. Jekrom>


9 commenti per “Linee Guida per la programmazione C++ con Irrlicht (2)”

  1. Bellaz ha scritto:

    Ottima guida credo che servirà a persone che come me hanno idee da sviluppare ma che programmano nella lingua di mordor :|

  2. rmsak ewfjir ha scritto:

    cfmdgvwn snrjqladc khsxverd bpwi pqzavd wytsf arojwh http://www.cltabrzhu.zgtuyawmd.com

  3. Paolo ha scritto:

    Una lista di indicazioni molto preziose sembra/è quella di un professore che detta ai sui alunni il decalogo di un buon programmatore professionale.
    Arrivederci.

  4. montoya ha scritto:

    Bella guida… solo che io uso il tab 4 spazi, per il resto come te :D

  5. serega ha scritto:

    world class call center definition

  6. serega ha scritto:

    canker sores in mouth

  7. serega ha scritto:

    sensual female nudes

  8. serega ha scritto:

    caco ricci nude photos

  9. serega ha scritto:

    bro. steve harris video productions