为什么不可移动的对象仍然是一个副本
why non-movable Object still a copy
考虑以下代码,实体对象是不可移动的。我知道 std::move(Obj) 只是将 Obj 转换为右值引用 Obj。而且我也知道右值引用变量仍然是一个左值对象。但是我还是很困惑为什么语句auto temp = std::move(a)
可以调用拷贝构造函数,语句a = std::move(b);
可以调用拷贝赋值运算符。因为,std::move(a) 是一个右值引用,为什么它仍然可以调用左值构造函数。
#include <iostream>
template<typename T>
void my_swap(T& a, T& b) {
auto temp = std::move(a);
a = std::move(b);
b = std::move(temp);
}
class Entity{
int _id;
public:
Entity(int id) :_id(id) {std::cout << "construtor\n" << std::endl;}
Entity(const Entity& other) {
_id = other._id;
std::cout << "copy constructor\n" << std::endl;
}
Entity& operator= (const Entity& other) {
if (&other == this) return *this;
this->_id = other._id;
std::cout << "copy assignment operator\n";
return *this;
}
};
int main() {
Entity e1 = Entity(10);
Entity e2 = Entity(20);
my_swap(e1,e2);
return 0;
}
Entity object is non-movable
没有。即使它没有 move constructor/assignment-operator,它也有 copy constructor/assignment-operator taking lvalue-reference to const。 std::move(a)
和 std::move(b)
是右值(xvalue)表达式,它们可以绑定到 lvalue-reference 到 const。
您还可以查看 std::is_move_constructible
:
Types without a move constructor, but with a copy constructor that accepts const T& arguments, satisfy std::is_move_constructible.
Considering the following code, Entity object is non-movable.
不,不是。 Entity
可移动
But I still confusing why statement auto temp = std::move(a)
对 const 的左值引用可以绑定到右值。复制构造函数接受对 const 参数的左值引用。该参数可以绑定到 std::move(a)
右值参数。
And I also know that rvalue reference variable is still a lvalue object.
不完全是。引用不是对象。 id-expression 命名任何东西,包括右值引用变量,是左值。
Entity is movable. Does is because there exists default move constructor/assignment-operator.
它是可移动的,因为它有一个复制constructor/assignment操作符,它没有删除移动constructor/assignment操作符。
如果您想将 Entity
设为 non-movable,请添加已删除的 move-constructor 和 move-assignment 运算符:
Entity(Entity&& other) = delete;
Entity& operator= (Entity&& other) = delete;
考虑以下代码,实体对象是不可移动的。我知道 std::move(Obj) 只是将 Obj 转换为右值引用 Obj。而且我也知道右值引用变量仍然是一个左值对象。但是我还是很困惑为什么语句auto temp = std::move(a)
可以调用拷贝构造函数,语句a = std::move(b);
可以调用拷贝赋值运算符。因为,std::move(a) 是一个右值引用,为什么它仍然可以调用左值构造函数。
#include <iostream>
template<typename T>
void my_swap(T& a, T& b) {
auto temp = std::move(a);
a = std::move(b);
b = std::move(temp);
}
class Entity{
int _id;
public:
Entity(int id) :_id(id) {std::cout << "construtor\n" << std::endl;}
Entity(const Entity& other) {
_id = other._id;
std::cout << "copy constructor\n" << std::endl;
}
Entity& operator= (const Entity& other) {
if (&other == this) return *this;
this->_id = other._id;
std::cout << "copy assignment operator\n";
return *this;
}
};
int main() {
Entity e1 = Entity(10);
Entity e2 = Entity(20);
my_swap(e1,e2);
return 0;
}
Entity object is non-movable
没有。即使它没有 move constructor/assignment-operator,它也有 copy constructor/assignment-operator taking lvalue-reference to const。 std::move(a)
和 std::move(b)
是右值(xvalue)表达式,它们可以绑定到 lvalue-reference 到 const。
您还可以查看 std::is_move_constructible
:
Types without a move constructor, but with a copy constructor that accepts const T& arguments, satisfy std::is_move_constructible.
Considering the following code, Entity object is non-movable.
不,不是。 Entity
可移动
But I still confusing why statement auto temp = std::move(a)
对 const 的左值引用可以绑定到右值。复制构造函数接受对 const 参数的左值引用。该参数可以绑定到 std::move(a)
右值参数。
And I also know that rvalue reference variable is still a lvalue object.
不完全是。引用不是对象。 id-expression 命名任何东西,包括右值引用变量,是左值。
Entity is movable. Does is because there exists default move constructor/assignment-operator.
它是可移动的,因为它有一个复制constructor/assignment操作符,它没有删除移动constructor/assignment操作符。
如果您想将 Entity
设为 non-movable,请添加已删除的 move-constructor 和 move-assignment 运算符:
Entity(Entity&& other) = delete;
Entity& operator= (Entity&& other) = delete;