2012-10-04 10 views
12

Quando si scrive un metodo helper per una classe in C++, dovrebbe essere dichiarato come metodo privato nella definizione della classe nel file di intestazione (.h)? Per esempio:La funzione di supporto dovrebbe andare nell'intestazione o nel file di implementazione?

/*Foo.h*/ 
class Foo { 

    public: 
     int bar(); 

    private: 
     int helper(); 
}; 
... 
/*Foo.cpp*/ 
... 
int foo::bar() { 
    int something = this->helper(); 
} 

int foo::helper() { 
    ... 
} 

Oppure, in alternativa, è meglio non dichiararla come un membro privato della classe, e invece solo ne fanno una funzione di free-standing per l'attuazione?

/*Foo.h*/ 
class Foo { 
    public: 
     int bar(); 
}; 
... 
/*Foo.cpp*/ 
... 
int Foo::bar() { 
    int something = helper(); 
    ... 
} 

int helper() { 
    ... 
} 

risposta

18

Una funzione indipendente nel file di implementazione migliora l'incapsulamento: ha bisogno di alcuna dichiarazione nell'intestazione, quindi non la ricompilazione del codice del client quando i suoi cambiamenti di firma per qualsiasi motivo. Per me, questo è un buon motivo per preferire questa opzione ogni volta che è fattibile. (Assicurati di metterlo nello spazio dei nomi anonimi per evitare scontri identificatori in fase di collegamento.)

Tuttavia, un metodo private ha accesso ad un'istanza di classe e le sue parti intime tramite il puntatore this. Se ha bisogno di tale accesso, allora deve essere un metodo o uno friend. In entrambi i casi, sarà visibile nella definizione della classe (file di intestazione) e i metodi sono semplicemente più convenienti degli amici.

+1

Per espandere il secondo paragrafo: [preferisce le funzioni di non membro non amico] (http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197). Se una funzione non ha bisogno di accesso privato, non dargli accesso privato. –

+0

@sftrabbit: grazie. Ho affinato un po 'il secondo paragrafo. –

1

La mia posizione è che l'intestazione contenga meno pubblicità possibile mentre si ottengono le proprietà di progettazione e layout desiderate. Se c'è un'opzione entra nella fonte. Tuttavia, alcuni dettagli interni richiedono l'accesso a troppi dettagli interni di una classe per renderlo praticabile nell'implementazione.

4

Se la funzione di aiuto ha senso essere un metodo dell'oggetto, preferirei quasi sempre farne una funzione membro, quindi esiste un puntatore implicito this, anziché passare un Foo * alla funzione di supporto.

Se la funzione di supporto non ha bisogno di essere un metodo dell'oggetto (ovvero, non ha bisogno di accedere ai membri dati o altre funzioni membro), quindi renderlo una funzione autonoma (static o in un anonimo spazio dei nomi, preferibilmente).

2

Questo è un po 'soggettivo, penso.

Dal mio punto di vista, dipende se ha qualcosa a che fare con i membri della classe e/o se ci si aspetta che le classi di amici lo usino (o classi derivate nel caso di accesso a protected).

Se la funzione non opera effettivamente su alcun membro e nessun altro è interessato, è necessario mantenerlo nel file di implementazione come funzione statica. Inoltre, se si tratta di un'operazione che deve essere veloce, puoi cogliere questa opportunità per renderla inline.

Al contrario, se la funzione opera sulla classe o può avere usi aggiuntivi in ​​classi derivate o correlate, renderla membro.

Problemi correlati