Il punto non è ottimizzare, ma fare attenzione perché il programma non vada in tilt.
Ad esempio:
codice:
Image* img = new Image(...);
Button btn(img); // passo il puntatore ad un oggetto nell'heap.
//Dove lo libero? Nel distruttore di Button o in seguito?
Image img_a(...);
Button btn_a(&img_a); // passo il puntatore di un oggetto sullo stack.
// Non posso fare una delete di un oggetto posto sullo stack.
Image* img_a = new Image(...);
Button btn_b(*img_b); // passo il reference.
delete img_b;
// il reference di btn_b adesso è invalido.
Sono esempi un pò forzati, ma dovrebbero rendere l'idea di che succede se non si fà attenzione al lifetime dell'oggetto considerato.
Invece:
codice:
Image* img = new Image(...);
Button btn(img); // passo il puntatore ad un oggetto nell'heap,
ma non lo libero nel distruttore: ci devo pensare fuori.
Image img_a(...);
Button btn_a(&img_a); // passo il puntatore di un oggetto sullo stack.
Image img_b(...)
Button btn(img_b); // passo un reference.
//L'oggetto img_b ha lifetime superiore rispetto a btn, quindi sono sicuro.
Vanno bene.
In caso tu voglia utilizzare un reference, la sintassi della classe diventa:
codice:
class Button
{
private:
Image& img;
public:
Button(Image& i ) : img(i) // obbligatorio
{ }
void draw( void )
{
img.draw();
}
};