1

将我的课程减少到最低限度以提高可读性:

#ifndef MESSAGEFOLDER
#define MESSAGEFOLDER

#include <string>
#include <set>

class Message;

class Folder{
public: 
    void addMsg(Message* m) { messages.insert(m); } 
    ~Folder() { removeFromMessages(); }
private:
    std::set<Message*> messages;
    void removeFromMessages(); //removes its pointers from Messages
};

class Message{
    friend class Folder;
public:
    Message(const std::string &s = ""): contents(s) { }
    Message(const Message& rhs): contents(rhs.contents), folders(rhs.folders) { addToFolders(); }
    Message& save(Folder&); 
    ~Message() { removeFromFolders(); }
private:
    std::string contents;
    std::set<Folder*> folders;
    void addToFolders();
    void removeFromFolders(); //removes its pointers from Folders
};


#endif // MESSAGEFOLDER

在 MessageFolder.cpp 中

void Message::addToFolders(){
    for(const auto& f : folders)
        f->addMsg(this);
}

Message& Message::save(Folder& f){
    folders.insert(&f);
    f.addMsg(this);
    return *this;
}

在定义const. 的messages构造函数Message不假定指针。因此,即使是非功能代码constthisaddToFoldersconst

Message a("hello");
Folder f;
a.save(f);
const Message b(a);

会编译得很好。这里有一个问题,因为b是一条const消息,但是复制构造函数将b的地址(通过addToFolders())设置为由 a 组成的文件夹set-Message*低级别const丢失了。事实上,如果我要定义一个函数Folder来更改底层消息,我可以更改contentsconst Message的,b看似没有编译错误。

一个解决方案是将Folder' 设置更改为,set<const message*>但这不允许我通过文件夹更改消息(我确实希望这样做)。我将如何防止message创建 const 对象,或者更好的是,强制this构造函数中的指针const失败addToFolders()

4

1 回答 1

2

你不能阻止const实例被构造。

如果您this在构造函数中使用,则需要适当小心 - 例如,您可以将const_cast其显式设置为 a const *

通常,如果对象的管理不在对象自己的类中处理,则效果会更好。例如,您可以限制事物,以便只能通过 a 创建对象folderfolder然后可以确保正确处理它。(这实际上只是关注点分离的一个例子。)

于 2015-08-31T16:59:48.487 回答