PDA

View Full Version : [C++] Design di un file Header


[Kendall]
04-05-2012, 09:31
Salve ragazzi, apro questo thread a mo di "sondaggio" e scambio opinioni.
Sono parecchi mesi che programmo in c++ e spesso e volentieri uno strumento valido per l'apprendimento è stato per me il leggere listati altrui, capirne i concetti, le tecniche, il design, e quant'altro. Una cosa che spesso ho notato è la varietà di stili nello stendere i file header, cosa che può aiutare o rendere difficoltosa la lettura, e nel caso di codice reso disponibile ad altri è un fattore direi più che importante.
Ma arriviamo alla domanda: voi tendete a raggruppare tutto sotto sezioni fisse (public, private e se presente protected) o dividete il codice per aree tematiche piuttosto che per visibilità? Un esempio di quest'ultimo concetto potrebbe essere questo listato:


#ifndef KCHRONO_H
#define KCHRONO_H

#include <ctime>
#include <string>


namespace KsLib
{

class KChrono
{
// Enumerators & Statics
public:
enum ChronoStatus {Pause, Forward, Backward};
enum ChronoType {Clock, Countdown};
enum ChronoFormat {HMS, HMSC};
constexpr static double CLOCKS_PER_MS = CLOCKS_PER_SEC / 1000.0;

// Fields & Fields Interfaces
private:
ChronoStatus _status;
clock_t _tickCount;
clock_t _initialValue;
clock_t _endValue;
bool _endFlag;
public:
void setEndValue(const long seconds);
clock_t getEndValue() const;
clock_t getTickCount() const;

// Constructors
public:
KChrono();
KChrono(const long seconds);

// Class Methods
public:
void forward();
void backward();
void pause();
void reset(const long seconds = 0);
bool EndReached() const;
std::string ToString(ChronoType chronoType, ChronoFormat chronoFormat) const;

}; // class KChrono

} // namespace KsLib


#endif // KCHRONO_H


Lo so, non è un concetto fondamentale il design degli header (visto che al compilatore non cambia una ceppa), però son curioso di conoscere i vostri personali stili.

AllerITA
04-05-2012, 11:26
Io tendo a raggruppare per regole di visibilità all'interno della
classe le variabili ed i metodi.
Mettendo prima i privated i protected e in fine i public.

Ulteriormente all'interno delle dichiarazioni
di visibilità tendo ad inserire raggruppandole per prima le variabili della classe
separandole tramite spazi dai metodi.
Questo non lo faccio per i costruttori e il distruttore che metto come prima voce nella rispettiva dichiarazione di visibilità.

Meglio se le dichiarazioni sono tutte i rispettivamente in ordine alfabetico.

Così prima cosa che si può notare e' la regola di visibilità poi la tipologia e in seguito le iniziali dell elemento della classe cercato.

A mio parere e' un metodo valido. Comunque sono aperto a idee più intelligenti per modificare il mio approccio.

Tommo
04-05-2012, 11:48
Io ho un "format" più o meno uguale, forse più strutturato nella dichiarazione della classe: prima elenco tutti i membri "public", poi i "protected" e poi i "private".
All'interno di ogni visibilità le dichiarazioni sono in questo ordine:

-classi nested
-typedef
-variabili
-costruttori
-distruttori
-metodi vari
-setters
-getters
-"boolean getters" (es: isWindowActive() )
-event callbacks virtuali e non (onWindowClosed, onButtonPressed)
-metodi di framework (metodi da usarsi solo all'interno della libreria anche se sono pubblici o protected e quindi ereditati, es: _fireOnButtonPressed() )

Sì sono parecchio fiscale :D
Ma così è facilissimo trovare tutto, e soprattutto è facile capire a che serve.

Un'altra cosa che faccio è NON includere alcun file "esterno" direttamente, es <ctime>: invece creo un "project common header" che include tutti i file esterni, e poi includo quello in tutti i file: è comodissimo perchè assicura la coerenza delle varie inclusioni/defines in tutto il progetto, e ti evita di dover pensare ogni volta a quali file servono.
E se si usano i precompiled headers, velocizza di parecchio la build :D

Too bad che su Linux ancora non sono riuscito a trvare un modo decente per usarli, e ogni progetto mi ci mette anni a compilare.
Ehhh, la superiorità tecnologica dell'open source :asd: