简体   繁体   English

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

[英]Why can a const member function modify a static data member?

In the following C++ program, modifying a static data member from a const function is working fine: 在下面的C++程序中,从const函数修改静态数据成员工作正常:

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

    void set() const
    {
        a = 10;
    }
};

But modifying a non-static data member from a const function does not work: 但是从const函数修改非静态数据成员不起作用:

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

    void set() const
    {
        a = 10;
    }
};

Why can a const member function modify a static data member? 为什么const成员函数可以修改static数据成员?

It's the rule, that's all. 这就是规则,就是这样。 And for good reason. 并且有充分的理由。

The const qualifier on a member function means that you cannot modify non- mutable non- static class member variables. 成员函数上的const限定符意味着您无法修改非mutablestatic类成员变量。

By way of offering some rationalisation, the this pointer in a const qualified member function is a const type, and this is inherently related to an instance of a class. 通过提供一些合理化, const限定成员函数中的this指针是一个const类型, this本身就与一个类的实例有关。 static members are not related to a class instance. static成员与类实例无关。 You don't need an instance to modify a static member: you can do it, in your case, by writing A::a = 10; 您不需要实例来修改static成员:在您的情况下,您可以通过编写A::a = 10; .

So, in your first case, think of a = 10; 所以,在你的第一种情况下,想到a = 10; as shorthand for A::a = 10; 作为A::a = 10;简写A::a = 10; and in the second case, think of it as shorthand for this->a = 10; 在第二种情况下,将其视为此的简写 - this->a = 10; , which is not compilable since the type of this is const A* . ,这是不编译自的类型thisconst A*

According to the C++ Standard (9.2.3.2 Static data members) 根据C ++标准(9.2.3.2静态数据成员)

1 A static data member is not part of the subobjects of a class ... 1静态数据成员不是类的子对象的一部分 ......

And (9.2.2.1 The this pointer) 并且(9.2.2.1这个指针)

1 In the body of a non-static (9.2.1) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called. 1在非静态(9.2.1)成员函数的主体中,关键字this是一个prvalue表达式,其值是调用该函数的对象的地址。 The type of this in a member function of a class X is X*. 类X的成员函数中的类型是X *。 If the member function is declared const, the type of this is const X* ,... 如果成员函数声明为const,则其类型为const X * ,...

And at last (9.2.2 Non-static member functions) 最后(9.2.2非静态成员函数)

3 ... if name lookup (3.4) resolves the name in the id-expression to a non-static non-type member of some class C, and if either the id-expression is potentially evaluated or C is X or a base class of X, the id-expression is transformed into a class member access expression (5.2.5) using (*this) (9.2.2.1) as the postfix-expression to the left of the . 3 ...如果名称查找(3.4)将id-expression中的名称解析为某个类C的非静态非类型成员,并且如果id-expression可能被评估或C是X或基类对于X,将id-expression转换为类成员访问表达式(5.2.5),使用(* this) (9.2.2.1)作为左侧的后缀表达式。 operator. 运营商。

Thus in this class definition 因此在这个类定义中

class A 
{
  public:   
    static int a; 

    void set() const
    {
        a = 10;
    }
};

the static data member a is not a subobject of an object of the class type and the pointer this is not used to access the static data member. 静态数据成员a不是类类型的对象和指针的子对象this不用于访问静态数据成员。 So any member function, non-static constant or non-constant, or a static member function can change the data member because it is not a constant. 因此任何成员函数,非静态常量或非常量或静态成员函数都可以更改数据成员,因为它不是常量。

In this class definition 在这个类定义中

class A 
{
  public:   
    int a; 

    void set() const
    {
        a = 10;
    }
};

the non-static data member a is an subobject of an object of the class type. 非静态数据成员a是类类型的对象的子对象。 To access it in a member function there is used either a member access syntax of this syntax is implied. 要在成员函数中访问它,可以使用此语法的成员访问语法。 You may not use a constant pointer this to modify the data member. 你可能不使用一个常量指针this修改的数据成员。 And the pointer this is indeed has type const A * within the function set because the function is declared with the qualifier const . 并且指针确实在函数set具有类型const A * ,因为函数是用限定符const声明的。 If the function had no the qualifier in this case the data member could be changed. 如果函数在这种情况下没有限定符,则可以更改数据成员。

The thing is, that if a member function of a class A is const , then the type of this is const X* , and thereby prevents non-static data members from being altered (cf, for example, C++ standard ): 的事情是,如果一个类的成员函数Aconst ,那么类型thisconst X* ,并由此防止非静态数据成员被改变(参见,例如, C ++标准 ):

9.3.2 The this pointer [class.this] 9.3.2这个指针[class.this]

In the body of a non-static (9.3) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called. 在非静态(9.3)成员函数的主体中,关键字this是一个prvalue表达式,其值是调用该函数的对象的地址。 The type of this in a member function of a class X is X*. 类X的成员函数中的类型是X *。 If the member function is declared const, the type of this is const X*, ... 如果成员函数声明为const,则其类型为const X *,...

If a is a non-static data member, then a=10 is the same as this->a = 10 , which is not allowed if the type of this is const A* and a has not been declared as mutable . 如果a是一个非静态数据成员,则a=10是相同的this->a = 10 ,这是不允许的,如果类型thisconst A*a还没有被宣布为mutable Thus, since void set() const makes the type of this being const A* , this access is not allowed. 因此,由于void set() const使的类型this之中const A* ,这种访问是不允许的。

If a is a static data member, in contrast, then a=10 does not involve this at all; 相反,如果a是静态数据成员,那么a=10根本不涉及this ; and as long as static int a by itself has not been declared as const , statement a=10 is allowed. 并且只要static int a本身未被声明为const ,则允许语句a=10

成员函数上的const限定符意味着您无法修改non-mutable non-static 类数据成员

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 const成员函数可以修改数据成员 - const member function can modify data member 为什么 const function 可以使用 static 成员对象的非常量 function? - Why const function can use a static member object's non-const function? 为什么可以初始化非const和静态const成员变量而不是静态成员变量? - Why can one initialize non-const and static const member variables but not static member variables? 为什么我可以更新 const 成员 function 中的成员变量? - Why can I update member variables in a const member function? 为什么C ++的“ const”函数可以修改其指针类型成员? - why a C++ “const” function can modify its pointer-type member? C++ - 为什么不能使用“const”限定符创建 static 成员 function - C++ - Why static member function can't be created with 'const' qualifier 为什么我们需要为静态常量数据成员单独定义? - Why we need a separate definition for a static const data member? 为什么我们不能在静态成员函数中使用const成员? - Why can't we use const members in static member functions? 静态const数据成员与函数中的硬编码值 - static const data member vs hard-coded value in function 常量成员 function 更改 Object 数据成员 - Const member function Changing Object Data Member
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM