当使用C++的移动语义时,内存中会发生什么?

问题描述 投票:0回答:1

我试图理解C++的移动语义、移动构造函数、移动赋值运算符、std::move()。 让我们考虑以下示例:

#include <iostream>

void swapWithMove(int& a, int& b) {
    int temp = std::move(a);
    a = std::move(b);
    b = std::move(temp);
}

int main() {
    int x = 5;
    int y = 10;

    std::cout << "Before swap: x = " << x << ", y = " << y << std::endl;

    swapWithMove(x, y);

    std::cout << "After swap: x = " << x << ", y = " << y << std::endl;

    return 0;
}

此示例通过 std::move() 交换两个整数值。我知道该示例更多地用于教育目的,并不是移动语义的典型用例。 但是,我仍然想正确理解当执行 swapWithMove 函数时,内存中 x、y、temp、a 和 b 发生了什么。

提前非常感谢您!

c++ c++11 move swap move-semantics
1个回答
0
投票

在这种情况下(交换

int
s),移动语义根本不会产生任何区别,对于我所知道的任何实现(例外会有些令人惊讶)。

当我们处理像

vector

 这样的东西(主要)存储指向它所包含的数据的指针时,
移动语义很大程度上会发挥作用。例如,让我们考虑一下
std::vector
的稍微简化的实现:

template <class T>
class vector {
    T *data;
    std::size_t size_allocated;
    std::size_t size_in_use;
// ...

这里需要注意的一件大事是

vector
结构本身不包含任何真实数据。它只包含一个指向数据的指针,该数据在其
Allocator
对象获取它的任何地方进行分配(但通常使用标准分配器,它从空闲存储中获取内存。

无论如何,让我们考虑一下我们的

vector
的作业:

vector &operator=(vector const &other) {
    if (size_allocated < other.size_allocated) {
        // reallocate our storage so we have enough room
    }
    for (int i=0; i<other.size_in_use; i++)
        data[i] = other.data[i];
    return *this;
}

这简化了很多,但你得到了总体思路——逐步遍历所有元素,并将每个元素从旧向量复制到新向量。

但是,如果右边的是

rvalue
,则意味着我们不需要保留其内容。所以我们可以“窃取”它包含的内容:

vector &operator=(vector &&other) {
    delete [] data; // simplified--really uses allocator object
    data = other.data;
    size_in_use = other.size_in_use;
    size_allocated = other.size_allocted;
    other.data = nullptr;
    other.size_allocated = 0;
    other.size_in_use = 0;
    return *this;
}

因此,我们不是单独复制每个元素,而是从源中获取指针,并将源转换为空向量。速度非常快,无论其大小如何。不过,我们可以通过一种稍微棘手的方法来简化它:

vector &operator=(vector &&other) {
    swap(data, other.data);
    swap(size_in_use, other.size_in_use);
    swap(size_allocated, other.size_allocated);

    return *this;
}

只需将我们的内容与其他人的内容交换即可。然后它会被销毁,然后我们的内容就会被处理掉。

无论如何:移动

int
通常与普通作业没有什么不同。与大多数其他标量类型相同(
char
short
long
double
float
、指针等),结构化类型会出现差异,尤其是那些主要包含指向实际数据的指针的类型他们储存。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.