const常量应该传播给成员指针指针吗?

时间:2012-09-13 16:35:50

标签: c++ pointers coding-style const

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

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

感谢任何建议。

3 个答案:

答案 0 :(得分:3)

您基本上有两种选择:

深度常量:

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; }
};

这完全取决于你,以及你班级的目的。如果类是一个智能指针,那么使用浅的constness语义似乎是合理的,因为该类应该尽可能与原始指针相似(并且你当然可以有一个指向非常量指针的常量原始指针) )。

否则,您应该问自己为什么要公开对成员指针对象的访问权限。您当然可以通过对类的不断引用来提供可变访问,但我想这些是特殊且罕见的情况。首先,代码中应该没有那么多原始指针。通过解除引用指针返回一个深度const引用应该没问题,但通常是更好的封装“getter”函数,它隐藏了类中有一个指针的事实,如T const & get() const { return *ptr; }

答案 1 :(得分:2)

一般来说,是的。它具有欺骗性,可以修改你声明不变的东西,即使你可以做到这一点。

如果有人使用你的代码并看到const,他们会期望const。修改虽然对你很敏感,但可能会导致严重的问题 - 甚至会导致程序崩溃。

答案 2 :(得分:0)

考虑std::vector<Blah>成员与用于实现动态数组的Blah*成员。通常,用前者替换后者是有意义的。使用Blah* memeber,允许const方法修改数组中的数据,而使用std::vector<Blah>成员时,const方法不允许修改数据。< / p>

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

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

在第一个示例中,使用成员数组,const完全是关于表达设计级别约束,但在第二个示例中,使用赋值代理,const完全是关于表达编码级别约束

然而,这些用法并非不相容。关键的想法是为代码的读者提供尽可能多的约束(因为这极大地减少了必须考虑理解或处理代码的不同事物的数量)。 Upshot:在任何地方添加const