Ich habe nach benutzerdefinierten Allokatoren gesucht und sehe sie oft mit einer Art Funktion, um Speicher zuzuordnen. Zu Testzwecken und zur Weiterbildung habe ich versucht, ein "einfaches" Beispiel dafür zu geben. Es gibt jedoch eine grundlegende Sache, die ich verstehe, wie man es macht. Einer der Hauptunterschiede in malloc
vs new
ist, dass mit new der Konstruktor aufgerufen wird. Was wäre, wenn ich meinen eigenen Allokator schreiben möchte, der im Wesentlichen new
ersetzt, wie würde ich den Konstruktor dazu bringen, bei Verwendung von malloc
aufgerufen zu werden?
Ich verstehe, dass ich bei Klassen die new
und delete
für die Klasse überladen kann, also nehme ich an, ein großer Teil der Frage lautet: Wie ruft new
den Objektkonstruktor während der Zuweisung auf? Ebenso interessiert mich, wie delete
den Destruktor aufruft.
Ich habe einen Beispieltestcode erstellt, von dem ich hoffte, dass der SomeClass
-Konstruktor während der Zuweisung aufgerufen wird, aber ich sehe nicht, wie.
(Als eine Anmerkung, ich weiß, ich kann nur new
verwenden. Zum Zweck des Lernens versuche ich jedoch, einen benutzerdefinierten Zuordner zu erstellen, der nicht nur new
oder placement new
aufruft).
Wenn Sie einen neuen Ausdruck wie T *t = new T;
verwenden, entspricht das im Wesentlichen:
Also wird zuerst etwas roher Speicher mit der Zuweisungsfunktion zugewiesen, dann wird ein Objekt in diesem Speicher erstellt. Wenn Sie einen Löschausdruck wie: delete t;
verwenden, entspricht das in etwa der folgenden Formel:
Also, wenn Sie new
und delete
für eine bestimmte Klasse überladen:
Wenn Sie dann einen neuen Ausdruck verwenden, ruft er die Klasse operator new
auf, um den Speicher zuzuweisen, und ruft malloc
auf, so dass T *t = new T();
letztendlich Speicher über malloc
zuweist (und ebenso Wenn Sie delete
it verwenden, wird operator delete
verwendet, was free
) aufruft.
Mindestens wie der Begriff normalerweise verwendet wird, ist ein Allocator ziemlich ähnlich, außer dass er von einem Container anstelle von anderem Code verwendet wird. Es kapselt auch die Zuweisungsfunktion und die Löschfunktion in eine Klasse ein. Wenn Sie also eine an den Container übergeben, müssen Sie nur ein Objekt übergeben, und es besteht kaum eine Chance, dass eine Zuweisungs- und Löschfunktion nicht übereinstimmt.
Wenn ich im Moment die Details darüber ignoriere, welche Namen für Dinge verwendet werden, macht die Allocator-Klasse in der Standardbibliothek meistens dasselbe, also mit ein wenig Umbenennung der Funktionen in T
Klasse darüber, Sie wären ungefähr die Hälfte fertig mit dem Schreiben eines Standard-Allokators. Um mit der Zuweisung und dem Löschen zu gehen, hat es eine Funktion% code% etwas Speicher (einen Speicherblock zu einem anderen Typ zu ändern), ein Objekt an Ort und Stelle (im Grunde nur ein Wrapper um ein neues Placement) und ein Objekt zu zerstören , trivialer Wrapper um den Destruktoraufruf). Natürlich verwendet es rebind
und operator new
anstelle von operator delete
und malloc
wie ich oben verwendet habe.
Mit einer neuen Platzierung können Sie einen bereits zugewiesenen Speicherplatz an den neuen Betreiber übergeben. Dann wird neu das Objekt an dem gegebenen Ort konstruieren, ohne eine Zuweisung an sich selbst vorzunehmen.
Bearbeiten:
So könnte es implementiert werden:
%Vor%Damit der Konstruktor aufgerufen wird, verwenden Sie das Placement new (Beachten Sie, dass Sie das Placement new nicht überschreiben können). Zum Löschen und alle Probleme gut die FAQ erklärt es gut. >
Tags und Links memory c++ new-operator memory-management