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

问题描述 投票:0回答:3

我有一个简单的例子:

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;
};

谢谢

c++ move rvalue
3个回答
2
投票

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

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


1
投票

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

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

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

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

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


0
投票

您不需要需要提供移动分配运算符,但是如果您不提供,则呼叫确实会降级为副本。

© www.soinside.com 2019 - 2024. All rights reserved.