c++ - 未将此指针设置为 const 的构造函数会导致未检测到的问题

标签 c++ constructor constants this-pointer

为了可读性,将我的类缩减到最低限度:

#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 的构造函数不要假设 constthis指针。所以即使addToFolders是非 const运行代码

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

可以正常编译。这里有一个问题,因为 bconst消息,但复制构造函数设置 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/

相关文章:

c++ - OpenCV 3.x 仅包含一个库 - o​​pencv_world.lib?

c++ - 为什么 fstream.open() 失败 "If the mode has both trunc and app set"?

c++ - 是否可以使用未定义为 const 的工厂方法来定义 const 成员?

c - 如何在 C 中声明常量数组参数?

c++ - 使用 shared_ptr 进行条件构造?

c++ - 有没有办法告诉 openmp 共享数据是不变的?

c++ - MD5代码覆盖率

c++ - 这是 struct hack 的 C++ 替代品吗?

c++ - 在派生构造函数中调用基方法的坏习惯?

C++11 数组初始化不会调用复制构造函数