保护再次自我分配

mod*_*ler 5 c++ assignment-operator

我正在阅读有关复制控制的内容,并在C++ Primer(第13.4章)一书中看到了以下示例.

我的问题是关于remove_from_Folders();内部复制赋值运算符:
如果我们首先这样做remove_from_Folders();,在自我赋值的情况下,它不folders.clear();清除rhs的数据成员并导致失败?

Message& Message::operator=(const Message &rhs)
{
 // handle self-assignment by removing pointers before inserting them
 remove_from_Folders();  // update existing Folders
 contents = rhs.contents; // copy message contents from rhs
 folders = rhs.folders;  // copy Folder pointers from rhs
 add_to_Folders(rhs);  // add this Message to those Folders
 return *this;
}

// remove this Message from the corresponding Folders
void Message::remove_from_Folders()
{
 for (auto f : folders) // for each pointer in folders
     f->remMsg(this);  // remove this Message from that Folder
 folders.clear();
}
Run Code Online (Sandbox Code Playgroud)

该类定义为:

class Message {
 friend class Folder;
public:
 // folders is implicitly initialized to the empty set
 explicit Message(const std::string &str = ""):
 contents(str) { }
 // copy control to manage pointers to this Message
 Message(const Message&);  // copy constructor
 Message& operator=(const Message&); // copy assignment
 ~Message();  // destructor
 // add/remove this Message from the specified Folder's set of messages
 void save(Folder&);
 void remove(Folder&);
private:
 std::string contents;  // actual message text
 std::set<Folder*> folders; // Folders that have this Message
 // utility functions used by copy constructor, assignment, and destructor
 // add this Message to the Folders that point to the parameter
 void add_to_Folders(const Message&);
 // remove this Message from every Folder in folders
 void remove_from_Folders();
};
Run Code Online (Sandbox Code Playgroud)

wkl*_*ang 1

https://github.com/Mooophy/Cpp-Primer/tree/master/ch13

上面列出的示例代码更适合处理operator=(self)

Message& Message::operator=(const Message &rhs) {
    if (this != &rhs) { // self-assigment check is necessary
                        // while remove_from_Folders() do folders.clear()
        remove_from_Folders();    // update existing Folders
        contents = rhs.contents;  // copy message contents from rhs
        folders = rhs.folders;    // copy Folder pointers from rhs
        add_to_Folders(rhs);      // add this Message to those Folders
    } 
    return *this;
}
Run Code Online (Sandbox Code Playgroud)