> ## Content Index
> Fetch the complete content index at: https://andybase.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# std::move
- URL: https://andybase.com/move/
- Published: 2019-05-21T01:50:28.000Z
- Updated: 2019-05-21T01:50:28.000Z
- Author: andy
- Tags: c++, 技术, #Migrated-1784083136856, #wp, #wp-post, #Import 2026-07-15 02:38

> 21天是肯定没法学会C++的。22天也不行。

C++11里引入了一个新的概念 ：*移动*。 这个概念说简单其实很简单，因为它是介于拷贝和引用之间的一种概念。但还是有很多小伙伴表示不理解*移动*到底做了什么，如何理解*移动*。

要想理解*移动*，先来介绍一个概念：左值与右值。

#### 左值与右值

笼统来讲，左值就是能够对其取地址的值。反之就是右值（临时变量也是右值）。比如`1`, `2.0`, `true`, `nullptr`这种纯值类型，就是妥妥的右值。再比如 `int a = 100;` ， `a`是左值，`100`是右值。在给`a`赋值的过程中，我们将**右值拷贝到了左值**。（其实并不是完全这样，编译器会做一定程度的优化，但为了方便理解，我们不考虑编译器的功劳）

#### 两个栗子

在早期C++里，我们通常用指针或者引用来传递一个*‌大*变量，因为可以避免一次拷贝的开销。第一个栗子：**如果我们有一个比较大的右值变量，我想将它传递给其他的函数，该如何避免/减少拷贝的开销呢？**比较熟悉的朋友可能会说，我们可以传递 `const &` 来避免拷贝的开销。

没错，在C++11 之前，`const &` 可以对右值直接取引用。这样我们可以传递引用来避免拷贝的开销。那么下一个栗子就是，**如果我们有一个比较大的右值变量，我想将它传递给其他的函数，*‌又想要修改这个右值变量的值*，该如何避免/减少拷贝的开销呢？**

C++11 提出了一个概念：右值引用。语法是两个&。 它允许我们对右值进行直接引用。

#### 移动

理解了右值之后，我们来思考一个问题。当我们进行赋值语句时，其实是构建了一个右值，然后复制给了左值。那么有没有花销更小的方法呢？答案就是*移动*。

熟悉C++的都知道C++中有构造方法。构造方法又有*拷贝构造*和*赋值构造*两种特殊的构造方法。C++11提出了新的构造类型：*移动构造*。也即方法接受的参数是一个右值，然后通过*移动*的方式，减少拷贝与销毁的开销，实现资源的转移。样式为： `Type::Type(Type && rval)`

另一个作用就是，`std::move`在移动的时候，**可以** 剥夺原变量的数据所有权。通常进行所有权转移时我们会显式调用`std::move` 方法。

以`vector`来举例。

```
vector<int> a {1,2,3,4,5};
for (auto i : a){
    cout << i<< ", ";   // --> 1, 2, 3, 4, 5   
}
vector<int> b  = move(a);

for (auto i : a){
    cout << i<< endl;   // Nothing, moved to b
}
cout << "----" <<endl;
for (auto i :b){
    cout << i<< ", ";   // --> 1, 2, 3, 4, 5   
}
```

#### 联通

C++ 11 中的移动语义使得我们在构造临时变量，减少构造与析构的消耗，并且可以显示表达所有权的转移。既增强了代码的运行效率，又增加了代码的可读性。

move不产生新变量，它只是c++的搬运工。