program story

const 멤버 함수가 정적 데이터 멤버를 수정할 수있는 이유는 무엇입니까?

inputbox 2020. 9. 25. 07:51
반응형

const 멤버 함수가 정적 데이터 멤버를 수정할 수있는 이유는 무엇입니까?


다음 C++프로그램에서는 함수 에서 정적 데이터 멤버수정하는 const것이 정상적으로 작동합니다.

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

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

그러나 함수 에서 비 정적 데이터 멤버수정하는 const것은 작동하지 않습니다.

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

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

const멤버 함수가 static데이터 멤버를 수정할 수있는 이유는 무엇 입니까?


그게 규칙입니다. 그리고 그럴만 한 이유가 있습니다.

const멤버 함수 한정자는 클래스가 mutable아닌 static멤버 변수를 수정할 수 없음을 의미 합니다.

합리화를 제공하는 방식으로 정규화 된 멤버 함수 this포인터 constconst유형 this이며 본질적으로 클래스 인스턴스 와 관련됩니다 . static멤버는 클래스 인스턴스와 관련이 없습니다. static멤버 를 수정하는 데 인스턴스가 필요하지 않습니다 A::a = 10;. 귀하의 경우에는 .

따라서 첫 번째 경우에는의 a = 10;약자로 생각 A::a = 10;하고 두 번째 경우 this->a = 10;에는 유형이 this이므로 컴파일 할 수없는의 약자로 생각하십시오 const A*.


C ++ 표준 (9.2.3.2 정적 데이터 멤버)에 따름

1 정적 데이터 멤버는 클래스의 하위 개체에 속하지 않습니다 ...

그리고 (9.2.2.1 this 포인터)

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은 (* this) (9.2.2.1)을 .NET Framework의 왼쪽에 접미사 식으로 사용하여 클래스 멤버 액세스 식 (5.2.5)으로 변환됩니다 . 운영자.

따라서이 클래스 정의에서

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. 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. 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. And the pointer this is indeed has type const A * within the function set because the function is declared with the qualifier 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):

9.3.2 The this pointer [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. The type of this in a member function of a class X is X*. If the member function is declared const, the type of this is 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. Thus, since void set() const makes the type of this being const A*, this access is not allowed.

If a is a static data member, in contrast, then a=10 does not involve this at all; and as long as static int a by itself has not been declared as const, statement a=10 is allowed.


The const qualifier on a member function means that you cannot modify non-mutable, non-static class data members.

참고URL : https://stackoverflow.com/questions/43936404/why-can-a-const-member-function-modify-a-static-data-member

반응형