Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> r-value refs & move-semantics. что? как? для чего? 
V
    Опции темы
boostcoder
Дата 9.11.2011, 02:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



итак. что же такое r-value refs & move-semantics?

что мне известно об этом?: первое(и вроде как единственное) - позволяет получать ссылки на временные объекты.
Код

void func(type&& t) {}

...


func(type());


такой еще пример:
Код

#include <iostream>
#include <utility>
#include <vector>
#include <string>
int main()
{
    std::string str = "Hello";
    std::vector<std::string> v;
 
    // uses the push_back(const T&) overload, which means 
    // we'll incur the cost of copying str
    v.push_back(str);
    std::cout << "After copy, str is \"" << str << "\"\n";
 
    // uses the rvalue reference push_back(T&&) overload, 
    // which means no strings will copied; instead, the contents
    // of str will be moved into the vector.  This is less
    // expensive, but also means str will now be empty.
    v.push_back(std::move(str));
    std::cout << "After move, str is \"" << str << "\"\n";
 
    std::cout << "The contents of the vector are \"" << v[0]
                                         << "\", \"" << v[1] << "\"\n";
}

http://en.cppreference.com/w/cpp/utility/move

не может быть чтоб на этом польза от r-value refs & move-semantics закончилась.
поделитесь опытом, мыслями.

спасибо.
PM WWW   Вверх
azesmcar
Дата 9.11.2011, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



boostcoder

Это перемещение объекта, объект может быть не копируемым, но перемещаемым. В некоторых случаях копирование объекта невозможно реализовать, зато запросто можно реализовать перемещение.
Например класс std::unique_ptr не поддерживает копирование. Он не считает количество ссылок, т.е. его копирование просто невозможно (или он должен работать как auto_ptr), зато реализовано перемещение этого объекта, что позволяет хранить std::unique_ptr в контейнерах.
PM   Вверх
boostcoder
Дата 9.11.2011, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



azesmcar, но у перемещаемого объекта все равно вызывается деструктор? и если да, то что он разрушает, если данные были перемещены?
PM WWW   Вверх
azesmcar
Дата 9.11.2011, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Например:
Код

#include <algorithm>

class X
{
private:
   int* data;
public:
   X():
      data(new int[1000000]) {}
   ~X()
   {
      delete data;
   }
   X(const X& other):
      data(new int[1000000])
   {
      std::copy(other.data,other.data+1000000,data);
   }
   X(X&& other):
      data(other.data)
   {
      other.data=0;
   }
};

int main()
{
   X x1;
   X x2=std::move(x1);
}

http://liveworkspace.org/code/4baf51d7d55a...835aad73d11a085

Объект перемещается, т.е. все данные переместились в другой объект, в данном случае деструктор сделает delete 0 и успокоится.
Что делает деструктор и конструктор перемещения решает программист.
PM   Вверх
boostcoder
Дата 9.11.2011, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(azesmcar @  9.11.2011,  10:04 Найти цитируемый пост)
Вызывается он у перемещенного

что-то не понял...
вот к примеру:
Код

template<typename F>
void async_call(F&& f) {}

...

async_call(boost::bind(...));

т.е. async_call() возвращает управление тут же. но если функциональный объект так же, тут же будет разрушен, то когда придет время его вызвать получим ошибку сегментации. или как?

Добавлено через 1 минуту и 53 секунды
Цитата(azesmcar @  9.11.2011,  10:10 Найти цитируемый пост)
в данном случае деструктор сделает delete 0

ага. т.е. реализация деструктора должна предполагать подобное поведение?
PM WWW   Вверх
azesmcar
Дата 9.11.2011, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(boostcoder @  9.11.2011,  10:10 Найти цитируемый пост)
т.е. async_call() возвращает управление тут же. но если функциональный объект так же, тут же будет разрушен, то когда придет время его вызвать получим ошибку сегментации. или как? 

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

Добавлено через 1 минуту и 57 секунд
Цитата(boostcoder @  9.11.2011,  10:10 Найти цитируемый пост)
ага. т.е. реализация деструктора должна предполагать подобное поведение? 

точнее реализациа конструктора перемещения smile 
деструктор в моем примере ведет себя как обычно.
PM   Вверх
rumit7
Дата 9.11.2011, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 16.6.2011

Репутация: 6
Всего: 7



Цитата(boostcoder @ 9.11.2011,  09:58)
azesmcar, но у перемещаемого объекта все равно вызывается деструктор? и если да, то что он разрушает, если данные были перемещены?

