Quando / perché dovrei voler eliminare esplicitamente il mio costruttore? Supponendo che il motivo sia per impedirne l'utilizzo, perché non farlo e basta private?
class Foo
{
public:
Foo() = delete;
};
Quando / perché dovrei voler eliminare esplicitamente il mio costruttore? Supponendo che il motivo sia per impedirne l'utilizzo, perché non farlo e basta private?
class Foo
{
public:
Foo() = delete;
};
delete. Sia la domanda che la risposta di Luchian si qualificano facilmente come costruttive. Chiunque non respiri i punti più fini di C ++ 11 ma dovrà presto ottenere qualcosa da entrambi.
Risposte:
Che ne dite di:
//deleted constructor
class Foo
{
public:
Foo() = delete;
public:
static void foo();
};
void Foo::foo()
{
Foo f; //illegal
}
contro
//private constructor
class Foo
{
private:
Foo() {}
public:
static void foo();
};
void Foo::foo()
{
Foo f; //legal
}
Sono fondamentalmente cose diverse. privateti dice che solo i membri della classe possono chiamare quel metodo o accedere a quella variabile (o agli amici ovviamente). In questo caso, è legale per un staticmetodo di quella classe (o qualsiasi altro membro) chiamare un privatecostruttore di una classe. Questo non vale per i costruttori eliminati.
Campione qui .
perché eliminare esplicitamente il costruttore?
Un altro motivo:
io usodelete quando voglio assicurarmi che una classe venga chiamata con un inizializzatore. Lo considero un modo molto elegante per ottenere questo risultato senza controlli di runtime.
Il compilatore C ++ esegue questo controllo per te.
class Foo
{
public:
Foo() = delete;
Foo(int bar) : m_bar(bar) {};
private:
int m_bar;
}
Questo codice, molto semplificato , assicura che non ci sia istanziazione come questa:Foo foo;
Fooavesse numerosi costruttori, ma non uno predefinito, Foo foo;causerebbe un errore molto più lungo elencando tutti i costruttori implicitamente definiti, protetti e privati che non è riuscito a trovare.
Ho incontrato i ctors predefiniti dichiarati come "cancellati" nel codice sorgente di LLVM (in AlignOf.h per esempio). I modelli di classe associati si trovano solitamente in uno speciale spazio dei nomi chiamato "llvm :: detail". L'intero scopo lì credo fosse che consideravano quella classe solo come una classe di aiuto. Non hanno mai inteso istanziarli; solo per usarli nel contesto di altri modelli di classe con alcuni trucchi di metaprogrammazione che vengono eseguiti in fase di compilazione.
Per esempio. c'è questo modello di classe AlignmentCalcImpl che viene utilizzato solo all'interno di un altro modello di classe chiamato AlignOf come parametro per l'operatore sizeof (.). Quell'espressione può essere valutata in fase di compilazione; e non c'è bisogno di istanziare il modello -> quindi perché non dichiarare il ctor predefinito delete per esprimere questa intenzione.
Ma è solo una mia ipotesi.
= defaultcerto senso va bene con , nemmeno la classe può usarlo, e personalmente preferisco vedere Uso della funzione cancellata. over La funzione è privata. Il primo afferma esplicitamente "Questo non è pensato per essere utilizzato". Se ne esce qualcosa, il fatto che la classe non sia in grado di usarlo fa effettivamente una differenza semantica.