2010-08-06 11 views
7
#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS 
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ 
    TypeName(const TypeName&);       \ 
    void operator=(const TypeName&) 

Ich bin, lesen Quellcode von Google. Warum Kopierkonstruktor und Zuweisungsoperator nicht erlaubt sind?Warum Kopierkonstruktor und Zuweisungsoperator nicht erlaubt sind?

+1

Sie heißen "Copy Constructor" und "Zuweisungsoperator". Es gibt keinen Zuweisungskonstruktor. – Sjoerd

+2

Ich würde sie entweder "Konstruktor" und "Zuweisungsoperator" oder "Kopiere Konstruktor" und "Kopierzuweisungsoperator" nennen. –

+2

würde ich das EVIL nicht nennen, diese Art von Farben sie in einem schlechten Licht. Deaktivieren Sie sie einfach wie boost: boost :: nicht kopierbar –

Antwort

12

Um zu verhindern, dass Instanzen der Klasse kopiert oder zugewiesen werden. Die meisten Klassen sollten das Kopieren nicht erlauben. Betrachten Sie zum Beispiel eine BankAccount-Klasse - wenn Sie Software für eine Bank schreiben, werden sie nicht allzu glücklich sein, wenn Sie Kopien von Konten erstellen und dann Gutschriften und Belastungen auf diese verschiedenen Kopien anwenden.

+0

Perfektes Beispiel. Wie ich wünschte, sie erlaubten es :) !!!! – DumbCoder

+0

+1 .... @DumbCoder Wenn Sie der Coder für die Software dieser Bank wären, wäre es möglich !! – KedarX

+0

@Neil Butterworth: Warum nicht einfach ein Singleton verwenden? – MainID

1

Wenn Ihr Typ Zeiger oder Referenzelemente enthält oder keinen semantischen Sinn zum Kopieren hat (z. B. ein Ressourcen-Handle, das im Destruktor freigegeben werden muss), empfiehlt es sich, den Kopierkonstruktor zu deaktivieren Aufgabenverwalter. In C++ 0x (z. B. in g ++ 4.4 oder höher im -std = C++ 0x-Modus) können Sie sie als gelöscht deklarieren. In älteren Compilern deklarieren Sie diese nur als privat und nicht implementiert.

7

Das Problem mit dem Kopierkonstruktor und dem Kopierzuweisungsoperator besteht darin, dass der Compiler Implementierungen automatisch generiert, wenn sie nicht explizit deklariert sind.

Dies kann leicht zu unbeabsichtigten Problemen führen. Wenn eine Klasse einen nicht-trivialen Destruktor hat, muss sie fast immer auch eigene Implementierungen für den Kopierkonstruktor und den Kopierzuweisungsoperator bereitstellen (dies ist der Law of the Big Three), da die vom Compiler erzeugten Standard-Generatoren normalerweise das Falsche tun.

Verletzung des Gesetzes der Big Three führt oft zu Fehlern wie Doppel-Frees von Datenelementen und Speicherbeschädigung. Es kommt nicht selten vor, dass diese Art von Fehlern auftritt, weil der Autor der Klasse sich nie Gedanken über das Kopierverhalten gemacht hat und es für die Verbraucher leicht ist, Objekte unbeabsichtigt zu kopieren.

Wenn der Autor der Klasse nicht wirklich darüber nachgedacht hat, Instanzen dieser Klasse ordnungsgemäß zu kopieren (oder die Klasse einen trivialen Destruktor hat), ist es besser, das Kopieren explizit zu verbieten, um mögliche Probleme zu vermeiden. Die Implementierung der Kopierbarkeit könnte dann aufgeschoben werden, bis ein tatsächlicher Bedarf dafür besteht.

+4

Das wird mit dem kommenden Standard C++ 0x mit dem Zusatz Move Constructor/Assignment zum "Gesetz der Big Five"! – David

+1

@David: Der Operator move constructor/move-assignment wird aktiviert (der Compiler generiert sie nicht, wenn Sie sie weglassen). – jamesdlin

+0

Sie haben recht, aber wenn Sie Wert auf Leistung legen, werden Sie sie auch bereitstellen. – David

Verwandte Themen