Извините что вмешиваюсь, вот по этой ссылке идет вроде не плохое и достаточно подробное объяснение 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() для различных аргументов:

Цитата

·         When called with an lvalue of type string, T is deduced to be string& , so Move() takes string& (after collapsing) and returns string&& (after RemoveReference).
 
·         When called with an lvalue of type const string, T is deduced to be const string& , so Move() takes const string& (after collapsing) and returns const string&& (after RemoveReference).
 
·         When called with an rvalue of type string, T is deduced to be string , so Move() takes string&& and returns string&& .
 
·         When called with an rvalue of type const string, T is deduced to be const string , so Move() takes const string&& and returns const string&& .
 
This is how Move() preserves the type and constness of its argument, but converts lvalues into rvalues.


Это сообщение отредактировал(а) rumit7 - 9.11.2011, 10:22
PM MAIL   Вверх
boostcoder
Дата 9.11.2011, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(azesmcar @  9.11.2011,  10:12 Найти цитируемый пост)
функциональный объект был перемещен и будет разрушен после выхода из области видимости

все равно не понимаю...

к примеру, r-value refs у нас нет. тогда мой пример записывался бы так:
Код

template<typename F>
void async_call(const F& f) {}

...

async_call(boost::bind(...));

т.е. тут создавался бы временный объект, внутри функции async_call() инициализировался бы другой объект, и временный объект бы разрушался. тут все понятно.

а вот с r-value что-то не понимаю смысла, если временный объект все равно создается и разрушается..

Добавлено через 1 минуту и 42 секунды
rumit7, спасибо. сейчас прочту.

PM WWW   Вверх
azesmcar
Дата 9.11.2011, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(boostcoder @  9.11.2011,  10:17 Найти цитируемый пост)
а вот с r-value что-то не понимаю смысла, если временный объект все равно создается и разрушается.. 

разрушается не объект а "пустышка", а душа обьекта переселилась в другое тело и живет там в лучших традициях реинкарнации.

Это сообщение отредактировал(а) azesmcar - 9.11.2011, 10:21
PM   Вверх
boostcoder
Дата 9.11.2011, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(azesmcar @  9.11.2011,  10:20 Найти цитируемый пост)
разрушается не объект а "пустышка"

ааа! вот оно как.

Цитата(azesmcar @  9.11.2011,  10:20 Найти цитируемый пост)
душа обьекта переселилась в другое тело и живет там в лучших традициях реинкарнации.

 smile 


вроде понял.. нужно усвоить.
PM WWW   Вверх
boostcoder
Дата 9.11.2011, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



azesmcar, все, понял. спасибо.

зы
с двухсотым плюсиком тебя.

PM WWW   Вверх
mes
Дата 9.11.2011, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  9.11.2011,  01:17 Найти цитируемый пост)
 позволяет получать ссылки на временные объекты.

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


Цитата(boostcoder @  9.11.2011,  01:17 Найти цитируемый пост)
не может быть чтоб на этом польза от r-value refs & move-semantics закончилась.

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



--------------------
PM MAIL WWW   Вверх
baldina
Дата 9.11.2011, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(boostcoder @  9.11.2011,  02:17 Найти цитируемый пост)
не может быть чтоб на этом польза от r-value refs & move-semantics закончилась.

оно собственно и задумывалось как средство оптимизации временных объектов, и от этого польза немалая, т.к. для обеспечения производительности раньше в некоторых случаях требовался специальный, менее красивый и простой дизайн.
Цитата(mes @  9.11.2011,  14:43 Найти цитируемый пост)
польза например наблюдается при возвращении массива из функции.. 

 smile да-да, типа того

Цитата(boostcoder @  9.11.2011,  02:17 Найти цитируемый пост)
 позволяет получать ссылки на временные объекты

Цитата(mes @  9.11.2011,  14:43 Найти цитируемый пост)
хочу обратить внимание, что временный объект не всегда рвалуе и поэтому эти понятия не стоит смешивать.. 

boostcoder видимо имеет в виду это:
http://liveworkspace.org/code/1a70c160da7c...2dbaf2a272a94a2
хотя имхо польза от этого довольно сомнительная...

PM MAIL   Вверх
boostcoder
Дата 9.11.2011, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  9.11.2011,  14:43 Найти цитируемый пост)
польза например наблюдается при возвращении массива из функции

