Jaki będzie rezultat poniższego kodu?
#include
class X
{
public:
int *px;
X( int init )
{ px = new int; *px = init; }
~X() { delete px; }
};
void print( X x )
{ printf( "%d
", *x.px ); }
int main() {
X x(15); print( x );
X y(16); print( x ); print( y );
return 0;
}
Odp:
Rezultat to np. 15 16 16. Dlaczego nie spodziewane 15 15 16 ?
Skoro nie został zdefiniowany konstruktor kopiujący dla klasy X, wywołanie funkcji 'print' nie stworzy głębokiej kopii dla obiektu x (zostanie skopiowany sam wskaźnik zamiast stworzenia duplikatu, czyli alokacji nowej porcji pamięci).
Property px lokalnej kopii obiektu x użytej w czasie wywołania 'print' wskazuje na ten sam int co px obiektu x.
Po wyjściu z funkcji 'print', destruktor niszczy lokalną kopię x, niszcząc też dynamicznie zaalokowany int (px dla x i lokalnej kopii wskazywały na niego).
Teraz px obiektu x wskazuje na niezaalokowaną komórkę pamięci.
W naszym przypadku, po utworzeniu obiektu y, kompilator przydzielił tą zwolnioną pamięć dla y, powodując to że px dla obiektu y i x wskazuje na ten sam int.