6 / 6 / 4
Регистрация: 26.06.2015
Сообщений: 83
1

C++11 Конструктор перемещения

05.08.2016, 14:05. Показов 3350. Ответов 9
Метки нет (Все метки)

Добрый день. Решил тут познакомится с конструктором перемещения, и сразу протестировал кое-что.
Конструктор перемещения просто изымает данные из аргумента и передает в объект который вызвал этот коструктор, для этого используют rvalue ссылку. Но ведь подобного можно добиться и с простой ссылкой. Вот пример:
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
class ptr
{
private:
    int *arr;
 
public:
    ptr()
    {
        cout<<"CONST "<<this<<endl;
        arr = new int[100];
        arr[0] = 1555;
    }
 
    ptr(ptr &&o)
    {
        cout<<"Move "<<this<<&o<<endl;
        arr = o.arr;
        o.arr = nullptr;
    }
 
    ptr(ptr &o)
    {
        cout<<"COPY "<<this<<&o<<endl;
        arr = o.arr;
        o.arr = nullptr;
    }
 
    ~ptr()
    {
        cout<<"DELETE "<<this<<endl;
        delete [] arr;
    }
 
    void print()
    {
        cout<<arr[0]<<endl;
    }
 
    void getptr()
    {
        cout<<arr<<endl;
    }
};
Если в main сделать такие вызовы:
C++
1
2
3
4
5
    ptr p1;
    ptr p2(std::move(p1));
    p2.print();
    p2.getptr();
    p1.getptr();
Результат будет таким:
C++
1
2
3
4
5
CONST  0x28fe44
Move  0x28fe40 0x28fe44
1555
0x14aa4ef8
0x0
Если переписать конструктор перемещения на конструктор копирования, то получается тоже самое:
C++
1
2
3
4
5
6
7
8
9
10
11
12
...
    ptr p1;
    ptr p2(p1);
    p2.print();
    p2.getptr();
    p1.getptr();
...
//CONST  0x28fe44
//COPY  0x28fe40 0x28fe44
//1555
//0x13504ef8
//0x0
Объясните пожалуйста принцип всего этого перемещения и move семантики. Спасибо!!!
П.С. Компилятор - MinGW 4.9.2, среда - Qt Creator 4.0.1
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.08.2016, 14:05
Ответы с готовыми решениями:

Конструктор перемещения
Здравствуйте, пытаюсь уже некоторое время разобраться с move-семантикой. Честно говоря возникли...

Конструктор перемещения
#include &lt;iostream&gt; #include &lt;memory&gt; using namespace std; class A { int x; public: ...

