Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
自分配保护 我正在阅读拷贝控制,在C++入门书中遇到了以下的示例(第13.4章)。p>_C++_Assignment Operator - Fatal编程技术网

自分配保护 我正在阅读拷贝控制,在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;
}