Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 构造函数未将此指针设置为const会导致未检测到的问题_C++_Constructor_Constants_This Pointer - Fatal编程技术网

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

C++ 构造函数未将此指针设置为const会导致未检测到的问题,c++,constructor,constants,this-pointer,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:

将我的类削减到最低限度以提高可读性:

#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
在定义
消息的
版本时,此代码可能会导致一些“问题”(尽管一切运行正常)。
消息
的构造函数不假定
指针的
const
。因此,即使
addToFolders
是一个非
const
函数,代码

Message a("hello");
Folder f;
a.save(f);
const Message b(a);
那就好了。这里存在一个问题,因为
b
是一条
const
消息,但是复制构造函数将
b
的地址(通过
addToFolders()
)设置到一个文件夹中,该文件夹由
消息的
集合
组成*
-低级
const
丢失。事实上,如果我在
文件夹
中定义一个函数来更改底层消息,我可以更改const Message
b
内容,看起来没有编译错误


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

您无法阻止构建
const
实例

如果你在构造器中使用
这个
,你就要适当小心了——例如,你可以显式地
将它转换成
常数*


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

我无法理解这个问题。然而,有一件事是肯定的——常量永远不会丢失,除非常量是特别铸造的。不管你走哪条路-如果某个东西被定义为常量,它将保持常量。你是对的,对象在构造时不是
const
。一旦
const
对象的生命周期开始(在构造函数之后),修改该对象的行为仍然是未定义的。但是你使用的
addToFolders
似乎有点可疑,尤其是因为你没有析构函数来再次删除它。@Alan Stokes我有一个析构函数,我会把它重新添加进去。为了可读性,我删除了很多。@AlanStokes,如果对象是const_cast,这只是一个未定义的行为。否则,它将定义良好,并导致编译错误。“我仍在试图理解这个问题,但我仍然无法理解。”SergeyA修改常量对象始终是未定义的行为,无论您如何实现它。此代码显示了一个不会生成编译错误的示例。(在
const X;
中,X的构造函数无法判断实例是否为const,并且可以在不进行任何强制转换的情况下获取非const指针或对其的引用。)
Message a("hello");
Folder f;
a.save(f);
const Message b(a);