为了可读性,将我的类缩减到最低限度:
#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
的构造函数不要假设 const
的 this
指针。所以即使addToFolders
是非 const
运行代码
Message a("hello");
Folder f;
a.save(f);
const Message b(a);
可以正常编译。这里有一个问题,因为 b
是 const
消息,但复制构造函数设置 b
的地址(通过 addToFolders()
)到由 set
组成的文件夹的 Message*
- 低级const
丢失了。事实上,如果我要在 Folder
中定义一个函数这改变了底层消息我可以改变contents
const 消息 b
似乎没有编译错误。
解决方案是更改 Folder
设置为 set<const message*>
但这不允许我通过文件夹更改消息(我确实希望这样做)。我将如何防止 message
的 const 对象正在创建,或者更好的是,强制 this
构造函数中的指针是 const
这样addToFolders()
会失败吗?
最佳答案
你不能阻止 const
实例的构造。
如果你在你的构造函数中使用this
,你需要适当小心——你可以显式地const_cast
它到一个const *
,例如。
一般来说,如果对象的管理不在对象自己的类中处理,效果会更好。例如,您可以限制对象只能通过 folder
创建,然后 folder
可以确保它得到正确处理。 (这实际上只是关注点分离的一个例子。)
关于c++ - 未将此指针设置为 const 的构造函数会导致未检测到的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32315950/