2011-08-29 14 views
8

Stavo guardando le nuove funzionalità di C++ 11 e una di queste mi confonde, perché non riesco a capire come usarlo in Real World.Funzioni cancellate e predefinite Esempi reali

Sono funzioni eliminate e predefinite, qualcuno ha esempi reali del suo utilizzo o è solo una di quelle funzionalità che aggiunge solo un po 'di zucchero?

risposta

8
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.

9

Una funzione membro speciale dichiarata dall'utente non è banale. Se una classe ha funzioni di membri speciali non banali, la classe non è POD. Pertanto, questo tipo è POD:

struct S { 
    S() = default; 
    S(int) { } 
}; 

ma questo tipo non è POD:

struct S { 
    S() { } 
    S(int) { } 
}; 
+0

@Christian: Se abbiamo semplicemente avuto 'struct S {S (int) {}};', la presenza di 'S (int)' sarebbe sopprime il costruttore predefinito implicitamente dichiarato. –

+0

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

+0

@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. –

1

Si useranno le funzioni eliminate per le classi in cui si desidera impedire la copia o l'istanza diretta, ad esempio (a la singleton in cui si desidera eseguire invece una funzione get_instance()). Puoi anche usare delete per evitare alcune varianti del tuo costruttore.

Il valore predefinito è utile se si desidera che il costruttore generato dal compilatore sia uno di quelli generati implicitamente. Ad esempio, se si crea un costruttore di argomenti personalizzati, l'argomento di default non verrà generato dal compilatore, pertanto è possibile chiedere che venga generato automaticamente con la parola chiave predefinita.

Vedi qui per gli esempi di cui sopra

http://www2.research.att.com/~bs/C++0xFAQ.html#default

Problemi correlati