为什么const成员函数可以修改静态数据成员?

msc*_*msc 82 c++ static const function c++11

在以下C++程序中,从函数修改静态数据成员const工作正常:

class A 
{
  public:   
    static int a; // static data member

    void set() const
    {
        a = 10;
    }
};
Run Code Online (Sandbox Code Playgroud)

但是从函数修改非静态数据成员const不起作用:

class A 
{
  public:   
    int a; // non-static data member

    void set() const
    {
        a = 10;
    }
};
Run Code Online (Sandbox Code Playgroud)

为什么const成员函数可以修改static数据成员?

Bat*_*eba 96

这就是规则,就是这样.并且有充分的理由.

const成员函数上的限定符意味着您无法修改mutable非非static类成员变量.

通过提供一些合理化,限定成员函数中的this指针const是一种const类型,并且this本质上与类的实例相关.static成员与类实例无关.您不需要实例来修改static成员:在您的情况下,您可以通过编写来执行此操作A::a = 10;.

所以,在你第一种情况下,想到的a = 10;是简写A::a = 10;,并在第二种情况下,把它作为简写this->a = 10;,这是不编译,因为类型thisconst A*.

  • @TaylorHansen`his`是指针类型的prvalue.非类型的Prvalues永远不会被cv限定. (2认同)

Vla*_*cow 21

根据C++标准(9.2.3.2静态数据成员)

1静态数据成员不是类的子对象的一部分 ......

并且(9.2.2.1这个指针)

1在非静态(9.2.1)成员函数的主体中,关键字this是一个prvalue表达式,其值是调用该函数的对象的地址.类X的成员函数中的类型是X*.如果成员函数声明为const,则其类型为const X*,...

最后(9.2.2非静态成员函数)

3 ...如果名称查找(3.4)将id-expression中的名称解析为某个类C的非静态非类型成员,并且如果id-expression可能被评估或C是X或基类对于X,将id-expression转换为类成员访问表达式(5.2.5),使用(*this)(9.2.2.1)作为左侧的后缀表达式.运营商.

因此在这个类定义中

class A 
{
  public:   
    static int a; 

    void set() const
    {
        a = 10;
    }
};
Run Code Online (Sandbox Code Playgroud)

静态数据成员a不是类类型的对象的子对象,并且指针this不用于访问静态数据成员.因此任何成员函数,非静态常量或非常量或静态成员函数都可以更改数据成员,因为它不是常量.

在这个类定义中

class A 
{
  public:   
    int a; 

    void set() const
    {
        a = 10;
    }
};
Run Code Online (Sandbox Code Playgroud)

非静态数据成员a是类类型的对象的子对象.要在成员函数中访问它,可以使用此语法的成员访问语法.您不能使用常量指针this来修改数据成员.并且指针确实const A *在函数中具有类型,set因为函数是使用限定符声明的const.如果函数在这种情况下没有限定符,则可以更改数据成员.


Ste*_*ner 13

问题是,如果类的成员函数Aconst,则类型为thisis const X*,从而防止非静态数据成员被更改(例如,参见C++标准):

9.3.2这个指针[class.this]

在非静态(9.3)成员函数的主体中,关键字this是一个prvalue表达式,其值是调用该函数的对象的地址.类X的成员函数中的类型是X*.如果成员函数声明为const,则其类型为const X*,...

如果a是非静态数据成员,那么a=10它是相同的this->a = 10,如果类型为thisis const A*a尚未声明为,则不允许mutable.因此,由于void set() const使的类型this之中const A*,这种访问是不允许的.

a相反,如果是静态数据成员,则a=10根本不涉及this; 只要static int a它本身没有被声明为const,a=10就允许声明.