Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/25: Рейтинг темы: голосов - 25, средняя оценка - 4.80
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562

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

23.11.2014, 19:22. Показов 5514. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Что такое 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 присваивания для этого класса?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.11.2014, 19:22
Ответы с готовыми решениями:

move семантика
Сейчас стало появляться нечто вроде такого: class X { public: X (const X& lvalue); // copy constructor X (X&&...

Move семантика (класс полиномов)
Доброго времени суток. Пишу простенький класс полиномов, в котором есть единственное приватное поле - это map. Вот думаю надо ли писать...

Что такое файловый буфер? Что такое режим (модификатор) доступа, при работе с файлами?
Что такое файловый буфер? Что такое режим (модификатор) доступа, при работе с файлами?

17
 Аватар для Pancir
59 / 46 / 11
Регистрация: 16.09.2014
Сообщений: 124
23.11.2014, 19:28
Вот реально странно, вроде опытный человек на форуме, а задать свой вопрос сперва у гугля не догадывается, там уже все ответы есть.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
23.11.2014, 19:29  [ТС]
То есть A &operator = (A &&a);
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
23.11.2014, 19:33
Цитата Сообщение от taras atavin Посмотреть сообщение
Как написать реализацию move присваивания для этого класса?
Через swap.
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
23.11.2014, 19:34
Наверное так :
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;
}
};
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
23.11.2014, 20:09  [ТС]
Цитата Сообщение от 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;
.
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
23.11.2014, 20:13
taras atavin,
Значит *Source не есть rvalue, и мув присваивание не вызывается, а вызывается обычное, которого судя по ошибке нет ))
Либо сами кастуем к rvalue, либо пишем обычное присваивание.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13179 / 6815 / 1821
Регистрация: 18.10.2014
Сообщений: 17,244
23.11.2014, 21:00
Цитата Сообщение от 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);
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
23.11.2014, 21:46
Цитата Сообщение от 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, что бы явно подчеркнуть, что этот объект можно опустошать.
2
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
24.11.2014, 04:25  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
И тогда, вы можете использовать std::move, что бы явно подчеркнуть, что этот объект можно опустошать.
Как?
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
24.11.2014, 04:27
Цитата Сообщение от taras atavin Посмотреть сообщение
Как?
Пост 8, последняя строчка.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
24.11.2014, 04:30  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
TDirectory *target, *source; ... *target = std::move(*source);
Здесь нужен конструктор перемещения, или достаточно присваивания?
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
24.11.2014, 04:32
Цитата Сообщение от taras atavin Посмотреть сообщение
Что такое move семантика?
вкратце: Семантика перемещения и perfect forwarding(правильная передача)
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13179 / 6815 / 1821
Регистрация: 18.10.2014
Сообщений: 17,244
24.11.2014, 05:20
Цитата Сообщение от taras atavin Посмотреть сообщение
Здесь нужен конструктор перемещения, или достаточно присваивания?
Здесь - именно перемещающий оператор присваивания.
1
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
23.12.2014, 07:31  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Здесь - именно перемещающий оператор присваивания.
Это понятно. А при его наличии перемещающий конструктор нужен?
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
23.12.2014, 08:14
Цитата Сообщение от taras atavin Посмотреть сообщение
Это понятно. А при его наличии перемещающий конструктор нужен?
Зависит от вашего алгоритма. Один при создании, другой при жизни. Но если уже и работаете с семантикой переноса - то реализуйте оба метода - времени затратите на 30 секунд больше - зато профит.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
23.12.2014, 08:18  [ТС]
А как его писать? Начиная с прототипа, пожалуйста.
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
23.12.2014, 08:31
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();
    
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.12.2014, 08:31
Помогаю со студенческими работами здесь

Что такое рекурсивный тип данных? Что такое конструкция рекурсивного типа?
Что такое рекурсивный тип данных? Что такое конструкция рекурсивного типа?

Что такое хэндлер файла? Что такое файловый указатель?
Что такое хэндлер файла? Что такое файловый указатель?

Что такое заголовочный файл? Что такое файл исходного кода? Рассмотрите назначение каждого из них
Что такое заголовочный файл? Что такое файл исходного кода? Рассмотрите назначение каждого из них пожалуйста.

Vector::swap и std::move - что эффективнее?
Пусть имеется пустой вектор A и заполненный некими данными вектор B. Тогда какой из методов более эффективный: A.swap(B); A =...

Что происходит когда std::move применяется для int?
Мне, вроде бы, понятно как работает std::move() на классах типа string. Но мне непонятно что будет в данном случаи. #include...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при создании или изменении элементов справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи электронной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru