Newsgroup: it.comp.lang.c++
Titolo: Ma le classi in realtà cosa sono?

Cioè ho una mia classe (es. class Madre) che contiene a sua volta
delle classi (es. class Figlia), più funzioni e uno std::vector nel
quale vengono aggiunti degli elementi.
Se dichiaro una variabile come Figlia f1, sizeof(f1) mi restituisce
12.
Se dichiaro una variabile come Madre m1, aggiungo dei dati in m1,
sizeof(m1) mi restituisce 12.
Mi aspettavo qualcosa di diverso, più pesante in termini di memoria
occupata.
Se devo passare un oggetto come parametro di una funzione, quanto
spreco c'è rispetto a passare un puntatore all'oggetto?


Girovagando un tantino su google ho letto che spesso i compilatori
trasformano sotto banco il passaggio di oggetti come riferimenti agli
oggetti.
Quindi oggetto vs puntatore dovrebbero essere equivalenti in termini
di velocità, stack usato, eccetera eccetera.
Quello che non mi torna sono i 12 bytes. Un normale puntatore ha
dimensione 4, la classe 12, praticamente il triplo.
Ora per fare una prova ho scrtitto questo:
http://pastebin.com/m21e98796
in cui il puntatore ad intero occupa 4 bytes, quello all'oggetto 16.
Boh...
g++ 3.4.2 su Windows
su Mac non so esattamente, devo controllare.

 Boh...
Lascia perdere.
Tutti questi dettagli sono dipendenti dall'implementazione enon sono 
specificati dal c++.
Comunque in linea di massima sizeof(oggetto)>=somma(sizeof(membri))
poi bisogna vedere se ci sono di mezzo vtable o altri dettagli 
implementativi...
e poi bisogna vedere come allinea il compilatore
insomma una regola generale non esiste
Nel tuo caso non hai funzioni virtuali e hai 2 membri.
Molto ragionevolmente l'int occupa 4 bytes e il vector ne occupa 12.
Sulla size del vector, poco da dire: anche questa � fortemente 
dipendente dall'implementazione. Lo std non credo dica nulla a tal 
proposito...

 proposito...
E quindi, tornando al discorso iniziale, passare un oggetto ad una
funzione è uguale a passarlo per riferimento? Fa tutto il compilatore?
Oppure conviene passare per riferimento?
In teoria per riferimento, cioè passo il puntatore, questo lo
immagino, ma non vorrei riscrivere tanto codice quando poi magari il
compilatore ottimizza per conto suo...

 compilatore ottimizza per conto suo...
Giusto, però temo che tu abbia ancora un po' di confusione sull'uso di
puntatori e riferimenti.
Ciao,
m.

 occupata.
Stanley Lippman molti anni fa ha scritto un libro interessante su
questo argomento specifico.
E' vecchiotto (1995) ma te lo consiglio, se riesci ancora a trovarlo
(forse su Amazon):
"Inside the C++ Object Model"

 puntatori e riferimenti.
Si in effetti credo di non aver capito la differenza tra riferimento e
puntatore o_O
Ero convinto che la differenza tra passaggio per valore e per
riferimento è che nel primo caso venga creata una copia dell'oggetto/
variabile, mentre nel secondo caso si usi un puntatore all'oggetto/
variabile...

 variabile...
Il succo è quello; solo nel secondo caso non si usa un *puntatore*,
bensì appunto un riferimento - che è l'indirizzo statico e costante al
quale si trova l'oggetto, ossia il suo l-valore. Questo è il motivo
per cui un riferimento (almeno, fino allo standard attuale del C++)
può essere solo un r-valore.
Sia f una funzione che assume un parametro formale, io lo posso
passare per:
* valore: con copia nel passaggio che viene distrutta alla fine dello
scope della funzione
* riferimento: passo un indirizzo di memoria al quale il compilatore
sa di trovare l'oggetto - solitamente soggetto ad ottimizzazioni come
quella che citavo nell'altro messaggio
* puntatore: passo una variabile con il valore che rappresenta
l'indirizzo di memoria al quale si dovrebbe (a meno di errori) trovare
l'oggetto
Il valore implica la copia, gli altri due metodi no.
Un riferimento è sempre costante, perché non è una variabile.
Un puntatore può essere riassegnato a piacere (a meno che non sia
dichiarato come costante ovviamente, per esempio: "int *const pippo").
Un puntatore può essere dereferenziato, e se ne può prendere lo l-
valore per inserirlo in un altro puntatore (per es. "int **pluto"). Un
riferimento no.
Ciao,
m.

 bit allinea a 4 byte
Non credo. Io direi che "usa le stesse strategie che vengono usate per
le struct C". Indicativamente l'allineamento non e' a 4 byte: se hai due
char, per dire, il tutto IMHO non verra' posizionato dalle normali
implementazioni come
[x|-|-|-|x|-|-|-]
ma come
[x|x]
Idem con degli interi da 2 byte. Non ho tuttavia provato, sto andando a
memoria, quindi posso sbagliare.
-- 
-riko