2015-09-25 5 views
-1

Я хочу использовать удобные функции при создании экземпляров класса в моей функции main(), чтобы сделать вещи более понятными.Справочные и установочные функции rvalue

Вот минимальный пример:

class MyClass 
{ 
    public: 
      MyClass() : value{ -1 }, str{ "hello" } {} 
      MyClass(const MyClass &&other) 
      { 
        value = move(other.value); 
        str = move(other.str); 
        file = move(other.file); //Use of deleted function... 
      } 

      void open() 
      { 
        file.open("myfile"); 
      } 

    private: 
      MyClass(const MyClass &) = delete; 
      MyClass operator=(const MyClass &) = delete; 
      MyClass &operator=(const MyClass &&) = delete; 

      ofstream file; 
      int value; 
      string str; 
}; 

inline MyClass setup_myclass() 
{ 
    MyClass ret; 
    ret.open(); 

    return ret; 
} 

int main(int argc, char **argv) 
{ 
    MyClass &&mc = setup_myclass(); 

    return 0; 
} 

Проблема заключается в том, когда мой класс содержит такие вещи, как fstream или нить, которая имеет свой ход конструкторов удалены.

Я компилирую с g ++ 5.1.1 и arm-linux-g ++ 5.2.0 (raspberrypi, buildroot).

Что должен выглядеть мой конструктор перемещения, когда у меня есть члены с удаленными конструкторами перемещения?

Как я могу изменить свой код на ту же самую чистую основную функцию?

+0

'std :: ofstream' имеет конструктор перемещения. [это конструктор копирования, который удален) (http://en.cppreference.com/w/cpp/io/basic_ofstream/basic_ofstream) – NathanOliver

+1

Неправильно по содержанию. Оба std :: ofstream и std :: thread имеют конструкторы перемещения. Почему вы думаете, что у вас есть проблема? Предоставьте сообщение компилятора. – SergeyA

+0

изменить 'MyClass (const MyClass && other)' в 'MyClass (MyClass && other)' –

ответ

4

Здесь есть две проблемы. Во-первых, ваш ход конструктор имеет неправильную подпись:

MyClass(const MyClass &&other) 

Вы не можете двигаться, из const RValue. Вы имели в виду:

MyClass(MyClass &&other) 

и более того, вы на самом деле имел в виду:

MyClass(MyClass &&other) = default; 

См Rule of Zero. Все ваши участники имеют конструкторы перемещения (std::thread и std::ofstream тоже!), Поэтому просто используйте их. Кроме того, это:

MyClass &operator=(const MyClass &&) = delete; 

должны быть public и выглядеть следующим образом:

MyClass &operator=(MyClass &&) = default; 

Почему включить конструктор перемещения, но delete задание двигаться?

Во-вторых, это плохо:

MyClass &&mc = setup_myclass(); 

вы просто взяли ссылку на временный, который разрушается в конце линии. Теперь у вас свисающая ссылка. То, что вы хотите сделать, это просто:

MyClass mc = setup_myclass(); 

Благодаря РВО, не будет на самом деле движение вызывается здесь. Временной в пределах setup_myclass() фактически будет построен на месте в mc.

+1

* "вы просто взяли ссылку на временное, которое будет уничтожено в конце строки." *, Не привязывает временное непосредственно к ссылка rvalue продлевает время жизни этого временного? –

+1

@PiotrSkotnicki Nope. «Время жизни временной привязки к возвращаемому значению в операторе return функции (6.6.3) не является расширенным, временное уничтожается в конце полного выражения в операторе return.« – Barry

+1

Это неприятное и удивительное (но не совсем) исключение для ссылочного расширения. Я забыл его. –

Смежные вопросы