切割我的課的最低性能的可讀性:構造函數不是這個指針設置爲const導致漏檢問題
#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
的構造函數不會假設this
指針的const
。因此,即使addToFolders
是非const
函數的代碼
Message a("hello");
Folder f;
a.save(f);
const Message b(a);
將彙編的罰款。這裏有一個問題,因爲b
是const
消息,但複製構造函數將b
的地址(通過addToFolders()
)設置爲由set
,Message*
組成的文件夾 - 低級const
丟失。事實上,如果我然後在Folder
中定義了一個函數,它改變了底層消息,我可以改變常量消息b
的contents
,看起來沒有編譯錯誤。
解決方法是將Folder
的集合更改爲set<const message*>
,但這樣做不允許我通過文件夾更改消息(這實際上是我所希望的)。我如何防止創建message
的const對象,或者更好的辦法是強制this
指針在構造函數中是const
,這樣addToFolders()
會失敗?
我無法得到很多的問題。然而,有一點是肯定的 - const永遠不會丟失,除非特別是const_cast。無論你走哪條路都無所謂 - 如果某事被定義爲const,它將保持爲const。 – SergeyA
你說的對象在構建時不是'const'。一旦它的生命週期開始(在構造函數之後),修改一個'const'對象仍然是未定義的行爲。但是,對addToFolders的使用似乎是可疑的 - 特別是因爲你沒有析構函數來重新刪除它。 –
@Alan Stokes我有一個析構函數,我將它添加回去。爲了便於閱讀,我刪除了很多。 – AntiElephant