Aufruf des Objektkonstruktors / Destruktors mit einem benutzerdefinierten Zuordner

8

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.

%Vor%

(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).

    
mmurphy 18.04.2012, 00:42
quelle

3 Antworten

10

Wenn Sie einen neuen Ausdruck wie T *t = new T; verwenden, entspricht das im Wesentlichen:

%Vor%

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:

%Vor%

Also, wenn Sie new und delete für eine bestimmte Klasse überladen:

%Vor%

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.

    
Jerry Coffin 18.04.2012, 02:47
quelle
7

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%     
bjhend 18.04.2012 00:53
quelle
0

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. >

    
stonemetal 18.04.2012 01:27
quelle