移动语义说明 [英] Move semantics clarification

查看:105
本文介绍了移动语义说明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读以下文章,该文章对移动语义有很好的了解:

I have read the below post which gives a very good insight into move semantics:

有人可以向我解释移动语义吗?

但是我仍然无法理解有关移动语义的以下内容-

but I am still fail to understand following things regarding move semantics -

  1. 在没有移动构造函数的情况下,复制省略和RVO是否仍适用于类?

  1. Does copy elision and RVO would still work for classes without move constructors?

即使我们的类没有移动构造函数,但STL容器也有一个.对于

Even if our classes doesn't have move constructors, but STL containers has one. For operation like

std :: vector vt = CreateMyClassVector();

std::vector vt = CreateMyClassVector();

并执行排序等操作.为什么STL不能在内部使用移动语义来通过不需要复制构造函数的复制省略或RVO等内部操作来改善此类操作?

and to perform operations like sorting etc. Why can't STL internally leverage move semantics to improve such operations internally using operations like copy elision or RVO which doesn't require move constructors?

3. 在以下情况下,我们会从移动语义中受益吗?

3. Do we get benefited by move semantics in below case -

std :: vector< int> vt1(1000000,5); //创建并初始化1百万个条目,其值为5

std::vector< int > vt1(1000000, 5); // Create and initialize 1 million entries with value 5

std :: vector< int> vt2(std :: move(vt1)); //将vt1移至vt2

std::vector< int > vt2(std::move(vt1)); // move vt1 to vt2

由于整数是原始类型,因此移动整数元素将不会提供任何优势. 或在执行移动操作后,此处vt2仅指向堆中的vt1内存,而vt1设置为null.实际发生了什么?如果是后者,则即使第2点也成立,我们可能不需要为类使用move构造函数.

as integer is a primitive type, moving integer elements will not offer any advantage. or here after move operation vt2 simply points to vt1 memory in heap and vt1 is set to null. what is actually happening? If latter is the case then even point 2 holds that we may not need move constructor for our classes.

4. 当使用std :: move在左值上调用push_back()时,例如:

4. When a push_back() is called using std::move on lvalue for e.g :

    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连续的内存区域,在这种情况下不会移动内存与复制内存一样好,如何通过简单地移动指向堆不同区域中的内存的指针,移动是否可以证明向量的连续内存需求??

now as vector has contiguous memory allocation, and obj is defined somewhere else in memory how would move semantics move the obj memory to vector vt contiguous memory region, wouldn't moving memory in this case is as good as copying memory, how does move justifies vectors contiguous memory requirements by simply moving a pointer pointing to a memory in different region of a heap.?

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

Thanks for explanation in advance!

推荐答案

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

Most semantics is not a way of moving memory. It's all about the transference of ownership of objects from one object instance to another. When you do this:

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

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

std::string allocates and manages a buffer of characters. Therefore, each std::string owns a buffer of memory, which contains the string itself.

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

The move constructor called to construct str2 will take the character buffer allocated by str1 and remove it from that object. Thus str2 now has the pointer that str1 originally allocated, and str1 doesn't have that pointer anymore. That's what move semantics is all about: transferring ownership of memory owned by an object.

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

If your class does not have a move constructor, std::vector will not call it. Obviously. Therefore, it cannot take advantage of any potential optimizations that having a move constructor might bring. But these optimization opportunities only exist for objects which have value semantics and which contain resources that must be managed. Otherwise, movement doesn't help you.

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

The general rule is to use smart pointers and container objects like vector, string, and the like to avoid having to write move constructors at all. Thus, (if your compiler properly supports generating move constructors) resource management happens automatically.

这篇关于移动语义说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