Bitte erstellen Sie eine Liste der Aufgaben, die ein Kopierkonstruktor und ein Zuweisungsoperator in C++ erfüllen müssen, um Ausnahmesicherheit zu gewährleisten, Speicherlecks zu vermeiden usw.
Ich dachte, man nennt es die 4er-Regel.
Bitte erstellen Sie eine Liste der Aufgaben, die ein Kopierkonstruktor und ein Zuweisungsoperator in C++ erfüllen müssen, um Ausnahmesicherheit zu gewährleisten, Speicherlecks zu vermeiden usw.
Vergewissern Sie sich zunächst, dass Sie die Kopie wirklich benötigen. In den meisten Fällen ist dies nicht der Fall, und daher ist die Deaktivierung beider Optionen der richtige Weg.
In diesem Fall sollten Sie den Zuweisungsoperator deaktivieren, einen (geschützten?) Kopierkonstruktor schreiben und eine virtuelle clone()-Funktion zur Verfügung stellen.
Andernfalls, wenn Sie eine Wertklasse schreiben, sind Sie zurück im Land der orthogonalen kanonischen Form von Coplien. Wenn Sie ein Mitglied haben, das nicht trivial kopiert werden kann, müssen Sie einen Kopier-Konstruktor, einen Destruktor, einen Zuweisungsoperator und einen Standard-Konstruktor bereitstellen. Diese Regel kann verfeinert werden, siehe zum Beispiel: Das Gesetz der großen Zwei
Ich würde auch empfehlen, einen Blick auf C++ FAQ zu Zuweisungsoperatoren und bei der Redewendung zum Kopieren und Austauschen und bei GOTW .
AFAIK stammt es aus dem Buch von Jim Coplien, daher der Name - es gilt übrigens nur für Wertklassen. Manche nennen sie auch die Vierer-Regel. Es gibt (gab?) auch Erklärungen zu /Rule of Big Three/ in C++ FAQ lite (ich kann sie nicht mehr finden). Und sie kann dank RAII auf zwei reduziert werden.
Die vom Compiler erzeugten Versionen funktionieren in den meisten Situationen.
Sie müssen ein bisschen mehr über das Problem nachdenken, wenn Ihr Objekt einen RAW-Zeiger enthält (ein Argument dafür, keine RAW-Zeiger zu haben). Sie haben also einen RAW-Zeiger, die zweite Frage ist, ob Sie Eigentümer des Zeigers sind (wird er von Ihnen gelöscht)? Wenn ja, dann müssen Sie die 4er-Regel anwenden.
Der Besitz von mehr als 1 RAW-Zeiger wird immer schwieriger, richtig zu tun (Die Zunahme der Komplexität ist auch nicht linear [aber das ist eine Beobachtung und ich habe keine wirklichen Statistiken, um diese Aussage zu unterstützen]). Wenn Sie also mehr als 1 RAW-Zeiger haben, denken Sie darüber nach, jeden in seine eigene Klasse zu verpacken (eine Form von Smart Pointer).
4er-Regel: Wenn ein Objekt der Eigentümer eines RAW-Zeigers ist, müssen Sie die folgenden 4 Mitglieder definieren, um sicherzustellen, dass Sie die Speicherverwaltung korrekt handhaben:
Wie Sie diese definieren, hängt von der jeweiligen Situation ab. Aber es gibt Dinge, auf die man achten sollte:
"Die vom Compiler erzeugten Versionen funktionieren in den meisten Situationen." - je nachdem, welche Art von Programmierung Sie betreiben. Selbst wenn alles intelligente Zeiger sind, die sich mit Ressourcenverfolgung und Ausnahmeproblemen befassen, ist eine oberflächliche Kopie möglicherweise nicht das, was Sie semantisch wollen.
Versuchen Sie, dies zu lesen.
http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
ist eine sehr gute Analyse von Assignment operator
Das ist eine typische Frage, die ich in einem Vorstellungsgespräch stellen würde. Ich sehe jedoch eine falsche Annahme: dass die meisten Objekte kopierbar sein müssen. "Jedes Objekt in einem gut konzipierten C++-System hat einen Standardkonstruktor, einen Kopierkonstruktor und einen Zuweisungsoperator." Dieser Satz bezieht sich auf wertbasierte Objekte, nicht auf Entitäten.
Ich habe keine Ahnung, ob hier Ausnahmen sicher sind, aber ich gehe diesen Weg. Stellen wir uns vor, es ist eine Vorlage Array Wrapper. Hoffe, es hilft :)
Array(const Array& rhs)
{
mData = NULL;
mSize = rhs.size();
*this = rhs;
}
Array& operator=(const Array& rhs)
{
if(this == &rhs)
{
return *this;
}
int len = rhs.size();
delete[] mData;
mData = new T[len];
for(int i = 0; i < len; ++i)
{
mData[i] = rhs[i];
}
mSize = len;
return *this;
}
Nein, ist es nicht. Ich hatte keine Probleme mit Ausnahmen sicheren Code, so dass ich nie eine Chance, es zu üben hatte. Diese oben ist ofc nur Snipper, normalerweise verwenden Sie STL-Container. Bitte posten Sie Ihr Snippet, ich würde gerne einen Blick auf sie zu nehmen.
In den Links, die ich in meiner Antwort angegeben habe, finden sich zahlreiche Auszüge. BTW, der Test, der die Selbstzuweisung verhindert, wird jetzt als Anti-Idiom betrachtet (jetzt, da Ausnahmen besser verstanden werden)
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.