繁体   English   中英

无法理解关于std :: move()的c ++入门

[英]failed to understand c++primer about std::move()

C ++ Primer一书中写道

必须认识到移动承诺,我们不打算再次使用rr1,除非分配给它或销毁它。

这是在线之后:

int &&rr3 = std::move(rr1);

怎么理解这句话? 调用std::move(rr1)后rr1有什么变化吗?

有人认为这个问题已经解决了什么是std :: move(),什么时候应该使用? 但我不同意。书中写道“我们可以摧毁一个移动的物体,并可以为它分配一个新值,但我们不能使用移动物体的值。”我不知道它是什么意味着“我们不能使用移动对象的值。”。是否有任何代码可以解释它?

那个特定的代码示例忽略了这一点。 std::move对它所应用的对象没有任何作用。 它只是一种不同的类型转换格式,它的作用是在重要的情况下指导重载解析。 例如:

void f(const my_type&);
void f(my_type&&);
my_type mm;
f(mm);            // calls f(const my_type&)
f(std::move(mm)); // calls f(my_type&&)

这很重要,因为采用右值引用的函数(在本例中为f(my_type&&) )通常会对其参数做一些讨厌的事情,以使其工作更容易。 例如, std::vector的复制构造函数会生成传递给它的参数的副本; 移动构造函数窃取参数的内部数组,将参数留空。 所以当你做std::vector<int> vec(std::move(other_vector)); 除了分配或破坏它之外,你不应该对other_vector做任何事情,这就是“规则”所说的。

代码示例的问题在于它对rvalue引用没有任何作用,因此,正如您所推断的那样,对象中没有任何内容发生更改,您可以继续使用它。 但这是对std::move的愚蠢使用,也是一个毫无意义的例子。

当对象在其中动态分配内存时,可以令人满意地理解move语义。

class MemoryBlock  
{
    public:
    MemoryBlock(size_t length) : _length(length), _data(new int[length])  
    {  
    }  

    // copy constructor.  
    MemoryBlock(const MemoryBlock& other) : _length(other._length), _data(new int[other._length])  
    {   
        std::copy(other._data, other._data + _length, _data);  
    }  

    // move copy constructor.  
    MemoryBlock(MemoryBlock&& other) : _data(nullptr), _length(0)  
    {  
        // Copy the data pointer and its length from the source object.  
        _data = other._data;  
        _length = other._length;  

        // Release the data pointer from the source object.
        other._data = nullptr;  
        other._length = 0;  
    }  

    // destructor.  
    ~MemoryBlock()  
    {  
        if (_data != nullptr)  
        {  
              delete[] _data;  
        }
        _length = 0;  
    }  

    private:  
    size_t _length; // The length of the resource.  
    int* _data; // The resource.  
};

// ok, 'a' has 20 byte memory inside it.
MemoryBlock a(20); 

// we are literally transferring the memory from 'a' to 'b' by using move copy constructor.
MemoryBlock b = std::move(a); 

// so you broke the promise: "that we do not intend to use object 'a' again" after it has been moved. 
// a::_data is now null and code will break.
MemoryBlock c = a; 

//when object 'a' will go out of scope it can be destroyed properly
//this will work because the promise holds: "that object can be destroyed" after it has been moved.

//this will work, since you are copying the memory inside of 'd' to 'a' using normal copy constructor.
//so you obeyed the promise: "that we can assign to object 'a'" after it has been moved.
MemoryBlock d(30); 
MemoryBlock a = d;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM