移动语义澄清

时间:2013-01-30 12:09:05

标签: c++ c++11 move-semantics

我已经阅读了以下帖子,它非常了解移动语义:

  

Can someone please explain move semantics to me?

但是我仍然无法理解关于移动语义的一些事情 -

  1. 复制elision和RVO是否仍适用于没有移动构造函数的类?

  2. 即使我们的类没有移动构造函数,但STL容器也有。适用于

  3. 等操作

    std :: vector vt = CreateMyClassVector();

    并执行排序等操作。为什么STL内部不能使用移动语义来在内部使用不需要移动构造函数的copy elision或RVO等操作来改进这些操作?

    3。 在下面的情况下,我们是否会受到移动语义的影响 -

    的std ::矢量< int> vt1(1000000,5); //创建并初始化值为5的100万个条目

    的std ::矢量< int> VT2(标准::移动(VT1)); //将vt1移动到vt2

    由于整数是基本类型,移动整数元素不会提供任何优势。 或者在移动操作之后,vt2只指向堆中的vt1内存,并且vt1设置为null。究竟发生了什么?如果是后一种情况,那么即使是第2点也认为我们的类可能不需要移动构造函数。

    4。  当使用std :: move on lvalue调用push_back()时,例如:

        std::vector<MyClass> vt;
    
        for(int i=0; i<10; ++i)
        {
            vt.push_back(MyClass());
        }
    
        MyClass obj;
    
        vt.push_back(std::move(obj));
    

    现在因为向量具有连续的内存分配,并且obj被定义在内存中的其他位置如何移动语义将obj内存移动到向量vt连续的内存区域,在这种情况下移动内存不会像复制内存一样好,如何通过简单地移动指向堆的不同区域中的内存的指针来移动证明向量连续的内存需求。

    感谢提前解释! [根据要求编辑了问题。]

1 个答案:

答案 0 :(得分:3)

大多数语义不是移动内存的一种方式。这是关于将对象的所有权从一个对象实例转移到另一个对象实例的全部内容。当你这样做时:

std::string str1("Some string.");
std::string str2(std::move(str1));

std::string分配和管理字符缓冲区。因此,每个std::string 拥有内存缓冲区,其中包含字符串本身。

调用构造str2的移动构造函数将获取str1分配的字符缓冲区,并将其从该对象中删除。因此,str2现在具有str1最初分配的指针,str1不再具有该指针。这就是移动语义的全部意义:转移对象拥有的内存所有权。

如果您的班级没有移动构造函数,std::vector将不会调用它。明显。因此,它无法利用具有移动构造函数可能带来的任何潜在优化。但是这些优化机会存在于具有值语义且包含必须管理的资源的对象。否则,运动对你没有帮助。

一般规则是使用智能指针和容器对象,如vectorstring等,以避免必须编写移动构造函数。因此,(如果您的编译器正确支持生成移动构造函数),资源管理会自动发生。