Per*_*kie 25 c++ move-semantics c++11
move对象之后,新旧对象之间是否存在依赖关系?int main () {
int a = 100;
std::cout<<&a<<std::endl;
auto a_copy = a; // deduced as int
std::cout<<&a_copy<<std::endl;
auto a_move = std::move(a); // deduced as int
std::cout<<&a_move<<std::endl;
};
Run Code Online (Sandbox Code Playgroud)
输出:
0x7fffffffe094
0x7fffffffe098
0x7fffffffe09c
Run Code Online (Sandbox Code Playgroud)
Bar*_*rry 27
在这个例子中,没有区别.我们最终得到int的是价值为100的3 秒.但是不同的类型肯定会有所不同.例如,让我们考虑一下vector<int>:
std::vector<int> a = {1, 2, 3, 4, 5}; // a has size 5
auto a_copy = a; // copy a. now we have two vectors of size 5
auto a_move = std::move(a); // *move* a into a_move
Run Code Online (Sandbox Code Playgroud)
最后一个变量a_move取得了a内部指针的所有权.所以我们最终得到的a_move是一个大小为5的向量,但a现在是空的.它move比a更有效copy(想象一下,如果它是一个1000字符串的向量 - a_copy将涉及分配一个1000字符串的缓冲区并复制1000个字符串,但a_move只需指定几个指针).
对于其他一些类型,一个可能无效:
std::unique_ptr<int> a{new int 42};
auto a_copy = a; // error
auto a_move = std::move(a); // OK, now a_move owns 42, but a points to nothing
Run Code Online (Sandbox Code Playgroud)
对于许多类型,但没有区别:
std::array<int, 100> a;
auto a_copy = a; // copy 100 ints
auto a_move = std::move(a); // also copy 100 ints, no special move ctor
Run Code Online (Sandbox Code Playgroud)
更普遍:
T a;
auto a_copy = a; // calls T(const T& ), the copy constructor
auto a_move = std::move(a); // calls T(T&& ), the move constructor
Run Code Online (Sandbox Code Playgroud)
在该示例中,默认副本和std :: move之间有什么区别?
没有区别.复制某些内容满足移动的要求,对于内置类型,移动实现为副本.
移动后,对象是新旧之间的依赖关系
不,没有依赖关系.两个变量都是独立的.
为了扩展其他发帖人的答案,move-is-a-copy 范式也适用于由 POD 类型组成(或由 POD 类型组成的其他类型组成)的所有数据结构,如下例所示:
struct Foo
{
int values[100];
bool flagA;
bool flagB;
};
struct Bar
{
Foo foo1;
Foo foo2;
};
int main()
{
Foo f;
Foo fCopy = std::move(f);
Bar b;
Bar bCopy = std::move(b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在两者的情况下Foo,Bar没有有意义的方式将数据从一个移动到另一个,因为两者最终都是 POD 类型的聚合 - 它们的数据都不是间接拥有的(指向或引用其他内存)。因此,在这些情况下,移动将作为副本实现,而原件 ( f, b) 在行上的分配之后保持不变std::move()。
移动语义只能通过动态分配的内存或独特的资源来有意义地实现。
| 归档时间: |
|
| 查看次数: |
9710 次 |
| 最近记录: |