应将常量传播到成员指针指针

Should constness propagate to member pointer pointees?

本文关键字:指针 成员 传播 常量      更新时间:2023-10-16

我有一个成员函数,它被声明为const,并通过指针修改数据。这似乎有误导性。我应该删除const关键字吗?

我想知道其他人是如何在他们的代码中处理这种情况的。人们只是添加一条评论来澄清发生了什么吗?他们没有将const关键字添加到成员函数中吗?也许完全是别的东西?

欢迎提出任何建议。

您基本上有两个选择:

深度常量:

class Foo
{
    T * ptr;
public:
    T       & operator*()       { return *ptr; }
    T const & operator*() const { return *ptr; }
    T       * operator->()       { return ptr; }
    T const * operator->() const { return ptr; }
};

浅常量:

class Foo
{
    T * ptr;
public:
    T & operator*() const { return *ptr; }
    T * operator->() const { return ptr; }
};

这真的取决于你,也取决于你班的目的。如果该类是一个智能指针,那么使用浅常量语义似乎是合理的,因为该类应该尽可能类似于原始指针(当然,您可以使用一个指向非常量指针对象的常量原始指针)。

否则,您应该问问自己,为什么要公开对成员指针对象的访问。当然,您可能希望通过对类的常量引用来提供可变访问,但我认为这是特殊且罕见的情况。首先,代码中不应该有那么多原始指针。通过取消引用指针来返回深度const引用应该是可以的,但通常在封装更好的"getter"函数中,这些函数隐藏了类中存在指针的事实,如T const & get() const { return *ptr; }

一般来说,是的。修改你声明为常量的东西是欺骗性的,即使你可以这样做

如果有人使用了你的代码并看到了const,他们就会期待const。修改,即使对你来说是明智的,也可能会给它们带来严重的问题——甚至导致程序崩溃。

考虑用于实现动态数组的std::vector<Blah>成员与Blah*成员。大多数情况下,用前者取代后者是有意义的。对于Blah*成员,允许const方法修改数组中的数据,而对于std::vector<Blah>成员,不允许const方法修改其中的数据。

还可以考虑一个带有索引方法的矩阵类,该方法返回一个允许赋值给元素的代理。通过代理进行分配会更改矩阵,而不是代理对象本身。因此,代理对象;s的赋值运算符可以是(也应该是)const,以便对其效果施加尽可能多的约束,而它的主要工作是修改事物。

这;设计级别与编码级别不同的另一个例子。

在第一个示例中,对于成员数组,const完全是关于表达设计级别约束,但在第二个示例中(对于分配代理),const完全是关于表示编码级别约束。

然而,这些用法并非不兼容。关键思想是为代码的读者提供尽可能多的约束(因为这大大减少了理解或处理代码时必须考虑的各种因素)。热门话题:尽可能添加const