2016-08-18 3 views
0

У меня возникли проблемы с пониманием семантики перемещения C++. Предположим, я хочу вернуть большой объект из метода. Чтобы сделать эту операцию эффективной, я использую конструктор перемещения для класса больших объектов. Я вызываю метод для получения большого объекта и передаю его другому методу, который будет обрабатывать его.Как работает конструктор перемещения?

processLargeObject(getLargeObject()); 

Я пишу метод getLargeObject() где я создаю большой объект. Если я создам объект без нового оператора, мне дается понять, что хранилище выделено в стеке. В случае, когда я знаю размер объекта заранее и представляю его в массиве, этот большой объект может быть определен как double foo[1000000000];. Теперь внутри конструктора двигаться, если я скажу,

foo = other.foo; 

затем перемещенный объект будет по-прежнему находиться в стеке и может быть переписан в стеке расширяется.

Так что это не должно быть так, как используется конструктор перемещения. Должен ли конструктор перемещения использоваться только для перемещения объектов, находящихся в куче?

+0

'foo = other.foo;' не будет компилироваться, если 'foo' - это массив удвоений. И как точно вы могли бы перемещать простой массив двойников? – Praetorian

+0

Означает ли это, что мне нужно пройти через массив и создать копию? – AggieMan

+0

Пробовали ли вы объявить и использовать объект с миллиардом удвоений в простом массиве? Кажется, хороший способ переполнить ваш стек.Вы должны использовать 'vector ', и тогда перемещение действительно имеет смысл. – Praetorian

ответ

2

Как работает конструктор перемещения?

Конструктор шаг должен сделать неглубокую копию - в отличие от глубокого копирования, что конструктор копирования должен делать. Помимо выполнения мелкой копии, конструктор перемещения «крадет» любые ресурсы (например, буфер внешней памяти, например буфер, принадлежащий std::vector), на который указывает перемещенный объект.

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

Педантично, крупность самого объекта не делает движение более эффективным, чем копия. Переход эффективен, когда объект указывает на некоторый большой ресурс, который можно «украсть». Если вы имели в виду, что такой внешний ресурс делает объект «большим», то справедливым.

Должен ли конструктор перемещения использоваться только для перемещения объектов, находящихся на куче?

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

этот большой объект может быть определен как double foo[1000000000];

Это хороший пример очень большого объекта, который не указывает на какой-либо внешний ресурс, который может быть украден. Перемещение массива двойников - это то же самое, что и копирование.

+0

Спасибо. Я получил эту часть. То, чего я не понимаю, не перемещается ли объект в кучу? – AggieMan

+0

@AggieMan см. Редактирование. – user2079303

+0

Для того чтобы конструктор перемещения мог принести существенную пользу, большая часть данных должна храниться в данных о куче, на которую ссылаются указатели в объекте. (Итак, 'std :: array ' обычно так же дорого переносится, как и для copy-construct, но 'std :: vector ' с 1000000 элементами очень быстро перемещается.) –

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