Heim >Backend-Entwicklung >C++ >Ist es legal, ein C-Objekt an seinen eigenen Konstruktor zu übergeben?

Ist es legal, ein C-Objekt an seinen eigenen Konstruktor zu übergeben?

Patricia Arquette
Patricia ArquetteOriginal
2024-11-13 10:13:02758Durchsuche

Is it legal to pass a C   object into its own constructor?

Ist es legal, ein C-Objekt an seinen eigenen Konstruktor zu übergeben?

Es ist verwirrend, dass Code wie dieser zu funktionieren scheint:

#include <iostream>

struct Foo {
    Foo(Foo& bar) {
        std::cout << &bar << std::endl;
    }
};

int main(int argc, char** argv) {
    Foo foo(foo); // I can't believe this works...
    std::cout << &foo << std::endl; // but it does...
    return 0;
}

Indem wir die Adresse eines nicht initialisierten Objekts an seinen eigenen Konstruktor übergeben, scheinen wir eine zirkuläre Definition zu erstellen. Es stellt sich die Frage: Erlauben die Standards die Übergabe eines Objekts an eine Funktion vor seiner Konstruktion? Oder stellt dies ein undefiniertes Verhalten dar?

Legal, aber nicht ungewöhnlich

Die Übergabe der Adresse eines nicht initialisierten Objekts an seinen eigenen Konstruktor ist kein undefiniertes Verhalten. Obwohl foo nicht initialisiert ist, verwenden wir es auf eine vom Standard genehmigte Weise.

Die Objektspeicherzuweisung erfolgt vor der vollständigen Initialisierung. Folglich ist das Binden eines Verweises auf eine solche Variable und das Abrufen ihrer Adresse während dieses Intervalls zulässig.

Dieses Verhalten steht im Einklang mit Fehlerbericht 363, der klarstellt, dass in einer solchen Situation erstellte Verweise als gültig gelten. Abschnitt 3.8 [basic.life] des C 14-Standards legt außerdem fest, dass die Verwendung von GL-Werten, die zugewiesene, aber nicht initialisierte Objekte referenzieren, in bestimmten Grenzen zulässig ist.

Wir können nämlich keine L-Wert-in-R-Wert-Konvertierungen anwenden und nicht statisch zugreifen Datenmember oder rufen nicht statische Memberfunktionen auf, binden an Referenzen virtueller Basisklassen oder verwenden Dynamic_cast oder Typeid.

In unserem Beispielsweise vermeiden wir diese verbotenen Aktionen, indem wir eine Referenz binden und die Adresse abrufen.

Compiler-Warnungen

Trotz der Legitimität des Verhaltens gibt Clang eine Warnung aus:

warning: variable 'foo' is uninitialized when used within its own initialization [-Wuninitialized]

Diese Warnung ist berechtigt, da die Generierung eines unbestimmten Werts aus einer nicht initialisierten automatischen Variablen ein undefiniertes Verhalten darstellt. Nichtsdestotrotz liefert unsere Verwendung keinen unbestimmten Wert und ist daher legal.

Weitere Überlegungen

Während Selbstinitialisierung durch Übergabe eines Objekts an seinen eigenen Konstruktor nicht inhärent ist Ob nützlich oder ratsam, es kann eine interessante Methode zur Untersuchung des Klassenverhaltens sein. Allerdings stellt die Selbstinitialisierung durch Zuweisung, wie in int x = x;, undefiniertes Verhalten dar.

Das obige ist der detaillierte Inhalt vonIst es legal, ein C-Objekt an seinen eigenen Konstruktor zu übergeben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn