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
포인터 const
는 const
유형 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.
'program story' 카테고리의 다른 글
파일이 아닌 저장소의 루트에서만 속성 변경 사항을 커밋합니다. (0) | 2020.09.25 |
---|---|
virtualenv 대신 글로벌 사이트 패키지에 pip 설치 (0) | 2020.09.25 |
ImageMagick 변환에서 샘플 / 리 샘플 / 스케일 / 크기 조정 / 적응 크기 조정 / 썸네일 연산자의 차이점은 무엇입니까? (0) | 2020.09.25 |
어떤 실제 WPF 애플리케이션이 있습니까? (0) | 2020.09.25 |
CC, gcc 및 g ++의 차이점은 무엇입니까? (0) | 2020.09.25 |