如果我有班级
class foo {
private:
std::shared_ptr<char> m_data;
public:
std::shared_ptr<const char> GetData()
{ return m_data;}
}
我相信std::shared_ptr< T >
应该转换为std::shared_ptr< const T >
并共享同一个对象,但该函数的const正确性是什么?
IE
这个有效吗?
std::shared_ptr<const char> GetData() const;
答案 0 :(得分:8)
该函数是否会修改对象的内部状态?不。*
该函数是否为其调用者(或其他外部环境)修改了对象内部状态的访问权限?否
这意味着可以将其标记为const
。
*注意:@Yakk在评论中正确地指出,对于“内部状态”的某些定义,该函数确实修改了它,因为它增加了char
所拥有的引用计数器。共享指针m_data
。你必须自己决定是否构成非常规操作;严格按照语言规则,它没有(因为它修改了shared_ptr
的指向的东西,而不是shared_ptr
本身。但是,由于您首先存储shared_ptr
,我认为您可以共享所有权,因此不应将其视为修改。
答案 1 :(得分:2)
你应该非常小心这样的代码。在您的代码处于此状态的状态下,一切都将是安全的,因为您只包装shared_ptr
并且没有人可以修改内容,因为它们是私有的。但是,如果扩展代码,则存在一个难以调试的微妙但严重的陷阱:如果添加修改shared_ptr
指向的数据的函数,那么已经拥有shared_ptr
的代码从const char
函数到GetData()
,您将看到已修改的数据,而不是数据的副本。
在C ++中,关键字const
实际上意味着只读,并且在他们第一次学习它时不会像许多人一样思考。使代码面向未来的一种方法是使用std::shared_ptr<char>
作为数据成员m_data
的数据类型。如果这不适合您的代码要求,请考虑在调用函数GetData()
时返回数据的完整副本。如果您有不良的性能限制,则可能需要实现写时复制,但除非您确定这些性能损失,否则应避免写入时复制,因为由于上述原因,它很棘手。