struct A
{
A(const A& arg) : data(arg.data)
{
do_something_special();
}
// by writing copy constructor, we suppress the generation of
// implicit default constructor A::A()
int data;
};
void foo1()
{
A a; // does not work, since there's no default constructor
}
Diciamo che il nostro costruttore di default non fa nulla di speciale ed è (più o meno) pari al compilatore generato. Siamo in grado di risolvere il problema da entrambe scrivere la nostra costruttore di default (che può diventare noioso se la nostra classe ha molti membri non statici), oppure utilizzando il = default
sintassi:
struct A
{
A() = default;
A(const A& arg) : data(arg.data)
{
do_something_special();
}
int data;
};
funzioni eliminazione è utile quando si vuoi proibire l'uso di sovraccarichi specifici o specializzazioni di modelli o solo per vietare la copia (o lo spostamento) di oggetti.
void foo(char c) {}
void foo(int i) = delete; // do not allow implicit int -> char conversion
Quando si vuole proibire la copia (vale a dire oggetti thread), il solito modo idiomatica è di dichiarare costruttore di copia privata senza implementazione (sì, o usare boost :: noncopyable). Sebbene questo funzioni per la maggior parte dei casi, a volte è possibile ottenere alcuni oscuri errori di linker. Considerare:
struct A
{
A() = default;
friend void foo();
private:
A(const A&);
};
void foo()
{
A a;
A b(a); // results in linker error in gcc
}
Fare A(const A&)
cancellato, abbiamo evitare possibili errori del linker e rendere il nostro intento (non consentire la copia) molto chiaro.
@Christian: Se abbiamo semplicemente avuto 'struct S {S (int) {}};', la presenza di 'S (int)' sarebbe sopprime il costruttore predefinito implicitamente dichiarato. –
Le regole per POD sono state ridotte in C++ 0x/11, quindi il secondo esempio sarebbe anche un POD in C++ 0x/11. È inoltre possibile utilizzare i nuovi tratti :: is_pod per verificare se stessi con un asser statico, ad esempio. –
David
@David: Le regole per POD sono state effettivamente ridotte, ma il secondo 'S' non è ancora POD. Una struttura POD deve essere una classe banale. Una classe banale deve avere un costruttore di base banale. Un costruttore predefinito fornito dall'utente non è banale. Il secondo 'S' ha un costruttore predefinito fornito dall'utente e pertanto non è POD. –