将左值引用分配给左值时会发生什么?

时间:2019-10-14 11:32:27

标签: c++ move rvalue

我有一个简单的例子:

void Message::move_Folders(Message *m) {
    m_folders = std::move(m->m_folders);
    for (auto f : m_folders) {
        f->removeMessage(m);
        f->addMessage(this);
    }
    m->m_folders.clear();
}

此功能可以将“文件夹”成员从一个移动到另一个。所以我想知道:我需要为“文件夹”提供移动分配功能吗?

folders &operator=(folders &&f) {
    ...
}

将左值引用分配给左值时会发生什么?它仍然是复制操作吗? (我相信不会。)

注意:文件夹是文件夹对象的集合。一条消息可能属于多个文件夹。因此,一条消息包含一组文件夹。该文件夹还具有成员messages。一个文件夹可能包含许多消息。有点复杂。

这是MessageFolder的定义:

class Message {
public:
// constructor and destructor
...
private:
    std::set<Folder *> m_folders;
...
};

class Folder {
friend class Message;
//constructor and destructor
...
private:
    std::set<Message *> m_messages;
};

谢谢

3 个答案:

答案 0 :(得分:2)

请注意,std::move不会移动任何东西;而是使事物可移动。因此,为了将m->folders实际移到this->folders中,移动分配确实必须执行该逻辑。

实际上,该移动分配应该是定义移动语义的责任:move_folders方法不必清除m->folders,因为它不应该知道这一细节。

答案 1 :(得分:1)

是否需要提供用户定义的移动分配取决于您已经定义了哪些其他特殊成员,请参见图像进行组合: enter image description here

因此,如果Folders没有用户定义的析构函数,复制构造函数或赋值运算符,则移动构造函数和赋值将由编译器隐式声明。否则,您需要自己写一个。

  

将左值分配给左值时会发生什么?它仍然是复制操作吗? (我相信不会。)

这取决于您是否有移动分配,它会移动,否则会复制。

最后,您是否需要为Folder类的移动分配移动std :: set实际上为No,因为std :: set的移动分配不会使用默认分配器一一移动内容。

答案 2 :(得分:0)

不需要提供移动分配操作员,但如果您不这样做,则呼叫确实会降级为副本。