Я недавно начал использовать C ++ и я решил учиться C ++ 11 функции.
Но то, как работают коды с ++, иногда не так ощутимо.
ниже мой код.
На части с decltype(std::move(sample)) sample2 = std::move(sample);
Я не уверен, почему эта строка не вызывает конструктор перемещения.
Не могли бы вы объяснить, почему?
#include <iostream>
class AAA
{
public:
AAA() { std::cout << "default constructor" << std::endl; }
AAA(const AAA& cs) { std::cout << "copy constructor" << std::endl; }
AAA(AAA&& cs) { std::cout << "move constructor" << std::endl; }
~AAA() { std::cout << "destructor" << std::endl; }
};
int main(int argc, char* args[])
{
AAA sample;
// ((right here))
decltype(std::move(sample)) sample2 = std::move(sample);
return 0;
}
Он скомпилирован в [ubuntu 16.04 LTS] с помощью [gcc 5.4.0]
оригинальный код: https://ide.geeksforgeeks.org/tALvLuSNbN
Ваш фрагмент расширяется до
AAA&& sample2 = std::move(sample);
который связывает значение (результат std::move(sample)
) к значению ссылки (sample2
). Новый объект не создается, и, следовательно, такой конструктор не вызывается.
Функция std::move<T>
возвращает T &&
, Таким образом, для std::move(sample)
это возвращается AAA &&
, Это Rvalue ссылка и вести себя очень как lvalue ссылка (типа как AAA &
будет ссылкой на lvalue) в том смысле, что они оба являются псевдонимами для уже существующих объектов.
Важно понимать, что std::move
делает не сама по себе причина чего-либо, чтобы быть перемещенным Он просто возвращает rvalue ссылку на заданный аргумент. Например std::move(foo);
один не делает абсолютно ничего. Только когда результат используется для инициализации или присвоения объекту, он становится полезным.
Например auto bar = std::move(foo);
вернет ссылку на значение foo
и использовать эту ссылку для вызова bar
конструктор.
Чтобы ответить на вопрос, так как std::move(sample)
возвращает AAA &&
линия, о которой идет речь, такая же, как AAA && sample2 = std::move(sample);
, Поведение практически такое же, как AAA & sample2 = sample;
, В обоих случаях вы инициализируете ссылку на существующий объект, и новый объект создавать не нужно.
Если ваша цель — двигаться sample
в новый AAA
правильная строка будет auto sample2 = std::move(sample);
как вы делаете с sample3
, Хотя будьте осторожны, что линия sample3
движется от уже переехал sample
,