c++ - 为什么在执行 std::move 时内存是新的

标签 c++ c++11

在这段代码中:

int main()
{
    std::vector<int> src{1, 2, 3};

    std::cout << "src: ";
    for (std::vector<int>::const_iterator x = src.begin(); x != src.end(); ++ x)
    {
        std::cout << *x << ' ' << &(*x) << std::endl ;
    }   

    std::vector<int> dest(std::move(src));

    std::cout << "src: ";                                                       
    for (std::vector<int>::const_iterator x = src.begin(); x != src.end(); ++ x)
    {
         std::cout << *x << ' ' << &(*x) << std::endl ;;
    }   
    std::cout << "\ndest: ";
    for (std::vector<int>::const_iterator x = dest.begin(); x != dest.end(); ++ x)
    {
        std::cout << *x << ' ' << &(*x) << std::endl ;;
    }   
    std::cout << '\n';
}

src: 1 0x43ea7d0
2 0x43ea7d4
3 0x43ea7d8
src: 
dest: 1 0x43ea7d0
2 0x43ea7d4
3 0x43ea7d8

这是有道理的,因为 dest 的内存地址现在是以前 src 的地址。

但是当我这样做的时候:

int main()
{
    std::vector<int> src{1, 2, 3};
    std::vector<int> dest(src.size());

    std::cout << "src: " << std::endl;
    for (std::vector<int>::const_iterator x = src.begin(); x != src.end(); ++ x)
    {
        std::cout << *x << ' ' << &(*x) << std::endl ;
    }   
    std::cout << "\ndest: " << std::endl;
    for (std::vector<int>::const_iterator x = dest.begin(); x != dest.end(); ++ x)
    {
        std::cout << *x << ' ' << &(*x) << std::endl ;
    }    
    std::cout << '\n';

    std::move_backward(src.begin() , src.end(), dest.end());

    std::cout << "src: " << std::endl;
    for (std::vector<int>::const_iterator x = src.begin(); x != src.end(); ++ x)
    {
        std::cout << *x << ' ' << &(*x) << std::endl ;
    }   
    std::cout << "\ndest: " << std::endl;
    for (std::vector<int>::const_iterator x = dest.begin(); x != dest.end(); ++ x)
    {
        std::cout << *x << ' ' << &(*x) << std::endl ;
    }    
    std::cout << '\n';
}

   src: 
1 0x41e0140
2 0x41e0144
3 0x41e0148

dest: 
0 0x41e0160
0 0x41e0164
0 0x41e0168

src: 
1 0x41e0140
2 0x41e0144
3 0x41e0148

dest: 
1 0x41e0160
2 0x41e0164
3 0x41e0168

为什么第二种情况地址不同?我以为 std::move 只是改变了指针,没有触及原始对象的内存

最佳答案

您的第一个代码示例移动 vector 本身。这会将源 vector 的内容移动到目标 vector ,而不触及包含的元素。

您的第二个代码示例创建了一个与源大小相同的新 vector (具有默认构造的元素),然后移动分配给这些元素。

当你使用一个元素类型来告诉你用它做了什么时,这就变得很明显了:

#include <iostream>
#include <vector>
#include <algorithm>


struct Thing {
    Thing() {}
    Thing & operator=(Thing &&) { std::cout << "Moved a thing" << std::endl; }
};


int main() {
    std::vector<Thing> source1(1);
    std::vector<Thing> source2(1);

    std::cout << "Move vector:" << std::endl;
    std::vector<Thing> vector_moved{std::move(source1)};

    std::cout << "-------------" << std::endl;

    std::cout << "Move elements:" << std::endl;
    std::vector<Thing> elements_moved{source2.size()};
    std::move_backward(source2.begin() , source2.end(), elements_moved.end());

    return 0;
}

Output :

Move vector:
-------------
Move elements:
Moved a thing

关于c++ - 为什么在执行 std::move 时内存是新的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44790105/

相关文章:

c++ - 将 NSDictionary 转换为 std::vector

数组中值的 C++ 实例? (直方图)

c++ - 使用句柄从 CreateProcess() 收集输出

c++ - 在连续内存中存储相同长度的字符串?

c++11 - 使用 std::mutex 而不是 boost::mutex 时出现未处理的异常

c++ - 使用常量内存使用的 xml 解析

c++ - map 和无序 map 有什么区别?

c++ - 如何 std::bind() 创建数据成员?

c++11 - 流的初始值设定项列表 (C++11)

c++ - 整数 vector 的 initializer_list 语法