2012-12-01 24 views
51

Wann/warum möchte ich meinen Konstruktor explizit löschen? Angenommen, der Grund ist, seine Verwendung zu verhindern, warum nicht einfach private machen?Warum explizit den Konstruktor löschen?

class Foo 
{ 
    public: 
    Foo() = delete; 
}; 

Vielen Dank!

+9

Es geht irgendwie gut mit '= default', nicht einmal die Klasse kann es verwenden, und ich persönlich bevorzuge * Verwendung der gelöschten Funktion. * Over * Funktion ist privat. * Ersteres sagt ausdrücklich" Dies ist nicht gemeint benutzt werden." Wenn irgendetwas daraus hervorgeht, macht die Klasse, die es nicht benutzen kann, tatsächlich einen semantischen Unterschied. – chris

+8

Ich glaube wirklich, dass die Leute anfangen, aggressiv zu werden mit den engen Stimmen. Ich sehe nicht, wie das nicht konstruktiv ist. –

+4

@LuchianGrigore: Einverstanden. Ich habe mich gefragt, warum die Gemeinschaft so viel steifer geworden ist. Ich verstehe den Punkt nicht. –

Antwort

58

Wie wäre:

//deleted constructor 
class Foo 
{ 
    public: 
    Foo() = delete;  
    public: 
    static void foo(); 
}; 

void Foo::foo() 
{ 
    Foo f; //illegal 
} 

gegen

//private constructor 
class Foo 
{ 
    private: 
    Foo() {}  
    public: 
    static void foo(); 
}; 

void Foo::foo() 
{ 
    Foo f; //legal 
} 

Sie sind grundsätzlich verschiedene Dinge. private teilt Ihnen mit, dass nur Mitglieder der Klasse diese Methode aufrufen oder auf diese Variable zugreifen können (oder natürlich auf Freunde). In diesem Fall ist es für eine static Methode dieser Klasse (oder eines anderen Mitglieds) zulässig, einen private Konstruktor einer Klasse aufzurufen. Dies gilt nicht für gelöschte Konstruktoren.

Probe here.

+2

Sie brauchen das nicht deklariere Foo() überhaupt, wenn du Foo (int) deklarierst. Foo() wird nicht generiert und somit ist Foo f sowieso ungültig. Ihr Beispiel zeigt also keinen Fall für gelöschten Konstruktor. Sehen Sie selbst - http://ideone.com/mogiIF – mark

+1

@mark Ich schrieb 2 Konstruktoren, um den Punkt zu beweisen. Ich werde bearbeiten, damit es für alle klar ist. –

+0

Ich verstehe den Unterschied, ich verstehe einfach nicht den Mehrwert der DELETE-Anweisung im Allgemeinen und für einen Konstruktor im Besonderen. Immerhin könnte ich einen privaten Standardkonstruktor ohne den Körper spezifizieren. Dann schlägt der Code auch nur während der Verknüpfung fehl. Nun, ich kann sehen, dass Löschen die Absicht expliziter vermittelt, aber das ist es auch schon. – mark

1

Ich habe im Quellcode von LLVM (in AlignOf.h zum Beispiel) mit Standard-Ctors als 'gelöscht' deklariert. Die zugehörigen Klassenvorlagen befinden sich normalerweise in einem speziellen Namespace namens 'llvm :: detail'. Der ganze Zweck dort war meiner Meinung nach, dass sie diese Klasse nur als Hilfsklasse betrachteten. Sie hatten nie vor, sie zu instantiieren; nur, um sie im Kontext anderer Klassenvorlagen mit einigen Metaprogrammierungstricks zu verwenden, die in der Kompilierungszeit ausgeführt werden.

Eg. Es gibt diese AlignmentCalcImpl-Klassenvorlage, die nur innerhalb einer anderen Klassenvorlage namens AlignOf als Parameter für den Operator sizeof (.) verwendet wird. Dieser Ausdruck kann in der Kompilierzeit ausgewertet werden; und es gibt keine Notwendigkeit, die Vorlage zu instanziieren -> also warum nicht deklarieren die Standard-Ctor löschen, um diese Absicht auszudrücken.

Aber es ist nur meine Annahme.

Verwandte Themen