тоже вариант.
PM WWW   Вверх
borisbn
Дата 9.11.2011, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 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 ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
mes
Дата 9.11.2011, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  9.11.2011,  18:04 Найти цитируемый пост)
Что я не так делаю...

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

Добавлено через 1 минуту и 20 секунд
Цитата(borisbn @  9.11.2011,  18:04 Найти цитируемый пост)
 Там создаётся 4 объекта

это по старым правилам smile



--------------------
PM MAIL WWW   Вверх
baldina
Дата 9.11.2011, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(borisbn @  9.11.2011,  19:04 Найти цитируемый пост)
Там создаётся 4 объекта (x, y, x и result внутри operator+), а вызывается 3 деструктора. Как это ?

там всего три объекта, погляди на адреса. result и z одно и то же.

что бы он вызвался, укажи семантику явно 
Код

Str z( move(x + y) );


Добавлено через 4 минуты и 18 секунд
Цитата(baldina @  9.11.2011,  19:32 Найти цитируемый пост)
result и z одно и то же.

это NRVO отработало. велик могучий языка...

Добавлено через 6 минут и 1 секунду
оказывается уже ответили((
PM MAIL   Вверх
borisbn
Дата 9.11.2011, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



mesbaldina, спасибо за ответы, но
1) я хочу, чтобы move-конструктор вызывался автоматически, поэтому не хочу использовать std::move()
2) boostcoder говорит, что на LWS оптимизация выключена, а вы говорите, что
Цитата(mes @  9.11.2011,  19:24 Найти цитируемый пост)
компилятор позволяет себе не переносить из временого в целевой, а сразу использовать целевой объект для результата.

Цитата(baldina @  9.11.2011,  19:32 Найти цитируемый пост)
result и z одно и то же.

или это не имеет отношения к оптимизации ?
тогда вопрос снят


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
mes
Дата 9.11.2011, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  9.11.2011,  18:40 Найти цитируемый пост)
или это не имеет отношения к оптимизации ?

не имеет, это не оптимизация, а перенос при инициализации.. 

некий аналог этому из недалекого прошлого :
Код

Str str = Str ("any");

так же создается только один объект..

Цитата(borisbn @  9.11.2011,  18:40 Найти цитируемый пост)
я хочу, чтобы move-конструктор вызывался автоматически, поэтому не хочу использовать std::move()

делайте перенос не при инициализации, а при присвоении..

Это сообщение отредактировал(а) mes - 9.11.2011, 19:46


--------------------
PM MAIL WWW   Вверх
W4FhLF
Дата 5.3.2012, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Цитата(azesmcar @ 9.11.2011,  10:10)
Например:
Код

#include <algorithm>

class X
{
private:
   int* data;
public:
   X():
      data(new int[1000000]) {}
   ~X()
   {
      delete data;
   }
   X(const X& other):
      data(new int[1000000])
   {
      std::copy(other.data,other.data+1000000,data);
   }
   X(X&& other):
      data(other.data)
   {
      other.data=0;
   }
};

int main()
{
   X x1;
   X x2=std::move(x1);
}

http://liveworkspace.org/code/4baf51d7d55a...835aad73d11a085

Объект перемещается, т.е. все данные переместились в другой объект, в данном случае деструктор сделает delete 0 и успокоится.
Что делает деструктор и конструктор перемещения решает программист.

Это получается как только я вызвал move constructor я уже объектом больше пользоваться не могу потому что данные были перемещены? Разве это не ведёт к понтенциальным ошибкам? Т.е. я должен теперь "запомнить", что объект был перемещён и больше его не трогать.


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
boostcoder
Дата 5.3.2012, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(W4FhLF @  5.3.2012,  14:13 Найти цитируемый пост)
я уже объектом больше пользоваться не могу потому что данные были перемещены?

угу.

Цитата(W4FhLF @  5.3.2012,  14:13 Найти цитируемый пост)
Разве это не ведёт к понтенциальным ошибкам?

move-semantic довольно редко используется, в особых случаях. или же с временными объектами.
посему, потенциально не сильно увеличивает вероятность ошибок.

Это сообщение отредактировал(а) boostcoder - 5.3.2012, 16:15
PM WWW   Вверх
bsa
Дата 5.3.2012, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(W4FhLF @  5.3.2012,  15:13 Найти цитируемый пост)
Т.е. я должен теперь "запомнить", что объект был перемещён и больше его не трогать. 

