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

时间:2017-06-27 21:19:57

标签: 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只更改指针,而不触及原始对象的内存

1 个答案:

答案 0 :(得分:3)

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

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

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

#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
相关问题