为什么静态成员函数不能有const限定符?

108
今天我遇到了一个问题。我需要一个静态成员函数,最好是带有const修饰符的。但是,我尝试了很多次都没有成功。有人能告诉我为什么或者怎么做吗?

4
对你来说,一个 const 静态成员函数意味着什么? - GManNickG
2
@GMan 我的意思是一个静态成员函数,它不会改变任何输入参数。 - prabhakaran
12
你的输入(函数参数)应该传值或使用const引用。 - GManNickG
5
这不会影响成员函数参数的const属性。它的意思并不是“让所有东西都变成const”,而是“让this变成const”。 - UncleBens
1
@prab:针对你所询问的,是的。 - GManNickG
显示剩余3条评论
5个回答

173

当你将const限定符应用于非静态成员函数时,它会影响this指针。对于一个类C的const限定成员函数,this指针的类型是C const*,而对于一个没有const限定的成员函数,this指针的类型是C*

静态成员函数没有this指针(这样的函数不是在类的特定实例上调用的),因此对静态成员函数进行const限定没有任何意义。


这是否意味着 'const' 只适用于像 int、指针等变量? - prabhakaran
我忘记在上面添加这一行:“在实际检查了Steve Jessop(下面)的评论之后,我不得不说” - prabhakaran
8
“静态成员函数没有this指针……因此,将静态成员函数声明为const是没有意义的”这句话本身是正确的,但作为回答“为什么”的问题时就是错误的。这个回答假定const关键字对于静态成员和非静态成员是相同的含义。举个例子来说明这种思维方式是不正确的,那就是考虑static关键字的含义,它取决于上下文。 - Cheers and hth. - Alf
3
C const* 还是 const C* - crisron
1
@crisron 两者是相同的。在 C/C++ 中,无论你将 const 限定符放在最内层类型的左侧还是右侧都没有影响。 - Tyg13
显示剩余5条评论

30

我同意你的问题,但不幸的是C++就是被设计成那样的。例如:

class A {
  int i;         //<--- accessed with 'this'
  static int s;  //<---- accessed without 'this'
public:
  static void foo ()  const // <-- imaginary const
  {}
};
截至今日,constthis 上下文中被视为是狭义的。可以通过将此 const 应用于this 指针以外的地方来使其更加广泛。
即所谓的“建议性”const,也可能适用于static函数,将会限制static成员的任何修改。

在示例代码中,如果可以使foo() 成为const,那么在该函数中,A::s 将无法被修改。如果这个规则被添加到标准中,我没有看到任何语言副作用。相反,有趣的是,为什么不存在这样的规则!


9
可能的原因和你不能将一个自由函数的const修改为“此函数不修改任何全局变量”的原因相同。const适用于对象(在const成员函数的情况下,是调用它的实例)。你想让它应用于类的所有静态成员,我猜想如果委员会考虑过这个问题,那么他们可能认为这不是一个足够常见的需求来支持。 - Steve Jessop
1
const修饰符不适用于成员方法或成员变量,而是用于隐式的this指针。由于静态成员方法不绑定到对象,因此没有this指针可以使用const - Ruud Althuizen

1
很遗憾,按照设计,C++不接受它,但从逻辑上讲,在某些使用情况下,它是有效的。 一个在类级别上有效(静态)的函数可能不会改变任何静态数据,它只是查询数据应该是const。也许应该像这样:
if(Object)
    MakeThisConstant()
else
    MakeStaticDataConstant() // Only in the scope but static data cannot be constant so may be it should in some scenarios

0
“常量成员函数”不允许修改其被调用的对象,但静态成员函数不针对任何对象进行调用。它直接由作用域解析运算符使用。因此,拥有一个常量静态成员函数是没有意义的,因此是非法的。

静态常量在类中定义时,具有良好的作用域绑定,或者为全局私有字段提供getter方法。 - Netch

0

不细讲,这是因为函数可能会或者可能不会修改对象,因此 const 对编译器来说是有歧义的。

回想一下,const 用于保持对象常量,但在这里可能会或者可能不会有对象需要被保持常量。


2
“可能或可能不”?静态成员函数从不具有this指针。(此外,“const”并不能使对象保持不变。它防止使用特定的指针或引用来修改对象,但仍可能通过另一条路径进行修改) - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接