![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
итак. что же такое r-value refs & move-semantics?
что мне известно об этом?: первое(и вроде как единственное) - позволяет получать ссылки на временные объекты.
такой еще пример:
http://en.cppreference.com/w/cpp/utility/move не может быть чтоб на этом польза от r-value refs & move-semantics закончилась. поделитесь опытом, мыслями. спасибо. |
||||
|
|||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
boostcoder
Это перемещение объекта, объект может быть не копируемым, но перемещаемым. В некоторых случаях копирование объекта невозможно реализовать, зато запросто можно реализовать перемещение. Например класс std::unique_ptr не поддерживает копирование. Он не считает количество ссылок, т.е. его копирование просто невозможно (или он должен работать как auto_ptr), зато реализовано перемещение этого объекта, что позволяет хранить std::unique_ptr в контейнерах. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
azesmcar, но у перемещаемого объекта все равно вызывается деструктор? и если да, то что он разрушает, если данные были перемещены?
|
|||
|
||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Например:
http://liveworkspace.org/code/4baf51d7d55a...835aad73d11a085 Объект перемещается, т.е. все данные переместились в другой объект, в данном случае деструктор сделает delete 0 и успокоится. Что делает деструктор и конструктор перемещения решает программист. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
что-то не понял... вот к примеру:
т.е. async_call() возвращает управление тут же. но если функциональный объект так же, тут же будет разрушен, то когда придет время его вызвать получим ошибку сегментации. или как? Добавлено через 1 минуту и 53 секунды ага. т.е. реализация деструктора должна предполагать подобное поведение? |
|||
|
||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
Функциональный разрушен не будет, функциональный объект был перемещен и будет разрушен после выхода из области видимости. Добавлено через 1 минуту и 57 секунд
точнее реализациа конструктора перемещения ![]() деструктор в моем примере ведет себя как обычно. |
|||
|
||||
rumit7 |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 71 Регистрация: 16.6.2011 Репутация: 6 Всего: 7 |
Извините что вмешиваюсь, вот по этой ссылке идет вроде не плохое и достаточно подробное объяснение r-value refs & move-semantics. Ну и к одному из приведенному примеру дается такое объяснение: " Instead of dynamically allocating memory, the move constructor and move assignment operator simply steal it from other . When stealing, we copy other's pointer and then null it out. When other is destroyed, its destructor will do nothing.". Там есть примеры показывающие различное поведение r-value refs, а также обсуждается как работает std::move() для различных аргументов:
Это сообщение отредактировал(а) rumit7 - 9.11.2011, 10:22 |
||||
|
|||||
boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
все равно не понимаю... к примеру, r-value refs у нас нет. тогда мой пример записывался бы так:
т.е. тут создавался бы временный объект, внутри функции async_call() инициализировался бы другой объект, и временный объект бы разрушался. тут все понятно. а вот с r-value что-то не понимаю смысла, если временный объект все равно создается и разрушается.. Добавлено через 1 минуту и 42 секунды rumit7, спасибо. сейчас прочту. |
||||
|
|||||
azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
разрушается не объект а "пустышка", а душа обьекта переселилась в другое тело и живет там в лучших традициях реинкарнации. Это сообщение отредактировал(а) azesmcar - 9.11.2011, 10:21 |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
||||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
azesmcar, все, понял. спасибо.
зы с двухсотым плюсиком тебя. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
хочу обратить внимание, что временный объект не всегда рвалуе и поэтому эти понятия не стоит смешивать..
польза например наблюдается при возвращении массива из функции.. если передачу в функцию еще как то могли смягчить за счет пристыковывания к константной ссылке, то с возвращением временого содержимого руки были связаны.. |
|||
|
||||
baldina |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
оно собственно и задумывалось как средство оптимизации временных объектов, и от этого польза немалая, т.к. для обеспечения производительности раньше в некоторых случаях требовался специальный, менее красивый и простой дизайн. ![]()
boostcoder видимо имеет в виду это: http://liveworkspace.org/code/1a70c160da7c...2dbaf2a272a94a2 хотя имхо польза от этого довольно сомнительная... |
||||
|
|||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
тоже вариант. |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Экспериментировал как-то с move-semantics:
http://liveworkspace.org/code/ad3e28d4a554...cdfe13a7b58d551 Почему-то у меня упорно не хочет вызыватся move-ctor Str( Str && other ); Что я не так делаю... И ещё. Там создаётся 4 объекта (x, y, x и result внутри operator+), а вызывается 3 деструктора. Как это ? И где вызвался конструктор z ? -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
компилятор позволяет себе не переносить из временого в целевой, а сразу использовать целевой объект для результата.. если нужно задействовать именно move -семантику в вашем случае, укажите это с помощью move(); Добавлено через 1 минуту и 20 секунд это по старым правилам ![]() |
|||
|
||||
baldina |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
там всего три объекта, погляди на адреса. result и z одно и то же. что бы он вызвался, укажи семантику явно
Добавлено через 4 минуты и 18 секунд это NRVO отработало. велик могучий языка... Добавлено через 6 минут и 1 секунду оказывается уже ответили(( |
||||
|
|||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
mes, baldina, спасибо за ответы, но
1) я хочу, чтобы move-конструктор вызывался автоматически, поэтому не хочу использовать std::move() 2) boostcoder говорит, что на LWS оптимизация выключена, а вы говорите, что
или это не имеет отношения к оптимизации ? тогда вопрос снят -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
mes |
|
||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
не имеет, это не оптимизация, а перенос при инициализации.. некий аналог этому из недалекого прошлого :
так же создается только один объект..
делайте перенос не при инициализации, а при присвоении.. Это сообщение отредактировал(а) mes - 9.11.2011, 19:46 |
||||
|
|||||
W4FhLF |
|
||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
Это получается как только я вызвал move constructor я уже объектом больше пользоваться не могу потому что данные были перемещены? Разве это не ведёт к понтенциальным ошибкам? Т.е. я должен теперь "запомнить", что объект был перемещён и больше его не трогать. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||
|
|||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
угу. move-semantic довольно редко используется, в особых случаях. или же с временными объектами. посему, потенциально не сильно увеличивает вероятность ошибок. Это сообщение отредактировал(а) boostcoder - 5.3.2012, 16:15 |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
объект, который подпадает под rvlaue-reference по любому ты использовать больше не сможешь. В простом случае, это правая часть выражения: a = c + b. Ты по любому после присваивания не сможешь воспользоваться временным объектом. А если у тебя остаются возможности им воспользоваться, то он не является rvalue и, соответственно, не подпадает под действие перемещающего конструктора. |
|||
|
||||
Sahab |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
Можно ли пользоваться исходным объектом (откуда перемещали) после его перемещения?
http://liveworkspace.org/code/3c9358e9ddae...fd6df109b6ea1cd
|
||||
|
|||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
||||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
кстати да. но...раз объекта не существует, то при вызове X::print() разве не должен произойти сегфолт? или разница в том что X::print() это код, а X::data - данные? ведь по логике, код мы перемещать не можем. так? |
|||
|
||||
Sahab |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
||||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
объект (this) существует .. move не трогает сами объекты, а переносит их содержимое ![]() кстати в приведенном последнем примере, print демонстриует состояние, а не использует его.. так что по сути все правильно работает ![]() |
|||
|
||||
Sahab |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
||||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
потому что ваш move-ctor обнуляет указатель на данные, и следовательно состояние объекта корректно.. |
|||
|
||||
Sahab |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
http://liveworkspace.org/code/c581e966af26...b39b963508fd5e4
Это сообщение отредактировал(а) Sahab - 13.4.2012, 20:30 |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
состояние объекта после переноса неопределено.. |
|||
|
||||
Sahab |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
||||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Вы не то проверяете.. Вы проверяете физическую сущность объекта, а move изменяет состояние.. Добавлено через 1 минуту и 9 секунд Sahab, в Вашем случае коректно.. но такое поведение не гарантированно, а следовательно может быть и подругому .. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
что я понял: move перемещает данные объекта, а следовательно - состояние.
то, что после перемещения, вызов X::print() не вызывает сегфолт - говорит лишь о том, что код не перемещается. оно и логично. при чтении X::data сегфолт не происходит потому, что X::data после перемещения все равно на что-то указывает. на мусор на стеке, к примеру. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
код никода не перемещается.. сегфолт происходит не из за какого то перемещения кода.. а из за за доступа к данным за пределами разрешений.. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
я же так и написал. Добавлено через 4 минуты и 30 секунд ну...почти так ![]() |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
может быть.. я не понял при чем во фразе "код", поэтому и уточнил..
|
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
ну как же.. вызов функции это: 1)сохранение стека, 2)call, и т.д.. т.е. если бы перемещение так же бы и переносило и код вызова, то тогда бы точно получали сегфолт. этим я всего лишь хотел сказать то, что успешный вызов X::print() без сегфолта - не показатель того что объект небыл перемещен. собственно, как и чтение переменной в которой до перемещения располагались данные. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
![]() |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
возможен. но прежде чем получить сегфолт при доступе к "висячим" данным, нужно произвести вызов X::print(). я же об этом и говорил. а т.к. код не переносится, то и при перенесенном объекте вызов всегда будет успешным. а вот получим ли мы сегфолт при чтении данных - это уже другой вопрос. |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Что вы тут спорите? move-семантика нужна в таких случаях, когда именно перемещение и необходимо. Для простых POD типов она смысла не имеет. А вот для контейнеров самое то. Потому что контейнер содержит несколько указателей. move-конструктор (например) копирует ЗНАЧЕНИЯ этих указателей в новый объект, а в старом (который передается как rvalue) их зануляет. Таким образом, деструктор старого объекта ничего не освободит, и новый объект будет существовать как ни в чем ни бывало. Это просто более быстрый вариант по сравнению с shared_ptr/array при использовании в таких ситуациях.
|
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
boostcoder, код вообще никогда не переносился, не переносится, и не будет переносится. Он один для всех объектов. Перенесение кода это не С++, более того, я даже не знаю, есть ли вообще в природе язык, где код переносится с экземпляром объекта. |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
это не от языка зависит. А от программиста. Если очень захотеть, то можно это сделать. По крайней мере на платформах, где нет защиты от выполнения кода в области данных. |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
bsa, я имел ввиду объекто-ориентированный аспект.
само перенесение кода, конечно возможно (хотябы в обычных exe-упаковщиках) Это другое. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
volatile, я не говорил что код переносится. я лишь пытался прояснить это:
|
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
boostcoder, исходным объектом пользоваться можно! Более того, исходный объект после перемещения используется как минимум в деструкторе. Но так как ты перенес состояние, то деструктор отработает "вхолостую" без реального освобождения ресурсов. А вот после деструктора объект уже использовать, как ты понимаешь, нельзя. По логике вещей, деструктор вызывается сразу же после отработки операции перемещения:
|
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
что значит можно ? да, он существуетн ( и довольно долго если был не временным), но у него неопределено состояние, и соответсвенно, неопределено поведение.. для конкретного случая можно определить возможность использования, можно даже обратно вдохнуть жизнь в такие объекты, но нет возможности распространнить это на все случаи.. поэтому говорить о можно нельзя ![]() или иногда можно, но очень осторожно ![]() Это сообщение отредактировал(а) mes - 14.4.2012, 11:43 |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
с чего это вдруг? у него вполне определенное состояние - то, в котором его оставил "перемещатель" (например, если перемещатель занулил только указатель на начало данных вектора, а остальные оставил без изменений, то состояние неопределенное - в общем случае, только деструктор отработает корректно). А это уже задача программиста следить за тем, чтобы состояние соответствовало планам использования. Имхо, после перемещения объект должен быть уничтожен... А "вдыхать" в него жизнь - это только делать себе хуже. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
это то понятно.. но во первых нет гарантий заставляющих оставлять объект в коректном состоянии, во вторых нет (не всегда есть) такой возможности.. а для общего случая нельзя.. |
|||
|
||||
Sahab |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
йопт... так можно или нельзя?
Че в стандарте написано? |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
имелось ввиду не состояние конкретного объекта, а состояние любого объекта после перемещения.. Добавлено @ 12:20 вообще применять move семантику нужно к rvalue... но С++, как говорится, всегда готов придти на помощь, и можно применить move для lvalue, однако в этом случае ответственность ложится на плечи программиста, а стандарт умывает руки ![]() Это сообщение отредактировал(а) mes - 14.4.2012, 13:49 |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
||||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |