Форум программистов, компьютерный форум CyberForum.ru

Что такое move семантика? - C++

Восстановить пароль Регистрация
 
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
23.11.2014, 19:22     Что такое move семантика? #1
Что такое move семантика?

Добавлено через 6 минут
Я правильно понимаю, что mov присваивание перемещает правый операнд на место левого? И как его писать?
Пусть есть некий класс, чьи объекты имеют указатель на родителя и указатель на массив потомков.
C++
1
2
3
4
5
6
7
8
class A
{
 A *Parent;
 A *Children;
 size_t Count;
 public:
  A &operator = (A &a);
};
. Как написать реализацию move присваивания для этого класса?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Pancir
 Аватар для Pancir
57 / 44 / 10
Регистрация: 16.09.2014
Сообщений: 124
23.11.2014, 19:28     Что такое move семантика? #2
Вот реально странно, вроде опытный человек на форуме, а задать свой вопрос сперва у гугля не догадывается, там уже все ответы есть.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
23.11.2014, 19:29  [ТС]     Что такое move семантика? #3
То есть A &operator = (A &&a);
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
23.11.2014, 19:33     Что такое move семантика? #4
Цитата Сообщение от taras atavin Посмотреть сообщение
Как написать реализацию move присваивания для этого класса?
Через swap.
Nosey
 Аватар для Nosey
1185 / 352 / 102
Регистрация: 22.10.2014
Сообщений: 789
Завершенные тесты: 2
23.11.2014, 19:34     Что такое move семантика? #5
Наверное так :
C++
1
2
3
4
5
6
7
8
9
10
11
12
class A
{
 A *Parent;
 A *Children;
 size_t Count;
 public:
  A &operator = (A &&a){
std::swap(Parent,a.Parent);
std::swap(Children,a.Children);
Count = a.Count;
}
};
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
23.11.2014, 20:09  [ТС]     Что такое move семантика? #6
Цитата Сообщение от Pancir Посмотреть сообщение
а задать свой вопрос сперва у гугля не догадывается, там уже все ответы есть.
Догадался.

Добавлено через 15 минут
C++
1
2
3
4
5
6
7
8
class TDirectory
{
 std::wstring                  Name;
 TDirectory                   *Parent;
 TDirectory                   *Children;
 size_t                        ChildrenCount;
 ...
};
C++
1
2
3
4
5
6
7
8
9
10
        TDirectory                     &
       TDirectory    ::                 operator =                                            (      TDirectory     &&Directory       )
{
 Name         =Directory.Name;
 Parent       =Directory.Parent;
 Children     =Directory.Children
 ChildrenCount=Directory.ChildrenCount;
 Directory.Children     =NULL;
 Directory.ChildrenCount=0;
}
,
на строку
C++
1
*Target=*Source;
пишет
C++
1
error: use of deleted function 'TDirectory& TDirectory::operator=(const TDirectory&)'|
. Я не операционную систему пишу, у меня внутри документа будут каталоги, но с точки зрения операционной системы это будет ровно один файл и каталогов внутри она не увидит.
C++
1
2
 TDirectory *Source;
 TDirectory *Target;
.
Nosey
 Аватар для Nosey
1185 / 352 / 102
Регистрация: 22.10.2014
Сообщений: 789
Завершенные тесты: 2
23.11.2014, 20:13     Что такое move семантика? #7
taras atavin,
Значит *Source не есть rvalue, и мув присваивание не вызывается, а вызывается обычное, которого судя по ошибке нет ))
Либо сами кастуем к rvalue, либо пишем обычное присваивание.
TheCalligrapher
С чаем беда...
Эксперт С++
 Аватар для TheCalligrapher
2909 / 1445 / 397
Регистрация: 18.10.2014
Сообщений: 2,669
23.11.2014, 21:00     Что такое move семантика? #8
Цитата Сообщение от taras atavin Посмотреть сообщение
пишет
error: use of deleted function 'TDirectory& TDirectory::operator=(const TDirectory&)'|
Неформально выражаясь, компилятор будет сам вызывать мув оператор присваивания только тогда, когда компилятор уверен, что объект в правой части - не жилец, т.е. будет уничтожен [почти] сразу после присваивания. В частности, присваивание из временных объектов будет идти по мув оператору

C++
1
2
3
TDirectory *target;
...
*target = TDirectory();
Если же объект в правой части не уничтожается сразу после присваивания, то мув автоматически делаться не будет. Его надо специально заказывать

C++
1
2
3
TDirectory *target, *source;
...
*target = std::move(*source);
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
23.11.2014, 21:46     Что такое move семантика? #9
Цитата Сообщение от taras atavin Посмотреть сообщение
Что такое move семантика?
Самое главное, что нужно понять: вы можете писать методы, которые различают "обычные объекты" (lvalue) и "временные" (rvalue)

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

Покажу на примере:

