关于c ++:move语义澄清

Move semantics clarification

本问题已经有最佳答案,请猛点这里访问。

我读过下面的文章,它对移动语义有很好的理解:

Can someone please explain move semantics to me?

但是我仍然不理解下面关于移动语义的内容-

  • 在没有移动构造函数的情况下,copy elision和rvo是否仍然适用于类?

  • 即使我们的类没有move构造函数,但stl容器有一个。用于类似操作

  • std::vector vt=createMyclassVector();

    为了执行诸如排序等操作,为什么STL不能在内部利用移动语义,使用不需要移动构造函数的复制省略或rvo之类的操作在内部改进这种操作?

    三。在下面的案例中,我们是否受益于移动语义?-

    std::vectorvt1(1000000,5);//创建并初始化100万个值为5的条目

    std::vectorvt2(std::move(vt1));//将vt1移动到vt2

    由于integer是一种基元类型,因此移动integer元素不会提供任何优势。或者,在移动操作之后,vt2只指向堆中的vt1内存,vt1设置为空。到底发生了什么?如果是后者,那么第2点也认为我们可能不需要为类移动构造函数。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        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连续的内存区域,在这种情况下,移动内存是否与复制内存一样好,move如何通过简单地移动指向mem的指针来调整向量的连续内存需求?在堆的不同区域。

    感谢您提前解释![按要求编辑问题。]


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

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

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

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

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

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