我遇到了const成员函数的两个解释
class A{
public:
...
void f() const {}
...
}
我认为第二个是正确的。但为什么第一个出来呢?有什么需要澄清的吗?
谢谢!
答案 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成员函数不能改变对象的状态。
詹姆斯上面也提到了可变成员 所以我也应该介绍这些。
可变成员变量是一个不属于对象状态的变量(编译器不认为它是对象状态的一部分)。你也应该这样对待它。保存有关对象的状态信息的任何成员变量应 NOT 标记为可变。您应该只使用它来保存可以从对象状态重新构造的临时信息。
一个简单的例子是日期时间对象。对象具有将数据/时间转换为可读字符串格式的方法。为了提高效率,可以将此字符串缓存在可变成员的对象中(这样您就不需要重复构建字符串)。但是字符串不是对象状态的一部分(因为它可以从其他成员构建)。
James也提到上面使用 const_cast 来消除常量。
除非在非常特殊的情况下,你知道对象不能 const这样做被认为是一个坏主意。因为它直接导致未定义的行为。如果你发现自己需要抛弃constness,那么你的程序中的设计就会出现一些非常错误。
事实上,我只能想到一种正常情况发生的情况。然后,我不愿意在不进行研究的情况下将其提交给代码,以确保我看起来不傻。
答案 3 :(得分:1)
我认为在一些澄清之后的情况1可能涉及到你有一个类型A的const对象的情况。在这种情况下,你只能在这种情况下调用它的成员函数声明为const,如f()。因此,根据您的帖子,您必须假设'它'是const A类型对象上成员函数的调用者。也许您应该检查您发现的定义时考虑到这个假设。