2011-04-01 18 views
162
class my_class 
{ 
    ... 
    my_class(my_class const &) = delete; 
    ... 
}; 

Cosa significa "= delete" in questo contesto?Significato di = cancella dopo la dichiarazione di funzione

Esistono altri "modificatori" (diversi da = 0 e = delete)?

+7

Sono abbastanza sicuro che non è di serie C++ ... – Blindy

+0

Dove hai preso questo codice? –

+19

@Blindy Sarà standard in C++ 0x, a breve. –

risposta

130

Eliminazione di una funzione è a C++11 feature:

L'idioma comune di "divieto di copia" può ora essere espresso direttamente:

class X { 
    // ... 
    X& operator=(const X&) = delete; // Disallow copying 
    X(const X&) = delete; 
}; 

[...]

Il "delete "il meccanismo può essere utilizzato per qualsiasi funzione. Per esempio, abbiamo in grado di eliminare una conversione indesiderata come questo:

struct Z { 
    // ... 

    Z(long long);  // can initialize with an long long   
    Z(long) = delete; // but not anything less 
}; 
+0

Non è il metodo tradizionale per "vietare la copia" solo per rendere copy-ctor e operator = "private?" Questo va un po 'oltre e ordina al compilatore di non generare nemmeno le funzioni. Se sono entrambi privati ​​e = cancella, la copia è doppiamente proibita? –

+2

@Reb, '= delete' rende il metodo inaccessibile anche in contesti che possono vedere metodi' private' (cioè all'interno della classe e dei suoi amici). Questo rimuove qualsiasi incertezza quando stai leggendo il codice. @Prasoon, il secondo esempio si limita a eliminare solo i costruttori: sarebbe bello vedere un operatore 'cancellato long()' per esempio. –

0

Questa è cosa nuova in standard 0x C++ in cui è possibile eliminare una funzione ereditata.

+8

È possibile eliminare qualsiasi funzione. E.g 'void foo (int); template void foo (T) = delete; 'interrompe tutte le conversioni implicite. Solo gli argomenti di tipo 'int' sono accettati, tutti gli altri cercheranno di creare un'istanza di una funzione" cancellata ". – UncleBens

58
  1. = 0 significa che una funzione è virtuale e non è possibile creare un'istanza di un oggetto da questa classe. Devi derivarne e implementare questo metodo
  2. = delete significa che il compilatore non genererà quei costruttori per te. AFAIK è consentito solo al costruttore di copia e all'operatore di assegnazione. Ma non sono troppo bravo per il prossimo standard.
+3

Ci sono altri usi della sintassi '= delete'. Ad esempio, è possibile utilizzarlo per disabilitare esplicitamente alcune conversioni implicite che potrebbero aver luogo con la chiamata. Per questo basta cancellare le funzioni sovraccaricate. Dai un'occhiata alla pagina di Wikipedia su C++ 0x per maggiori informazioni. – LiKao

+0

Lo farò non appena ne troverò qualcuno. Indovina che è ora di recuperare con C++ 0X – mkaes

+0

Sì, rocce C++ 0x. Non vedo l'ora che GCC 4.5+ sia più comune, quindi posso iniziare a utilizzare lambdas. – LiKao

1

Nuovo standard C++ 0x. Vedere la sezione 8.4.3 nel N3242 working draft

+0

Whoa, quella bozza non è aggiornata. Ecco l'ultima (dal 3 aprile 2011): http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf – TonyK

+0

Grazie e aggiornato il collegamento. Molto utile per ottenere la bozza attuale. La sezione/contenuto di riferimento era corretta anche nella vecchia bozza quindi non capisco il voto negativo. – dubnde

+0

Rimosso, ora hai aggiornato il collegamento :-) – TonyK

1

= delete è una funzionalità introdotta in C++ 11. Come da =delete non sarà permesso chiamare questa funzione.

In dettaglio.

Supponiamo in una classe.

Durante la chiamata a questa funzione per l'assegnazione obj non è consentito. Significa che l'operatore di assegnazione limiterà a copiare da un oggetto a un altro.

3

Questo estratto da Il C++ linguaggio di programmazione [4 ° Edizione] - Bjarne Stroustrup libro parla il vero scopodietro utilizzando =delete:

utilizzando la copia di default o spostare per una classe in una gerarchia è tipicamente un disastro: dato solo un puntatore ad una base, noi semplicemente non sappiamo cosa membri della classe derivata ha (§3.2.2), in modo che non possiamo sapere come copiare loro.Quindi, la cosa migliore da fare è di solito per eliminare la copia di default e spostare le operazioni, cioè, di eliminare le definizioni di default di queste due operazioni:

class Shape { 
public: 
    Shape(const Shape&) =delete; // no copy operations 
    Shape& operator=(const Shape&) =delete; 

    Shape(Shape&&) =delete; // no move operations 
    Shape& operator=(Shape&&) =delete; 
    ˜Shape(); 
    // ... 
}; 

Ora un tentativo di copiare una forma sarà catturato dal compilatore.

Il =delete meccanismo è generale, cioè, può essere utilizzata per sopprimere qualsiasi operazione