Perché dobbiamo inserire membri privati nelle intestazioni?

58

Le variabili private sono un modo per nascondere la complessità e i dettagli di implementazione all'utente di una classe. Questa è una caratteristica piuttosto carina. Ma non capisco perché in c ++ abbiamo bisogno di metterli nell'header di una classe. Vedo due fastidiosi inconvenienti a questo:

  • Riordina l'intestazione dall'utente
  • Forza la ricompilazione di tutte le librerie client ogni volta che gli interni vengono modificati

Esiste una ragione concettuale alla base di questo requisito? È solo per facilitare il lavoro fuori dal compilatore?

    
posta Simon 10.04.2012 - 11:25
fonte

3 risposte

65

È perché il compilatore C ++ deve conoscere la dimensione effettiva della classe per allocare la giusta quantità di memoria all'istanza. E la dimensione include tutti i membri, anche quelli privati.

Un modo per evitarlo è usare l'idioma Pimpl , spiegato da Herb Sutter nella sua serie di Guru della settimana # 24 e # 28 .

Aggiornamento

In effetti, questo (o più in generale, la distinzione tra header / file sorgente e #include s) è un ostacolo importante in C ++, ereditato da C. Indietro nei giorni in cui C ++ C è stato creato, non c'era ancora esperienza con lo sviluppo di software su larga scala, dove questo inizia a causare problemi reali. Le lezioni apprese da allora sono state ascoltate dai designer di linguaggi più recenti, ma il C ++ è vincolato da requisiti di compatibilità a ritroso, rendendo davvero difficile affrontare un problema così fondamentale nella lingua.

    
risposta data 10.04.2012 - 11:53
fonte
15

La definizione della classe deve essere sufficiente affinché il compilatore produca un layout identico nella memoria, ovunque sia stato utilizzato un oggetto della classe. Ad esempio, dato qualcosa di simile:

class X { 
    int a;
public:
    int b;
};

Il compilatore avrà in genere a all'offset 0 e b all'offset 4 . Se il compilatore ha visto questo come solo:

class X { 
public:
    int b;
};

Sarebbe "pensare" che b dovrebbe essere a offset 0 invece di offset 4. Quando il codice utilizza quella definizione assegnata a b , il codice che usa la prima definizione vedrebbe a essere modificato, e viceversa.

Il solito modo di minimizzare gli effetti di apportare modifiche alle parti private della classe viene solitamente chiamato idioma pimpl (di cui sono sicuro che Google può fornire una grande quantità di informazioni).

    
risposta data 10.04.2012 - 11:57
fonte
3

Ci sono probabilmente molte ragioni. Mentre i membri privati non sono accessibili dalla maggior parte delle altre classi, è comunque possibile accedere alle classi di amici. Quindi almeno in questo caso potrebbero essere necessari nell'intestazione, in modo che la classe di amici possa vedere che esistono.

La ricompilazione dei file dipendenti può dipendere dalla struttura di inclusione. Includendo i file .h in un file .cpp invece di un'altra intestazione, in alcuni casi è possibile evitare lunghe catene di ricompilazioni.

    
risposta data 10.04.2012 - 11:40
fonte

Leggi altre domande sui tag