http://rextester.com/JCQZS64854

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
using namespace std;
 
struct sample
{
    int* data;
    
    ~sample()
    {
        if(data)
            cout<<"delete object("<<*data<<")\n";
        else
            cout<<"delete empty object\n";
            
        
        delete data;
    }
    
    sample(const int v)
        : data( new int(v) )
    { cout<<"ctor("<<*data<<")\n"; }
    
    sample():data(nullptr) { cout<<"ctor\n"; }
    sample(const sample&)  { cout<<"copy\n"; }
    sample(sample&&     )  { cout<<"move\n"; }
    
    sample& operator=(const sample& rhs)
    {
        cout<<"copy operator=\n";
        data = new int(*rhs.data);
        return *this;
    }
    
    sample& operator=(sample&& rhs)
    {
        cout<<"move operator=\n";
        
        data = rhs.data;
        rhs.data = nullptr;
        return *this;
    }
};
 
sample foo()
{
    sample s(10);
    return s;
}
 
int main()
{
    std::cout << "Hello, world!\n";
    
    sample s;
    s = foo();
}
sample держит внутри себя указатель на данные в куче.

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

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

Таким образом осуществляются оптимизации создания объектов без необходимости выполнять глубокую копию.

--------------

Иногда бывают случаи, когда объект по факту не является временным.
Но вы совершенно уверены, что объект вам больше не нужен.

И тогда, вы можете использовать std::move, что бы явно подчеркнуть, что этот объект можно опустошать.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
24.11.2014, 04:25  [ТС]     Что такое move семантика? #10
Цитата Сообщение от hoggy Посмотреть сообщение
И тогда, вы можете использовать std::move, что бы явно подчеркнуть, что этот объект можно опустошать.
Как?
0x10
2426 / 1598 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
24.11.2014, 04:27     Что такое move семантика? #11
Цитата Сообщение от taras atavin Посмотреть сообщение
Как?
Пост 8, последняя строчка.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
24.11.2014, 04:30  [ТС]     Что такое move семантика? #12
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
TDirectory *target, *source; ... *target = std::move(*source);
Здесь нужен конструктор перемещения, или достаточно присваивания?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
24.11.2014, 04:32     Что такое move семантика? #13
Цитата Сообщение от taras atavin Посмотреть сообщение
Что такое move семантика?
вкратце: Семантика перемещения и perfect forwarding(правильная передача)
TheCalligrapher
С чаем беда...
Эксперт С++
 Аватар для TheCalligrapher
2909 / 1445 / 397
Регистрация: 18.10.2014
Сообщений: 2,669
24.11.2014, 05:20     Что такое move семантика? #14
Цитата Сообщение от taras atavin Посмотреть сообщение
Здесь нужен конструктор перемещения, или достаточно присваивания?
Здесь - именно перемещающий оператор присваивания.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
23.12.2014, 07:31  [ТС]     Что такое move семантика? #15
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Здесь - именно перемещающий оператор присваивания.
Это понятно. А при его наличии перемещающий конструктор нужен?
rikimaru2013
C++ Game Dev
 Аватар для rikimaru2013
2139 / 972 / 223
Регистрация: 30.11.2013
Сообщений: 3,241
23.12.2014, 08:14     Что такое move семантика? #16
Цитата Сообщение от taras atavin Посмотреть сообщение
Это понятно. А при его наличии перемещающий конструктор нужен?
Зависит от вашего алгоритма. Один при создании, другой при жизни. Но если уже и работаете с семантикой переноса - то реализуйте оба метода - времени затратите на 30 секунд больше - зато профит.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
23.12.2014, 08:18  [ТС]     Что такое move семантика? #17
А как его писать? Начиная с прототипа, пожалуйста.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.12.2014, 08:31     Что такое move семантика?
Еще ссылки по теме:

C++ Vector::swap и std::move - что эффективнее?
C++ Семантика перемещения - разобрать код
C++ Что такое С++ ?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
rikimaru2013
C++ Game Dev
 Аватар для rikimaru2013
2139 / 972 / 223
Регистрация: 30.11.2013
Сообщений: 3,241
23.12.2014, 08:31     Что такое move семантика? #18
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
using namespace std;
 
 
class Foo
{
private:
    int* m_ptr = nullptr;
public:
    Foo(int x)
    {
        m_ptr = new int(x);
    }
 
    Foo(Foo&& move)
    {
        m_ptr = move.m_ptr;
        move.m_ptr = nullptr;
    }
    ~Foo()
    {
        delete m_ptr;
    }
 
    void show()
    {
        cout << *m_ptr << endl;
    }
};
 
 
Foo createFoo(int x)
{
    return Foo(x);
}
int main()
{
    Foo a = std::move(createFoo(33));
    a.show();
    
}
Yandex
Объявления
23.12.2014, 08:31     Что такое move семантика?
Ответ Создать тему
Опции темы

Текущее время: 15:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru