Was ist die vollständige Liste der Aktionen durch die Platzierung neuer in C ++ durchgeführt?

StackOverflow https://stackoverflow.com/questions/1031543

  •  06-07-2019
  •  | 
  •  

Frage

diese Frage eine Factory-Methode zu schaffen, wenn der Compiler nicht neue und Platzierung neue diskutiert wird. Offensichtlich einige geeignete Lösung gefertigt werden könnten malloc (), wenn alle notwendigen Schritte durch Platzierung getan neue in irgendeiner Weise reproduziert werden.

Was Platzierung ist neue zu tun - ich werde versuchen und zur Liste Hoffnung nichts zu verpassen - mit Ausnahme der folgenden

  • Anruf Konstrukteuren für alle Basisklassen rekursiv
  • Anruf Konstrukteuren und initializers (falls vorhanden) für alle Membervariablen
  • gesetzt VTable-Zeiger entsprechend an.

Was andere Aktionen gibt es?

War es hilfreich?

Lösung

Placement new tut alles, was eine regelmäßige new tun würde, außer Speicher zuweisen.

Ich glaube, Sie haben im Wesentlichen genagelt, was passiert, mit einigen kleineren Präzisierungen:

  • offensichtlich der Konstruktor der Klasse selbst aufgerufen wird, als auch
  • VTable-Zeiger werden als Teil Konstruktoraufrufe initialisiert, nicht getrennt. Eine Folge davon ist, dass ein teilweise konstruiertes Objekt (man denken Ausnahmen in Konstruktor geworfen) hat seine VTable die Konstruktion bis zu dem Punkt aufgebaut weitergegangen.

Die Reihenfolge der Konstruktion / Initialisierung ist wie folgt:

  1. virtuelle Basisklassen in der Reihenfolge der Deklaration
  2. nicht-virtuelle Basisklassen in der Reihenfolge der Deklaration
  3. die Teilnehmer in der Reihenfolge der Deklaration
  4. Klassenkonstruktors selbst

Andere Tipps

gesetzt VTable-Zeiger entsprechend

Dieser Teil ist fast vollständig die Implementierung definiert. Ihr Compiler möglicherweise nicht vtables verwenden. Es kann mehr VTable-Zeiger, oder ein oder mehrere Zeiger auf Dinge, die nicht vtables. Mehrfachvererbung ist immer unterhaltsam, als virtuelle Basisklassen sind. Diese Metadaten werden nicht mit memcpy auf ein anderes Objekt sein kopierbar garantiert, so dass der Zeiger (n) nicht absolut sein. Es könnte drin sein Offsets, die relativ zu dem Objekt sind Zeiger selbst.

IIRC allgemein, was passiert, ist, dass die Basisklasse Konstruktor aufgerufen wird, dann wird der VTable-Zeiger auf die Basisklasse gesetzt ist, dann wird die erste abgeleitete Klasse Konstruktor aufgerufen, etc. Dies ist, um die Anforderungen in der Spezifikation zu erfüllen, in Bezug auf was passiert, wenn eine virtuelle Funktion in einem Konstruktor aufgerufen wird. Soweit ich mich erinnere, gibt es keine „Liste der Aktionen“ in der Norm, nur eine definierte Initialisierung Ordnung.

So ist es nicht möglich ist, zu verallgemeinern, was eine Implementierung der Fall ist, vor allem da das, was Sie haben, ist nicht eine Implementierung der C ++ Standard. Wenn es Ecken schneidet durch Weglassen „neue“, vermutlich mit gutem Grund, weil es denkt, sollte man es nicht auf der Zielplattform verwenden, dann wer weiß, was andere Regeln der Sprache ignoriert. Wenn es möglich wäre, „neu“ mit einem malloc zu verspotten und ein bisschen Zeiger schieb, warum auf der Erde ist der Compiler nicht nur neue implementieren? Ich glaube, Sie müssen Fragen mit Ihrem spezifischen Compiler und Plattform getaggt stellen, so dass alle Experten auf Ihrem Compiler reagieren zu können.

@laalto Antwort im Allgemeinen gilt. Erweist sich jedoch als eine Ausnahme die Regel.

  

VTable-Zeiger werden als Teil Konstruktoraufrufe initialisiert, nicht getrennt.

Die Microsoft C ++ Compiler weiß sogenannte lokale vftables, das heißt vftables sind lokal für eine DLL und werden für jede importierte Klasse geklont werden. Dies liegt daran, dass der Compiler will eine modifizierte destructor schaffen, die das Original Wraps (sa hier ).

Jedes Mal, wenn Sie ein Objekt einer importierte Klasse konstruieren der Compiler Code erzeugt, die überschreiben die ursprünglichen vftable Zeiger (n) mit lokalen Zeigern (n) nach Konstruktor Aufruf. Dieser Code ist auch bei der Platzierung neuer Anrufe.

Es gibt eine andere Abhilfe neben den oben im Beitrag erwähnt. Diese Problemumgehung zwingt Sie nicht die Original-Header-Dateien zu ändern. Weitere Informationen finden sie hier: https://godbolt.org/g/YQsffY

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top