Конструктор перемещения
Здравствуйте. У меня есть такой класс: class Organization { char *name; int year,...

Конструктор перемещения
Правильно написан конструктор, значения в right нужно обнулять или не нужно? class Test {...

9
125 / 125 / 44
Регистрация: 05.10.2013
Сообщений: 462
05.08.2016, 14:37 2
Лучший ответ Сообщение было отмечено TheThe как решение

Решение

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

Добавлено через 6 минут
Для инициализации константным объектом в конструкторе аргумент нужно объявлять как ссылку на константу. Но тогда вы не сможете "переместить" данные, а только можно скопировать. То же самое будет касаться и временных объектов. Вы не сможете в них переместить данные с помощью конструктора копирования. Поэтому был введен конструктор перемещения. Плюс конструктор перемещения используется для инициализации объектами, которые больше не нужны (с помощью std::move, который вы продемонстрировали в примере).
1
245 / 139 / 53
Регистрация: 23.11.2015
Сообщений: 394
05.08.2016, 14:55 3
Лучший ответ Сообщение было отмечено TheThe как решение

Решение

старый auto_ptr так и был реализован, через конструктор копирования и пару оберток
с самого начала до 3:30 он объясняет как это было, а потом говорит, чем такой подход плох.

2
rikimaru2013
05.08.2016, 16:47
  #4

Не по теме:

Babysitter, вот это он волосатый!!! =-O

0
Babysitter
05.08.2016, 17:30
  #5

Не по теме:

rikimaru2013, "hacker long hair" +5 int and +5 wisdom

0
6 / 6 / 4
Регистрация: 26.06.2015
Сообщений: 83
05.08.2016, 19:19  [ТС] 6
Babysitter, Спасибо за видео.

Добавлено через 21 минуту
Babysitter, Т.е. если я правильно понял, то.
C++
1
2
3
4
5
6
7
8
9
10
11
template<typename T>
T crtObj()
{
T a;
return a;
}
 
...
T x;
x = crtObj();
...
Объект а при выходе из функции и будет rvalue ссылкой ? Т.е. приводится к rvalue ссылке?? И, имея реализованный перемещающий оператор, данные из временного объекта а можно изъять и присвоить объекту х?
0
245 / 139 / 53
Регистрация: 23.11.2015
Сообщений: 394
05.08.2016, 19:39 7
Лучший ответ Сообщение было отмечено TheThe как решение

Решение

Цитата Сообщение от TheThe Посмотреть сообщение
Объект а при выходе из функции и будет rvalue ссылкой ? Т.е. приводится к rvalue ссылке?? И, имея реализованный перемещающий оператор, данные из временного объекта а можно изъять и присвоить объекту х?
ага, теперь все, у чего есть дешевый мув можно и нужно возвращать из функции по значению.
всем показывают код вроде этого, а потом говорят скомпильте дважды с -std=c++98 и -std=c++11
и посмотрите как быстро будут работать эти программы.
C++
1
2
3
4
5
6
7
std::vector<int> return_vector(void)
{
    std::vector<int> tmp (1000000);
    return tmp;
}
 
std::vector<int> rval_ref = return_vector();
2
6 / 6 / 4
Регистрация: 26.06.2015
Сообщений: 83
05.08.2016, 19:47  [ТС] 8
Babysitter, теперь понятнее, спасибо!
0
245 / 139 / 53
Регистрация: 23.11.2015
Сообщений: 394
05.08.2016, 19:55 9
TheThe, последнее - в старых компиляторах были такие оптимизации, назывались rvo/nrvo. так вот они иногда делали по сути тоже самое, что делает мув семантика на уровне языка. если хочешь реально провести этот опыт и увидеть большую разницу, то нужно отключить эти оптимизации флагом компилятора, в гцц -fno-elide-constructors
1
827 / 251 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
05.08.2016, 20:09 10
Цитата Сообщение от Babysitter Посмотреть сообщение
делали по сути тоже самое
Не тоже самое, т.к. copy elision/rvo/nrvo вообще ничего не вызывает в плане копирования/перемещения и плюет на сайд эффекты.
Цитата Сообщение от Babysitter Посмотреть сообщение
в старых компиляторах были такие оптимизации
Они и сейчас есть. Эти оптимизации эффективнее, чем перемещение.

Добавлено через 2 минуты
TheThe, как раз сейчас пишу блог о семантике перемещения. Пока скудно, но уже что-то есть. Когда будет готово - не знаю, хотя могу опубликовать и уже потом "допиливать" потихоньку.
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.08.2016, 20:09
Помогаю со студенческими работами здесь

Конструктор перемещения и оптимизация
Имеем тестовый код: #include &lt;iostream&gt; using namespace std; struct A { A( int v ) ...

Синтезируемый конструктор перемещения
Насколько я знаю, при определении в классе пользовательского конструктора копирования компилятор не...

Не срабатывает конструктор перемещения
Есть класс у которого удалён конструктор перемещения. Но тем не менее, при передаче обьекта данного...

Не работает конструктор перемещения (C++11)
Прив. Пишу класс подобный string'гу, ну и в процессе изучаю C++. Добрался до оператора и...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru