Newsgroup: it.comp.lang.c++
Titolo: Window (): _hwnd (0) {} ???



Ciao!

Sto imparando a programmare in V C++ e in un sorgente che ho trovato

in rete e' presente questa definizione di classe:

class Window


     {


     public:


        

Window (): _hwnd (0) {}


        
Window (char const * caption, char const * className, HINSTANCE hInstance);


        
void Show (int cmdShow)


        
{


            
::ShowWindow (_hwnd, cmdShow);


            
::UpdateWindow (_hwnd);


        
}


     protected:


        
HWND _hwnd;


     };


non capisco come e' stato definito il costruttore evidenziato in rosso.

Ti ringrazio.

Maurizio




...


La sintassi che ti preoccupa e` quella detta "ctor
initializer list" -- lista di inizializzatori nel ctor (ctor
e` il modo breve di dire costruttore, come dtor lo
e` per distruttore).  Ogni costruttore puo` avere,
subito dopo la ")" dei parametri, un ":" seguito da
una lista di inizializzatori separati da "," prima
della "{"; questi inizializzatori possono riguardare
tutte le basi (dirette o virtuali) e i membri
dell'oggetto il cui costruttore stiamo scrivendo,
e vengono eseguiti nell'ordine: basi virtuali da
sinistra a destra, poi basi dirette idem, infine
membri "dall'alto in basso" nell'ordine dell'oggetto
(e` meglio scrivere gli inizializzatori nello stesso
ordine in cui vengono eseguiti, per chiarezza).
Vediamo un esempio semplice semplice, e
precisamente confrontiamo due costruttori:
class Pippo {
    std::string pluto;
public:
    Pippo(const char*);
    Pippo(std::string);
    // eccetera
};
Pippo::Pippo(const char* cc) {
    pluto = cc;
}
Pippo::Pippo(std::string ss): pluto(ss) {
}
I due ctor sono praticamente equivalenti
come "risultato finale": nel primo, pluto
viene prima costruito con il suo costruttore
di default, poi gli viene assegnata la stringa
implicitamente costruita dall'argomento cc;
nel secondo ctor, pluto viene _direttamente_
costruito con un costruttore di copia da ss.
In ambo i casi pluto finisce con il valore
stringa equivalente all'argomento passato,
ma il secondo ctor e` molto piu` efficiente:
evita di costruire inizialmente una string
con il default ctor per poi buttare via subito
questo con un assegnamento, come fa il
primo ctor!  Usando direttamente il ctor
giusto si risparmia praticamente meta` del
lavoro -- e il C++ e` un linguaggio fortemente
orientato all'efficienza, quindi...
Quindi merita abituarsi a scrivere SEMPRE
gli inizializzatori invece di assegnazioni nel
corpo del costruttore (cioe` fra le graffe); in
tanti casi non c'e` guadagno (quando i membri
sono di tipi builtin, poiche` in questi casi non
c'e` una vera e propria "costruzione di default"),
pero` non ci si rimette mai ed e` importante
prendere la buona abitudine.  Dunque, anche
nella classe Window che tu porti ad esempio,
l'autore ha adottato questa ottima prassi, che
invito tutti a generalizzare il piu` possibile!
(Il fatto, invece, di avere costruttori o altri
metodi inline nel corpo della classe, benche`
comodo per l'esposizione, e` secondo me
uno stile inferiore per codice di produzione,
in quanto richiede molto editing se uno, dopo,
decide che un dato metodo non deve piu`
essere inline; molto meglio, come regola
generale, tenere solo le dichiarazioni nel
corpo della classe -- con l'aggettivo inline
se occorre -- e le definizioni fuori dal corpo
nella classe, che sia nell'header file per un
inline o nel source file per un metodo non
inline [c'e` anche lo stile di avere un tipo di
file specifico per gli inline, come ad esempio
l'estensione .INL, che ha i suoi vantaggi]).
Alex