关于const成员函数

时间:2009-12-27 16:29:17

标签: c++ const const-correctness

我遇到了const成员函数的两个解释

class A{
  public:
  ...
  void f() const {}
  ...
}
  1. 这意味着它只能访问常量成员;
  2. 表示不会修改任何成员;
  3. 我认为第二个是正确的。但为什么第一个出来呢?有什么需要澄清的吗?

    谢谢!

4 个答案:

答案 0 :(得分:18)

您可以检查const成员函数中的所有类成员值,在某些情况下甚至可以更改成员变量的值。第一个解释是不正确的,我不知道它来自哪里。第二种解释是正确的,但有一些例外。

此规则有一些例外情况。您还可以在const成员函数中更改可变变量,例如,声明为此的成员变量:

mutable float my_rank;

你也可以通过const_cast'引用你自己来破坏类中的const-correctness:

Class* self = const_cast<Class*> (this);

虽然在C ++中技术上允许,但这通常被认为是糟糕的形式,因为它抛弃了设计的所有const修饰符。除非你真的需要,否则不要这样做,如果你发现自己不得不这么做,这表明你的设计存在问题。 C++ FAQ很好地涵盖了这一点。

如果您想要阅读更多内容,请参阅以下两个参考资料:

答案 1 :(得分:5)

简单来说,在const函数中,您无法更改对象的状态。

在const函数中,此指针表现为 const指向const数据的指针,其中非const函数的行为类似于 const指向数据的指针

void foo() const  --> const ClassName * const this (so you can't alter data)

void foo() --> ClassName * const this (so you can alter data)

就const数据成员而言,您可以从任何成员函数访问(读取)它是否为const。

正如詹姆斯·汤普森所表明的那样,如果你愿意的话,你甚至可以通过删除常数来改变对象的状态。

class Bar
{
    int bar;
    public:
     void foo() const
     {
        this->bar = 0; //flashes error 

        Bar * const thisClass = const_cast<Bar * const>(this);
        thisClass->bar = 0;  
     }
};

还可以在const函数中更改可变数据成员。

答案 2 :(得分:2)

他们都是正确的。

const成员函数不能改变对象的状态

  • 这意味着它可以读取(但不能修改)所有成员变量。
  • 这也意味着它只能调用其他const成员函数
    保证不改变对象状态的其他方法。

詹姆斯上面也提到了可变成员 所以我也应该介绍这些。

可变成员变量是一个不属于对象状态的变量(编译器不认为它是对象状态的一部分)。你也应该这样对待它。保存有关对象的状态信息的任何成员变量应 NOT 标记为可变。您应该只使用它来保存可以从对象状态重新构造的临时信息。

一个简单的例子是日期时间对象。对象具有将数据/时间转换为可读字符串格式的方法。为了提高效率,可以将此字符串缓存在可变成员的对象中(这样您就不需要重复构建字符串)。但是字符串不是对象状态的一部分(因为它可以从其他成员构建)。

James也提到上面使用 const_cast 来消除常量。

除非在非常特殊的情况下,你知道对象不能 const这样做被认为是一个坏主意。因为它直接导致未定义的行为。如果你发现自己需要抛弃constness,那么你的程序中的设计就会出现一些非常错误。

事实上,我只能想到一种正常情况发生的情况。然后,我不愿意在不进行研究的情况下将其提交给代码,以确保我看起来不傻。

答案 3 :(得分:1)

我认为在一些澄清之后的情况1可能涉及到你有一个类型A的const对象的情况。在这种情况下,你只能在这种情况下调用它的成员函数声明为const,如f()。因此,根据您的帖子,您必须假设'它'是const A类型对象上成员函数的调用者。也许您应该检查您发现的定义时考虑到这个假设。