4 Stimmen

Speichern von rvalue-Referenzen: Sollte das funktionieren?

Ich teste mein Verständnis von lvalue- und rvalue-Referenzen, indem ich absichtlich versuche, Dinge zu brechen. Angenommen, es gibt diese Struktur:

struct FooBar
{
    FooBar(int&& number) : rNumber(number)
    {

    }

    int& rNumber;
};

und ich erstelle eine Instanz FooBar obj(5). Jeder Versuch, die Referenzvariable zu lesen, liefert das richtige Ergebnis (5). Das Gleiche passiert, wenn ich statt int&& const int& verwende.

Ich habe bemerkt, dass das Ersetzen von int durch std::string und das Lesen der Referenz eine leere Zeichenfolge zurückgibt, daher vermute ich, dass es zu einem undefinierten Verhalten führt. Ist das so? Und wenn ja, warum funktioniert es mit Ganzzahlen?

Update: Ich erstelle die Instanz und lese sie wie folgt:

FooBar obj(5);
//FooBar obj("Hallo"); // Für Zeichenfolgen...

std::cout << obj.rNumber << std::endl;

Update 2: Es funktioniert auch, wenn man einen benutzerdefinierten Typ übergibt, so:

struct GooBar
{
public:
    GooBar(int number) : itsNumber(number) 
    {
        std::cout << "Im Konstruktor..." << std::endl;
    }

    GooBar(const GooBar& rhs) = delete;
    GooBar(GooBar&& rhs) = delete;

    ~GooBar() 
    {
        std::cout << "Im Destruktor..." << std::endl;
    }

    int itsNumber;
};

struct FooBar
{
    FooBar(GooBar&& number) : rNumber(number)
    {

    }

    GooBar& rNumber;
};

und dann eine Instanz erstellen und sie so lesen:

FooBar obj(GooBar(5));

std::cout << obj.rNumber.itsNumber << std::endl;

Ich finde das interessant, weil es folgende Ausgabe liefert:

Im Konstruktor...
Im Destruktor...
5

2voto

Cheers and hth. - Alf Punkte 138555

Mit einem Ganzzahlliteral als tatsächlichem Argument kann der Compiler eventuell eine Referenz auf eine statisch zugewiesene Instanz übergeben.

Mit einem formalen Argument vom Typ std::string und einem Zeichenkettenliteral als tatsächlichem Argument wird die Instanz beim Aufruf erstellt und am Ende des Aufrufs zerstört.

In beiden Fällen handelt es sich um ein undefiniertes Verhalten.


Es ist jedoch nicht klar, wie Sie dies aufrufen: Sie haben vergessen, diese entscheidende Information mit einzubeziehen (zum Zeitpunkt des Schreibens dieser Nachricht).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X