Kopien von Objekten verhindern?
-
Hallo!
Was muss ich alles tun, um zu verhindern das von Objekten durch den Benutzer Kopien angelegt werden können?
Den Kopierkonstruktur leer implementieren und private machen
Den =-operator implementieren (für Objekt* und Objekt&) und private machenIst das so richtig? Was fehlt noch?
-
In der Boost-Bibliothek gibt es so eine kleine, praktische Klasse namens "noncopyable". Die sieht in etwa so aus:
class noncopyable { protected: noncopyable() {} ~noncopyable() {} private: noncopyable(noncopyable const&); noncopyable const& operator=(noncopyable const&); };Du kannst jetzt Deine Klasse so schreiben:
class dings : private noncopyable { ... };Der Compiler kann dann keinen Copy-Ctor und keinen Zuweisungsoperator mehr automatisch für dings generieren, weil Copy-Ctor und Zuweisungsoperator der Oberklasse privat sind.
siehe noncopyable.hpp und utility.hpp
Gruß,
SP
-
Um warum ihn nicht einfach privat machen?! Wozu ableiten!
-
1. Tipparbeit sparen
2. Es drückt auf einen Blick aus was die Idee ist (nämlich das Kopieren zu verhindern)Simon
-
class noncopyable { protected: noncopyable() {} ~noncopyable() {}Muss ich da dann noch irgendwas mit virtual beachten oder kann man das gefahrlos bei jeder Klasse so anwenden?
-
Muss ich da dann noch irgendwas mit virtual beachten oder kann man das gefahrlos bei jeder Klasse so anwenden?
Das kannst Du gefahrlos anwenden und brauchst nichts virtual zu machen.
Simon
-
Fragensteller2 schrieb:
Um warum ihn nicht einfach privat machen?! Wozu ableiten!
1. ist kürzer
2. ist leserlicher. Man weiß sofort, was gemeint ist
3. Elementfunktionen und Freunde können dann auch keine Kopie anlegen oder den Zuweisungsoperator benutzen.
4. Es tut nicht weh (empty class optimization, es wird kein virtual benötigt)Gruß,
SP
-
Sebastian Pizer schrieb:
Fragensteller2 schrieb:
Um warum ihn nicht einfach privat machen?! Wozu ableiten!
4. Es tut nicht weh (empty class optimization, es wird kein virtual benötigt)
Gruß,
SPMagst du den Punkt kurz erläutern?
Hab mal nach empty base class optimization gegoogelt, allerdings sind die erklären echt Mist.
Es geht jetzt irgendwie darum, dass man, obwohl man eine zusätzliche Klasse verwendet, von der man erbt, keine Speicherverschwendung hat?
-
Kopiererei schrieb:
Es geht jetzt irgendwie darum, dass man, obwohl man eine zusätzliche Klasse verwendet, von der man erbt, keine Speicherverschwendung hat?
Ja.
Was willst du jetzt noch erklärt haben? Das sagt doch eh schon alles.
-
hustbaer schrieb:
Kopiererei schrieb:
Es geht jetzt irgendwie darum, dass man, obwohl man eine zusätzliche Klasse verwendet, von der man erbt, keine Speicherverschwendung hat?
Ja.
Was willst du jetzt noch erklärt haben? Das sagt doch eh schon alles.Das sagt nicht das Interessante, nämlich das warum.
Stellenweise klingen die Antworten hier immer total gereizt.
-
Empty Base Optimization heißt das auch, ab und an auch Empty Base Class Optimization. Was die macht ist ja schon klar: eine leere Basisklasse erzeugt keinen Zusätzlichen Speicherverbrauch. Und das Warum: naja. Damit leere Basisklassen keinen zusätzlichen Speicher verbrauchen.
Hier gibts eine recht gute Erklärung.
-
Der C++ Standard erlaubt, dass obwohl immer 1 <= sizeof(eine_klasse) gilt, eine "leere Klasse" als Basisklasse keinen zusätzlichen Speicher verbraucht. Diese Optimierung ist auch nicht besonders anspruchsvoll, wird aber auch nicht garantiert. G++ 3.4.5. liefert mir bei folgendem Programm
#include <iostream> struct A {}; struct B : A { char c; }; int main() { std::cout << sizeof(A) << '\n'; std::cout << sizeof(B) << '\n'; }das Ergebnis
1 1Ein kleiner Eintrag dazu (ohne große Erklärungen) gibt's auch in Stroustrup's FAQ.
Gruß,
SP