Werden leere Konstruktoren immer in C ++ aufgerufen?

7

Ich habe eine allgemeine Frage, die vielleicht etwas compilerspezifisch ist. Ich interessiere mich für die Bedingungen, unter denen ein Konstruktor aufgerufen wird. Insbesondere wird im Freigabemodus / für die Geschwindigkeit optimierten Builds immer ein vom Compiler generierter oder leerer Konstruktor aufgerufen, wenn Sie ein Objekt instanziieren?

%Vor%

Ich habe viel gesucht und einige Zeit damit verbracht, den generierten Assembler-Code in Visual Studio durchzusehen. Es kann jedoch schwierig sein, in Release-Builds zu folgen.

Zusammenfassend: Wird der Konstruktor immer aufgerufen? Wenn ja, warum?

Ich verstehe, dass dies sehr vom Compiler abhängen wird, aber sicherlich gibt es eine gemeinsame Haltung. Alle Beispiele / Quellen, die Sie zitieren können, wären sehr geschätzt.

    
JBeFat 23.02.2011, 21:43
quelle

5 Antworten

5

Wenn Ihre Klasse oder Struktur im Optimierungsmodus POD ist (nur POD-Typen hat) und kein Konstruktor angegeben ist, überspringt jeder C ++ - Compiler in Produktionsqualität nicht nur den Aufruf an einen Konstruktor, sondern generiert ihn sogar.

>

Wenn Ihre Klasse Nicht-POD-Mitglieder hat, deren Konstruktoren aufgerufen werden müssen, generiert der Compiler einen Standardkonstruktor, der die Konstruktoren des Mitglieds aufruft. Aber selbst dann - es wird keine POD-Typen initialisieren. I.e. Wenn Sie member nicht explizit initialisieren, können Sie dort mit Müll enden.

Die ganze Sache kann sogar Fantasien bekommen, wenn Ihr Compiler / Linker LTO hat.

Hoffe es hilft! Und machen Sie Ihr Programm zuerst, dann verwenden Sie einen Profiler, um langsame Orte zu erkennen und optimieren Sie sie dann. Vorzeitige Optimierung kann nicht nur Ihren Code unlesbar machen und Ihre Zeit verschwenden, sondern könnte auch nicht helfen. Sie müssen zuerst wissen, was Sie optimieren müssen.

Hier ist eine Disassemblierung für Code in Ihrem Beispiel (x86_64, gcc 4.4.5):

%Vor%

Wie Sie sehen, werden überhaupt keine Konstruktoren aufgerufen. Es gibt überhaupt keine Klassen, jedes Objekt ist nur eine 4-Byte-Ganzzahl.

Mit MS-Compiler, YMMV. Sie müssen also die Demontage selbst überprüfen. Aber das Ergebnis sollte ähnlich sein.

Viel Glück!

    
user405725 23.02.2011, 21:58
quelle
15
  

Wird ein Compiler generierter Konstruktor / leerer Konstruktor immer aufgerufen, wenn Sie ein Objekt instanziieren?

Nein. Wenn Ihre Klasse ein sogenannter "POD" (einfache alte Daten) ist, wird der vom Compiler erzeugte Konstruktor nicht aufgerufen.

Insbesondere wird es in den beiden folgenden Fällen nicht aufgerufen:

%Vor%

Die Bedingungen dafür, wann genau ein Typ ein POD ist, sind ein bisschen schwierig. Die C ++ - FAQ hat eine schöne Aufschlüsselung .

    
Konrad Rudolph 23.02.2011 21:50
quelle
10

Logischerweise wird der Konstruktor aufgerufen. Wenn der Konstruktor im generierten Code nichts tut, gibt es keine Anweisungen, die auf den Konstruktor zurückverfolgt werden können, es sei denn, Ihr Compiler ist sehr schlecht im Optimieren und fügt einen Aufruf an etwas ein, das gerade zurückkehrt.

    
Erik 23.02.2011 21:49
quelle
1

Bestimmte Klassen- oder Strukturtypen werden in C ++ POD "Plain Old Data" genannt. Diese Typen werden nicht Konstruktoren aufgerufen.

Die Regeln für ein POD sind wichtig genug, dass Sie sie nachschlagen sollten, aber zusammenfassend: enthält nur primitive Datentypen und hat keine definierten Konstruktoren.

    
Zan Lynx 23.02.2011 21:50
quelle
0

Ihr Beispiel ist nicht sehr gut, Sie haben das Schlüsselwort public in Beispielklassen verpasst und außerdem in Ihren Beispielen die Nullinitialisierung erzwungen, indem Sie CLASS * class = new CLASS(); anstelle von CLASS * class = new CLASS; schreiben.

Im Code, wie Sie es nennen - Null-Initialisierung wird immer so durchgeführt, wie es der Standard verlangt. Sie können es wie Sie wollen nennen - aber es wird Code geben, um die Regeln des Standards zu garantieren.

Wenn Sie gefragt hätten, ohne diesen umstrittenen Beispielcode zu zeigen - dann wäre die einzige korrekte Antwort - compiler specific .

    
Andrey 23.02.2011 22:10
quelle