объект, который подпадает под rvlaue-reference по любому ты использовать больше не сможешь. В простом случае, это правая часть выражения: a = c + b. Ты по любому после присваивания не сможешь воспользоваться временным объектом.
А если у тебя остаются возможности им воспользоваться, то он не является rvalue и, соответственно, не подпадает под действие перемещающего конструктора.
PM   Вверх
Sahab
Дата 13.4.2012, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



Можно ли пользоваться исходным объектом (откуда перемещали) после его перемещения?

http://liveworkspace.org/code/3c9358e9ddae...fd6df109b6ea1cd

Код

#include <algorithm>
#include <iostream>

class X
{
private:
   int* data;
public:
   X():
      data(new int[1000000]) {
            std::cout << "сtor()" << std::endl;
      }
   ~X()
   {
      std::cout << "~dtor()" << std::endl;
      delete data;
   }
   
   void print() {
      std::cout << this << ", " << &data[0] << std::endl;
   }
   
   X(const X& other):
      data(new int[1000000])
   {
      std::cout << "copy()" << std::endl;
      std::copy(other.data,other.data+1000000,data);
   }
   X(X&& other):
      data(other.data)
   {
      std::cout << "rcopy()" << std::endl;
      other.data=0;
   }
};

int main()
{
   X x1;
   X x2=std::move(x1);
   x1.print();
   x2.print();
}


Цитата

сtor()
rcopy()
0xbff6727c, 0
0xbff67278, 0xb6ab0008
~dtor()
~dtor()

PM MAIL   Вверх
mes
Дата 13.4.2012, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Sahab @  13.4.2012,  18:23 Найти цитируемый пост)
Можно ли пользоваться исходным объектом (откуда перемещали) после его перемещения?

нельзя

Цитата(Sahab @  13.4.2012,  18:23 Найти цитируемый пост)
  X x2=std::move(x1);
   x1.print();
   x2.print();

Логика проверки существования значения, путем вывода его в корне не верна.. 



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 13.4.2012, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  13.4.2012,  19:55 Найти цитируемый пост)
проверки существования значения, путем вывода его в корне не верна

кстати да.
но...раз объекта не существует, то при вызове X::print() разве не должен произойти сегфолт? или разница в том что X::print() это код, а X::data - данные? ведь по логике, код мы перемещать не можем.
так?

PM WWW   Вверх
Sahab
Дата 13.4.2012, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



Цитата(mes @  13.4.2012,  19:55 Найти цитируемый пост)
Логика проверки существования значения, путем вывода его в корне не верна.. 

Я предполагал segfault, именно это я проверял, а не вывод и его значение.

Добавлено через 38 секунд
Цитата(boostcoder @  13.4.2012,  20:16 Найти цитируемый пост)
или разница в том что X::print() это код, а X::data - данные?

Проверял и с данными, сегфолта нет.
PM MAIL   Вверх
mes
Дата 13.4.2012, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  13.4.2012,  19:16 Найти цитируемый пост)
но...раз объекта не существует, то при вызове X::print() разве не должен произойти сегфолт? 

объект  (this) существует .. move не трогает сами объекты, а переносит их содержимое smile

кстати в приведенном последнем примере, print демонстриует состояние, а не использует его.. так что по сути все правильно работает smile





--------------------
PM MAIL WWW   Вверх
Sahab
Дата 13.4.2012, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



Цитата(mes @  13.4.2012,  19:55 Найти цитируемый пост)
нельзя

Я это и предполагал, хотел просто услышать материальное объяснение. 
PM MAIL   Вверх
mes
Дата 13.4.2012, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Sahab @  13.4.2012,  19:22 Найти цитируемый пост)
Проверял и с данными, сегфолта нет. 

потому что ваш move-ctor обнуляет указатель на данные, и следовательно состояние объекта корректно..



--------------------
PM MAIL WWW   Вверх
Sahab
Дата 13.4.2012, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



http://liveworkspace.org/code/c581e966af26...b39b963508fd5e4


Это сообщение отредактировал(а) Sahab - 13.4.2012, 20:30
PM MAIL   Вверх
mes
Дата 13.4.2012, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Sahab @  13.4.2012,  19:25 Найти цитируемый пост)
 услышать материальное объяснение

состояние объекта после переноса неопределено.. 


--------------------
PM MAIL WWW   Вверх
Sahab
Дата 13.4.2012, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



Цитата(mes @  13.4.2012,  20:26 Найти цитируемый пост)
и следовательно состояние объекта корректно..


Цитата(mes @  13.4.2012,  20:29 Найти цитируемый пост)
состояние объекта после переноса неопределено..  


PM MAIL   Вверх
mes
Дата 13.4.2012, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Код

   x1.setValue(0.3);

Вы не то проверяете.. Вы проверяете физическую сущность объекта, а move изменяет состояние..

Добавлено через 1 минуту и 9 секунд
Sahab, в Вашем случае коректно.. но такое поведение не гарантированно, а следовательно может быть и подругому .. 



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 13.4.2012, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



что я понял: move перемещает данные объекта, а следовательно - состояние.
то, что после перемещения, вызов X::print() не вызывает сегфолт - говорит лишь о том, что код не перемещается. оно и логично.
при чтении X::data сегфолт не происходит потому, что X::data после перемещения все равно на что-то указывает. на мусор на стеке, к примеру.

PM WWW   Вверх
mes
Дата 13.4.2012, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  13.4.2012,  19:50 Найти цитируемый пост)
что код не перемещается. оно и логично.

код никода не перемещается.. сегфолт происходит не из за какого то перемещения кода.. 
а из за за доступа к данным за пределами разрешений.. 




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 13.4.2012, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  13.4.2012,  20:59 Найти цитируемый пост)
сегфолт происходит не из за какого то перемещения кода.

я же так и написал.

Добавлено через 4 минуты и 30 секунд
ну...почти так smile

PM WWW   Вверх
mes
Дата 13.4.2012, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  13.4.2012,  20:07 Найти цитируемый пост)
я же так и написал.
может быть.. я не понял при чем во фразе "код", поэтому и уточнил.. 



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 13.4.2012, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  13.4.2012,  21:13 Найти цитируемый пост)
я не понял при чем во фразе "код"

ну как же.. вызов функции это: 1)сохранение стека, 2)call, и т.д..
т.е. если бы перемещение так же бы и переносило и код вызова, то тогда бы точно получали сегфолт.

этим я всего лишь хотел сказать то, что успешный вызов X::print() без сегфолта - не показатель того что объект небыл перемещен. собственно, как и чтение переменной в которой до перемещения располагались данные.

PM WWW   Вверх
mes
Дата 13.4.2012, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  13.4.2012,  20:33 Найти цитируемый пост)
т.е. если бы перемещение так же бы и переносило и код вызова,

 smile, ну пусть так.. тогда вопрос .. а если не переносит код ,то сегфолт невозможен ?!




--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 13.4.2012, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  13.4.2012,  21:38 Найти цитируемый пост)
а если не переносит код ,то сегфолт невозможен ?

возможен. но прежде чем получить сегфолт при доступе к "висячим" данным, нужно произвести вызов X::print(). я же об этом и говорил. а т.к. код не переносится, то и при перенесенном объекте вызов всегда будет успешным. а вот получим ли мы сегфолт при чтении данных - это уже другой вопрос.

PM WWW   Вверх
bsa
Дата 13.4.2012, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Что вы тут спорите? move-семантика нужна в таких случаях, когда именно перемещение и необходимо. Для простых POD типов она смысла не имеет. А вот для контейнеров самое то. Потому что контейнер содержит несколько указателей. move-конструктор (например) копирует ЗНАЧЕНИЯ этих указателей в новый объект, а в старом (который передается как rvalue) их зануляет. Таким образом, деструктор старого объекта ничего не освободит, и новый объект будет существовать как ни в чем ни бывало. Это просто более быстрый вариант по сравнению с shared_ptr/array при использовании в таких ситуациях.
PM   Вверх
volatile
Дата 13.4.2012, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(boostcoder @  13.4.2012,  21:33 Найти цитируемый пост)
если бы перемещение так же бы и переносило и код вызова, то тогда бы точно получали сегфолт.

boostcoder, код вообще никогда не переносился, не переносится, и не будет переносится. 
Он один для всех объектов. 
Перенесение кода это не С++, более того, я даже не знаю, есть ли вообще в природе язык, где код переносится с экземпляром объекта.
PM MAIL   Вверх
bsa
Дата 13.4.2012, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(volatile @  14.4.2012,  00:52 Найти цитируемый пост)
Перенесение кода это не С++, более того, я даже не знаю, есть ли вообще в природе язык, где код переносится с экземпляром объекта. 

