具有同一对象的 C++ 复制分配

C++ Copy assignment with same object

提问人:J.Doe 提问时间:10/17/2022 更新时间:10/17/2022 访问量:201

问:

在著名的C++入门书中,我找到了以下代码片段

Message& Message::operator=(const Message &rhs)
{
    // handle self-assignment by removing pointer before inserting them
    remove_from_Folders(); // updating 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;
}

Message 类:

class Message {
    friend class Folder;
public: 
    // folders is implicity 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; // Folder's 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();
}

void Message::save(Folder &f)
{
    folders.insert(&f); // add the given Folder to our list of Folders
    f.addMsg(this);     // add this Message to f's set of Messages
}

void Message::remove(Folder &f)
{
    folders.erase(&f); // take the given Folder out of our list of Folders
    f.remMsg(this);    // remove this Message to f's set of Messages
}

// add this Message to Folders that point to m
void Message::add_to_Folders(const Message &m)
{
    for (auto f : m.folders) // for each Folder that holds m
        f->addMsg(this); // add a pointer to this Message to that Folder
}

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();       // no Folder points to this Message
}

Message::~Message()
{
    remove_from_Folders();
}

现在我的问题是:我们看到整个文件夹集被清除了。我们还看到 copy-assignment 运算符中的参数是一个引用。那么,为什么召唤它,然后做它,在这里起作用呢?既然是引用,那么当我们使用同一个对象(即进行自我(复制)赋值)时,现在不会是空集吗?这不就是引用的工作方式吗?或者编译器在使用赋值运算符进行操作时是否满足了特殊规则?remove_from_Foldersrhsremove_from_Folders()folders = rhs.folders;rhsrhs.folders

C++ 逐个引用 运算符 复制赋值

评论

1赞 Nelfeal 10/17/2022
如果这就是所有代码,并且该类没有做任何奇怪的事情,那么是的,消息的成员在自赋值后将是空的。通常,复制赋值运算符会进行如下检查Folderfoldersif (&rhs == this) return;
0赞 J.Doe 10/17/2022
谢谢!我真的在质疑我对我从书中学到的东西的理解......我猜作者可能已经忘记了这句话。
0赞 Neil Butterworth 10/17/2022
如果不阅读这本书(我在第一版中就有这本书 - 不记得这一点)并了解问题域或有关 Folder 类的任何内容,很难评论/回答。
1赞 Paul Sanders 10/17/2022
@user4581301 这是一个有趣的想法(或一个assert)
1赞 user4581301 10/17/2022
@PaulSanders,我很惊讶我还能保持头脑清醒。当我按照我打算编写的方式编译它时,编译器会很快发现错误。assertabortabort

答: 暂无答案