PDA

Visualizza la versione completa : [C++] Funzione privata in struct


Jack5891
04-03-2011, 16:21
Ciao a tutti,
vi pongo una semplice domanda riguardo il linguaggio C++.
Se mi trovo davanti una struttura definita in questo modo:

struct my_struct
{
.....
my_struct();
.....
private:
my_struct( const my_struct & )
}

cosa sta a significare la funzione privata my_struct? O meglio, che significa passare come parametro solo &? io di solito passo o puntatori (int *a) o indirizzi (int &a) ma la & da sola che significa in questo caso?
Grazie a tutti!

MItaly
04-03-2011, 16:23
Nei prototipi puoi omettere il nome del parametro; è un normale passaggio per reference (o indirizzo come lo chiami tu).
In particolare, quella funzione è un costruttore di copie; il fatto che sia privato e non definito indica che si tratta del classico idioma per disattivare il costruttore di copie predefinito generato dal compilatore.

Jack5891
04-03-2011, 16:38
Ti ringrazio per la risposta rapida e chiara.
Ho solo un dubbio sull'ultima tua affermazione. Cosa significa in parole più semplici "si tratta del classico idioma per disattivare il costruttore di copie"?
Grazie!

pippopoppo
04-03-2011, 22:33
struct your_struct
{
.....
your_struct();
.....
}


/// Nel programma

your_struct a;
your_struct b = a; // OK

my_struct c;
my_struct d = c; // ERRORE (in compilazione)
// il costruttore per copia di my_struct
// è privato e non può essere invocato

my_struct d;
d = c; // OK: non copia ma assegnazione .
// Vuoi evitare anche l'assegnazione?
// Devi ridefinire anche l'operatore =

/// Nel programma

struct my_struct
{
.....
my_struct();
.....
private:
my_struct( const my_struct & );
my_struct& my_struct::operator=( const my_struct& );
}

/// CODICE.....

my_struct c;
my_struct d = c; // ERRORE (in compilazione)

my_struct d;
d = c; // ERRORE (in compilazione)

MItaly
04-03-2011, 22:40
In C++ quando non dichiari un tuo costruttore di copie il compilatore ne genera uno automaticamente, che crea una copia del tuo oggetto bit-a-bit ("shallow copy"); spesso però questo tipo di copia non è adeguato.
Pensa ad esempio ad un oggetto che ha dei campi puntatori che deve deallocare nel distruttore: il costruttore di copie di default copierebbe semplicemente i puntatori, e ciascuno dei due distruttori distruggerebbe gli stessi puntatori - si ha un problema di double free.
D'altra parte spesso e volentieri la logica di deep copy è complessa da implementare, o banalmente non si prevede di copiare la classe in questione, per cui si vorrebbe semplicemente disattivare il costruttore di copie di default, in modo da ottenere semplicemente un errore di compilazione nel caso in cui si tenti di copiare un oggetto di tale tipo.
Il modo più usato per fare ciò è dichiarare il costruttore di copie come privato e non implementarlo. In questa maniera il costruttore di copie di default non viene generato, ma ogni tentativo di copia (ossia, di richiamare il costruttore di copie) fallisce con un errore di compilazione dato che il costruttore di copie è privato. Se anche la copia viene effettuata da codice che ha la possibilità di chiamare metodi privati (ad esempio classi friend) si ottiene un errore di linking dato che il costruttore di copie non è effettivamente implementato.

Nella futura versione dello standard C++ è previsto un modo esplicito per disattivare la creazione automatica del costruttore di copie: sarà infatti possibile scrivere:


struct my_struct
{
// ...
my_struct( const my_struct & ) = delete;
};

(link (http://en.wikipedia.org/wiki/C%2B%2B0x#Explicitly-defaulted_and_deleted_special_member_functions))

Nota che tutto questo si applica (mutatis mutandis) anche ai costruttori di default e agli operatori di assegnamento.

Loading