это не от языка зависит. А от программиста. Если очень захотеть, то можно это сделать. По крайней мере на платформах, где нет защиты от выполнения кода в области данных.
PM   Вверх
volatile
Дата 14.4.2012, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



bsa, я имел ввиду объекто-ориентированный аспект.
само перенесение кода, конечно возможно (хотябы в обычных exe-упаковщиках)
Это другое.

PM MAIL   Вверх
boostcoder
Дата 14.4.2012, 01:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



volatile, я не говорил что код переносится. я лишь пытался прояснить это:

Цитата(mes @  13.4.2012,  19:55 Найти цитируемый пост)
Цитата(Sahab @  13.4.2012,  18:23 )
Можно ли пользоваться исходным объектом (откуда перемещали) после его перемещения?

нельзя

Цитата(Sahab @  13.4.2012,  18:23 )
  X x2=std::move(x1);
   x1.print();
   x2.print();

Логика проверки существования значения, путем вывода его в корне не верна.. 


PM WWW   Вверх
bsa
Дата 14.4.2012, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



boostcoder, исходным объектом пользоваться можно! Более того, исходный объект после перемещения используется как минимум в деструкторе. Но так как ты перенес состояние, то деструктор отработает "вхолостую" без реального освобождения ресурсов. А вот после деструктора объект уже использовать, как ты понимаешь, нельзя. По логике вещей, деструктор вызывается сразу же после отработки операции перемещения:
Код
MyClass x = y + z;
Сначала выполнится y+z и результат поместится во временный объект. Затем вызовется перемещающий конструктор для x и перенесет состояние из временного объекта. Затем будет вызван деструктор временного объекта.
PM   Вверх
mes
Дата 14.4.2012, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(bsa @  14.4.2012,  10:16 Найти цитируемый пост)
 исходным объектом пользоваться можно!

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



Это сообщение отредактировал(а) mes - 14.4.2012, 11:43


--------------------
PM MAIL WWW   Вверх
bsa
Дата 14.4.2012, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(mes @  14.4.2012,  12:40 Найти цитируемый пост)
у него неопределено состояние

с чего это вдруг? у него вполне определенное состояние - то, в котором его оставил "перемещатель" (например, если перемещатель занулил только указатель на начало данных вектора, а остальные оставил без изменений, то состояние неопределенное - в общем случае, только деструктор отработает корректно). А это уже задача программиста следить за тем, чтобы состояние соответствовало планам использования.
Имхо, после перемещения объект должен быть уничтожен... А "вдыхать" в него жизнь - это только делать себе хуже.
PM   Вверх
mes
Дата 14.4.2012, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(bsa @  14.4.2012,  11:06 Найти цитируемый пост)
с чего это вдруг? у него вполне определенное состояние - то, в котором его оставил "перемещатель" 

это то понятно.. но во первых нет гарантий заставляющих оставлять объект в коректном состоянии, во вторых нет (не всегда есть) такой возможности.. 

Цитата(mes @  14.4.2012,  10:40 Найти цитируемый пост)
для конкретного случая можно определить возможность использования
 а для общего случая нельзя.. 




--------------------
PM MAIL WWW   Вверх
Sahab
Дата 14.4.2012, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



йопт... так можно или нельзя?
Че в стандарте написано?
PM MAIL   Вверх
mes
Дата 14.4.2012, 12:18 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(bsa @  14.4.2012,  11:06 Найти цитируемый пост)
у него вполне определенное состояние - то, в котором его оставил "перемещатель" 

имелось ввиду не состояние конкретного объекта, а состояние любого объекта после перемещения..

Добавлено @ 12:20
Цитата(Sahab @  14.4.2012,  11:17 Найти цитируемый пост)
йопт... так можно или нельзя?

вообще применять move семантику нужно к rvalue...
но С++, как говорится, всегда готов придти на помощь, и можно применить move для lvalue,  однако в этом случае ответственность ложится на плечи программиста, а стандарт умывает руки  smile 

Это сообщение отредактировал(а) mes - 14.4.2012, 13:49


--------------------
PM MAIL WWW   Вверх
bsa
Дата 14.4.2012, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(mes @  14.4.2012,  13:18 Найти цитируемый пост)
но в С++, какк говорится, всегда готов придти на помощь, и можно применить move для lvalue, но в этом случае ответсвенность ложится на плечи программиста, а стандарт умывает руки
Классно сказано! Ёмко!
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1915 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.