自分配保护 我正在阅读拷贝控制,在C++入门书中遇到了以下的示例(第13.4章)。p>
我的问题是关于自分配保护 我正在阅读拷贝控制,在C++入门书中遇到了以下的示例(第13.4章)。p>,c++,assignment-operator,C++,Assignment Operator,我的问题是关于remove_from_Folders()内部副本分配运算符: 如果我们先做remove_from_Folders(),在自我分配的情况下,不会将其文件夹清除()清除rhs的数据成员并导致故障 该类定义为: 类消息{ 朋友类文件夹; 公众: //文件夹隐式初始化为空集 显式消息(const std::string&str=“”): 内容(str){} //复制控件以管理指向此消息的指针 Message(const Message&);//复制构造函数 消息和运算符=(常量消息&);
remove_from_Folders()代码>内部副本分配运算符:
如果我们先做remove_from_Folders()代码>,在自我分配的情况下,不会将其文件夹清除()代码>清除rhs的数据成员并导致故障
该类定义为:
类消息{
朋友类文件夹;
公众:
//文件夹隐式初始化为空集
显式消息(const std::string&str=“”):
内容(str){}
//复制控件以管理指向此消息的指针
Message(const Message&);//复制构造函数
消息和运算符=(常量消息&);//复制分配
~Message();//析构函数
//从指定文件夹的邮件集中添加/删除此邮件
作废保存(文件夹&);
作废删除(文件夹&);
私人:
std::string contents;//实际消息文本
std::set folders;//包含此消息的文件夹
//复制构造函数、赋值和析构函数使用的实用程序函数
//将此消息添加到指向该参数的文件夹中
无效添加到文件夹(const Message&);
//从文件夹中的每个文件夹中删除此邮件
void从_文件夹中删除_();
};
上面列出的sampe代码更适合处理运算符=(self)
是的,在发生自赋值时,赋值操作符似乎会按照您所说的做。在我看来,这是一个bug,尽管源代码评论如此;创建一个临时复制和交换(这也是异常安全的)看看这个:这似乎是一个很好的候选人,因为我正在读同一本书,刚刚进入复制控制章节。我也在问自己同样的问题。。所以这是一个错误,不是吗?有人能解释为什么这个答案被否决了吗?如果有人想保留文件夹,它很短,不言自明,并且只添加一行代码。在从文件夹中删除文件夹()中的clear(),即使对类消息的进一步修改使情况复杂化,它仍然有效并继续工作。
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();
}
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();
};
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;
}