2015-05-20 28 views
10

Angenommen, ich möchte eine externe Funktion meines Objekts aufrufen, um einige Überprüfungen innerhalb des Body-Konstruktors durchzuführen. Da die Lebensdauer eines Objekts beginnt, wenn der Körper des Konstruktors seine Ausführung beendet, handelt es sich um ein unsicheres Design?C++: Lebensdauer eines Objekts und externe Funktionen

Ich meine, ich rufe und externe Funktion mit einem noch nicht lebenden Objekt. Ist es undefiniertes Verhalten?

Verwandte Fragen: Wenn ich diese überprüfende Funktion als eine Elementfunktion (statisch oder nicht) setze, was sagt der Standard über die Verwendung von nicht-noch-lebenden Objekten außerhalb des Konstruktors, aber innerhalb der Klasse?

Gibt es einen Unterschied in der Lebensdauer Konzept zwischen dem Standpunkt einer Klasse und ihren Benutzern (eine Art von in-class gegenüber Lebenszeiten außerhalb der Klasse)?

+2

Die [C++ FAQ] (https://isocpp.org/wiki/faq/ctors#using-this-in-ctors) hat Informationen darüber. –

+0

Es sollte in Ordnung sein, solange die Funktion kein Member virtual ist und nicht in der Initialisierungsliste ist. – KABoissonneault

+1

A const & ist eine Referenz und wird weder am Anfang der Prüfung initialisiert noch am Ende der Funktionen zerstört. Neben dem Konstruktor ist das Objekt vollständig konstruiert. Ich sehe kein Problem in diesem Code – Brahim

Antwort

8

Die Lebensdauer von A wird nicht begonnen, als check() da genannt wird, von [base.life]:

Die Lebensdauer eines Objekts vom Typ T beginnt, wenn:

  • Speicher mit die richtige Ausrichtung und Größe für den Typ T wird erhalten und
  • Wenn das Objekt eine nicht-leere Initialisierung hat, ist die Initialisierung abgeschlossen.

A hat nicht vacuous Initialisierung. Seine Initialisierung ist abgeschlossen, wenn von [class.base.init]/13:

In einem nicht delegieren Konstruktor Initialisierung erfolgt in folgenden Reihenfolge:

  • ...
  • - Schließlich wird die Compound-Anweisung des Konstruktor-Körpers ausgeführt.

Doch trotz A nicht seiner Lebenszeit nicht begonnen hat, der Standard bietet zusätzlich in [class.base.init]/16:

Member-Funktionen (einschließlich virtuellen Elementfunktionen, 10.3) kann für ein Objekt im Bau aufgerufen werden ... Wenn diese Operationen jedoch in einem ctor-Initialisierer ausgeführt werden (oder in einer Funktion, die direkt oder indirekt von einem ctor-Initialisierer aufgerufen wird), bevor alle Memorys initiieren Alizers für Basisklassen abgeschlossen sind, ist das Ergebnis der Operation nicht definiert.

Im Hinblick auf die Lebensdauer Fragen, gibt es keinen Unterschied zwischen:

void check(const A&) { .. } 
struct A { 
    A() { check(*this); } 
}; 

Und:

struct A { 
    void check() const { .. } 
    A() { check(); } 
}; 

Letzteres ist für ausdrücklich erlaubt (wie ist es in einem nicht Ctor-Initialisierer), so sehe ich keinen Grund, das erstere auf Lebenszeit auszuschließen.

+0

... außer wenn A eine Basisklasse mit virtuellen Membern ist, die von 'check()' aufgerufen werden - dann können die Ergebnisse Sie überraschen. –

+0

@RichardHodges Es ist jedoch kein undefiniertes Verhalten. – Barry

+0

@Barry Sind Sie sicher, dass die Initialisierung dort endet? http://StackOverflow.com/a/20409911/1794803 –