Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Tworzenie obiektu w funkcji i przeniesienie własności

Ostatnio zmodyfikowano 2013-12-26 09:40
Autor Wiadomość
b00rt00s
Temat założony przez niniejszego użytkownika
Tworzenie obiektu w funkcji i przeniesienie własności
» 2013-12-26 02:16:11
Mam taki problem. Mam klasę, której nie można kopiować i potrzebuję, aby funkcja (ew. metoda) tworzyła obiekt i zwracała go. Pomyślałem, że przy okazji tego mógłbym wreszcie zrozumieć referencje do r-wartości. Napisałem taki przykładowy kod:

C/C++
#include <iostream>


class A
{
public:
    A() = default;
    A( A & ) = delete;
    A( A && ) = delete;
   
    void print()
    {
        std::cout << "blabla" << std::endl;
    }
};

oraz dwie funkcje:

C/C++
A & make1()
{
    A a;
    return a;
}

A && make2()
{
    A a;
    return std::move( a );
}

a także main:

C/C++
int main( int argc, char * argv[] )
{
   
    A & pierwszy = make1();
    A && drugi = make2();
   
    pierwszy.print();
    drugi.print();
}

Na mój gust, to funkcja make1 powinna wywołać crash programu, bo zwraca referencję do obiektu lokalnego. Tak się jednak nie dzieje, kod się kompiluje i wykonuje poprawnie.

Zastanawiam się jednak nad funkcją make2. Czy ona jest poprawna? Czy tak mogę tworzyć i przekazywać obiekty? Proszę o pomoc i wyjaśnienie tej kwestii.
P-100135
Monika90
» 2013-12-26 09:40:29
Zwracanie z funkcji referencji do automatycznego obiektu, który za chwilę przestanie istnieć, to jest zawsze błąd, bez względu na to, czy to jest referencja do L-wartości czy do R-wartości. Zachowanie programu jest w takiej sytuacji niezdefiniowane. Nie wiadomo co się stanie, może on wypisać "blabla" albo cokolwiek innego.

Zwracaj przez wartość i używaj bezpośredniej inicjalizacji (to działa nawet dla klas co nie mają ani konstruktora kopiującego, ani przenoszącego, choć praktycznych zastosowań to chyba nie ma).
C/C++
A make() { return { }; }

int main( int argc, char * argv[] )
{
    A && pierwszy = make();
    A && drugi = make();
    pierwszy.print();
    drugi.print();
    make().print();
}
P-100139
« 1 »
  Strona 1 z 1