2009-12-27 98 views
7

我遇到const成员函数的两个说明约const成员函数

class A{ 
    public: 
    ... 
    void f() const {} 
    ... 
} 
  1. 这意味着它只能访问恒定成员;
  2. 这意味着它不会修改任何成员;

我认为第二个是正确的。但为什么第一个出来?有什么要澄清的吗?

谢谢!

+1

你的C++书是怎么说的? – 2009-12-27 16:42:11

+6

这个网站**是我的C++书! – 2009-12-27 17:42:14

+0

他们都是正确的。在一定程度上(见下文)。 – 2009-12-27 19:36:15

回答

18

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

这条规则有一些例外。您还可以更改可变的变量在一个const成员函数,例如宣布这样一个成员变量:

mutable float my_rank; 

您还可以通过const_cast'ing一个参考给自己这样的破坏const,正确性类:

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

虽然技术上允许使用C++,但这通常被认为是不好的形式,因为它会抛弃设计的所有const修饰符。不要这样做,除非你真的必须这样做,并且如果你发现自己不得不这么做,那就意味着你的设计存在问题。 C++ FAQ涵盖了这一点。

这里有情况下,两个引用您希望做更多阅读:

5

在一个简单的意思,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函数中更改可变数据成员。

1

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

2

它们都是正确的。

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

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

詹姆斯以上还提到可变成员。
所以我也应该在这里介绍。

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

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

另外詹姆斯提到上面使用const_cast抛弃了常量。

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

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

+0

我认为你读第一个问题比我不同。提出的定义是“它只能访问常量成员”。一个const成员函数可以访问非常量成员,只要它不改变它们的状态,所以定义是不正确的。 – 2009-12-28 01:49:41

+0

@詹姆斯。请让你的陈述更清楚。一个const方法可以读取任何成员变量。但是只能调用const成员方法。我认为很明显,原来的问题刚刚有一些细节混杂在一起。 – 2009-12-28 04:19:52

+0

不用担心,虽然有2个具体的例子。将拿出所有的意见,并开始支持媒体渠道展示琐碎的观察。谁知道,也许我会开始看到每辆车的专用车道,而不是一条单一的道路。 – 2009-12-29 11:34:50