2015-12-02 5 views
1

Я немного смущен, почему вы должны использовать/нужен конструктор перемещения.
Если у меня есть следующие:Зачем использовать конструктор перемещения?

vector fill(istream& is) 
{ 
    vector res; 
    for(double x; is >> x; res.push_back(x)); 
    return res; 
} 

void bar() 
{ 
    vector vec = fill(cin); 
    // ... use vec ... 
} 

можно удалить необходимость возврата Рез, следовательно, не вызывая конструктор копирования, добавив vector fill(istream& is, vector& res).

Так в чем же смысл иметь конструктор перемещения?

+0

Как вы думаете, никогда не нужно копировать объекты на C++? Если это так, вы делаете это неправильно. – juanchopanza

+2

Одна из причин заключается в том, что читать гораздо проще. Если есть вызов функции 'somefunction (var1, var2, var3)', неясно, модифицируются некоторые из них или нет. –

+0

Вы пытались сделать некоторые чтения по темам движущихся конструкторов и перенести семантику вообще? Существует множество информации, просто Google ... –

ответ

4

Предположим, вы в следующий раз поставить вас std::vector<T> в std::vector<std::vector<T>> (если вы думаете, векторы не должны быть вложенными, предположим, что внутренний тип будет std::string и предположим, что мы обсуждаем std::string «s двигаться конструктор): даже если вы можете добавить пустой объект и заполнить его на месте, в конце концов, вектор нужно будет перемещать при изменении размера, в результате чего перемещение элементов будет полезно.

Обратите внимание, что возврат от функции не является основным мотиватором конструкции перемещения, по крайней мере, не в отношении эффективности: когда эффективность имеет значение для структурирования кода, чтобы обеспечить возможность копирования, дальнейшее улучшение производительности, даже избегая перемещения.

Конструктор перемещения может по-прежнему быть релевантным семантически, потому что для возврата требуется, чтобы тип был либо скопирован, либо подвижным. Некоторые типы, например, потоки, не могут быть скопированы, но они могут быть перемещены и могут быть возвращены таким образом.

2

В вашем примере компилятор может применить RVO - Оптимизацию возвращаемого значения, это означает, что функция будет встраиваться, поэтому возврат не произойдет - и семантика семантики не будет применена. Только если он не может применить RVO - будет использоваться конструктор перемещения (если он доступен).

Перед тем как перейти к семантике были введены люди использовали различные техники для имитации их. Один из них фактически возвращает значения по ссылкам.

2

Одна из причин заключается в том, что использование операторов присваивания облегчает понимание того, что делает каждая строка. Если есть вызов функции somefunction(var1, var2, var3), неясно, модифицируются ли некоторые из них или нет. Чтобы узнать это, вы должны фактически прочитать другую функцию.

Кроме того, если вам нужно передать вектор в качестве аргумента в fill(), это означает, что для каждого места, которое вызывает вашу функцию, потребуются две строки вместо одной: сначала создать пустой вектор, а затем позвонить fill().

Другая причина в том, что конструктор перемещения позволяет функции возвращать экземпляр класса, у которого нет конструктора по умолчанию. Рассмотрим следующий пример:

struct something{ 
    something(int i) : value(i) {} 
    something(const something& a) : value(a.value) {} 

    int value; 
}; 

something function1(){ 
    return something(1); 
} 

void function2(something& other){ 
    other.value = 2; 
} 

int main(void){ 
    // valid usage 
    something var1(18); 
    // (do something with var1 and then re-use the variable) 
    var1 = function1(); 

    // compile error 
    something var2; 
    function2(var2); 
} 

В случае, если вы обеспокоены тем, практичность, это не имеет значения ли вы написать fill() возвращать значение, или взять выходной переменной в качестве параметра. Ваш компилятор должен оптимизировать его до наиболее эффективной альтернативы этих двух. Если вы подозреваете, что это не так, вам лучше измерить это.

+0

Вы не можете «вернуть класс». –

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