2014-11-14 4 views
10

vengo dalla programmazione C in cui i dati in una struct è disposto con la variabile superiore per primo, poi la seconda, la terza e così via ..Come è il layout di memoria di una classe contro una struct

I ora sto programmando in C++ e sto usando una classe invece. Io fondamentalmente voglio raggiungere lo stesso, ma voglio anche ottenere i metodi/set ed anche forse di altri metodi (Voglio anche provare farlo in un C++ stile e maye imparare qualcosa di nuovo).

C'è una garanzia per esempio che le variabili pubbliche saranno prima in memoria quindi la variabile privata?

+1

L'unica differenza sono i diritti di accesso. Regola empirica mantenere le variabili calde in alto. – 101010

+8

Non c'è alcuna differenza nel layout tra una classe e una struttura. –

+0

Quindi, se prima definisco le variabili pubbliche, saranno prima in memoria? E presumo di poter effettivamente accedere ai membri privati ​​in questo modo? – Phat

risposta

16

C'è una garanzia per esempio che le variabili pubbliche saranno prima nella memoria quindi nella variabile privata?

No, tale garanzia è non fatto - C++ 11 di serie, [class.mem]/14:

membri di dati non statici di un (non-union) classe con lo stesso accesso controllo (Articolo 11) sono assegnati in modo che i membri successivi hanno maggiore indirizzi all'interno un oggetto classe. L'ordine di allocazione dei membri di dati non statici con controllo di accesso diverso non è specificato (11).

Così

struct A 
{ 
    int i, j; 
    std::string str; 

private: 

    float f; 

protected: 

    double d; 
}; 

Si è garantito solo che, per un dato oggetto di tipo A,

  • i ha un indirizzo più piccolo di j e
  • j ha un indirizzo più piccolo di str

Si noti che i codici di classe struct e class non hanno alcuna differenza per quanto riguarda il layout: la loro unica differenza sono i diritti di accesso che esistono solo in fase di compilazione.


Dice solo l'ordine, ma non che la prima variabile effettivamente iniziare al "primo indirizzo"? Assumiamo una classe senza ereditarietà.

Sì, ma solo per classi di layout standard. Esiste una riga di requisiti che una classe deve soddisfare per essere una classe di layout standard, uno dei quali è che tutti i membri hanno lo stesso controllo di accesso.
Citando C++ 14 (lo stesso vale per il C++ 11, ma la formulazione è più indiretto), [class.mem]/19:

Se un oggetto di classe standard di layout ha alcun non- membri di dati statici, l'indirizzo è uguale all'indirizzo del primo membro non statico dei dati . Altrimenti, il suo indirizzo è lo stesso come l'indirizzo del suo primo base di classsubobject (se presente).[Nota: potrebbe pertanto essere il padding senza nome all'interno di un oggetto struct con layout standard, ma non all'inizio, come necessario per ottenere l'allineamento appropriato. - end nota]

[classe]/7:

Una classe standard la layout è una classe che:

  • ha alcun membri dati non statici digitare classe di layout non standard (o matrice di tali tipi) o riferimento,
  • non ha funzioni virtuali (10.3) e nessuna classe di base virtuale (10.1),
  • ha lo stesso controllo di accesso (Articolo 11) per tutti i membri di dati non statici,
  • ha alcun classi base non standard di layout,
  • o ha membri dati non statici nella classe più derivata e al massimo una classe base con membri dati non statici o non ha classi base con membri dati non statici e
  • non ha classi base dello stesso tipo del primo membro dati non statico.

110) Questo assicura che due sotto-oggetti che hanno lo stesso tipo di classe e che appartengono allo stesso oggetto più derivati ​​non sono allocati allo stesso indirizzo (5.10).

+0

Quindi non posso presumere che siano in ordine sequenziale se ho variabili sia pubbliche che private? Cosa succede se ho solo pubblico o solo privato? – Phat

+1

Quindi hanno effettivamente aumentato gli indirizzi. Come dice la citazione. – Columbo

+0

Dice solo l'ordine, ma non che la prima variabile inizi effettivamente dal "primo indirizzo"? Assumiamo una classe senza ereditarietà. – Phat

5

Per prima cosa: class e struct in C++ sono molto lo stesso - l'unica differenza è che tutti i membri prima del primo specificatore di accesso in un class sono considerati privati, mentre in un struct sono pubbliche.

Esiste una garanzia ad es. che le variabili pubbliche saranno prima in memoria quindi la variabile privata?

Non esiste tale garanzia. Quando non c'è ereditarietà, la memoria verrà allocata ai membri della classe nell'ordine in cui li dichiari all'interno dello stesso gruppo di accesso. Spetta al compilatore decidere se le variabili dei membri pubblici devono essere posizionate prima di quelle private/protette o viceversa. Come C, C++ può aggiungere padding tra i membri della classe.

L'ereditarietà rende le cose più complicate, poiché i membri di dati della classe base devono essere posizionati all'interno della classe derivata. Oltre a ciò, esiste un'eredità virtuale e un'ereditarietà multipla, con regole complesse.

Fondamentalmente voglio ottenere lo stesso [layout], ma voglio anche ottenere metodi get/set e forse anche altri metodi.

Se si rendono privati ​​tutti i membri di dati della classe e si aggiungono funzioni di membro di accesso (questo è ciò che C++ chiama "metodi" da altre lingue) si otterrebbe questo effetto.

Problemi correlati