다음 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)을. 운영자.
따라서이 클래스 정의에서
class A
{
public:
static int a;
void set() const
{
a = 10;
}
};
정적 데이터 멤버 a
는 클래스 유형의 개체의 하위 개체 this
가 아니며 포인터 는 정적 데이터 멤버에 액세스하는 데 사용되지 않습니다. 따라서 멤버 함수, 비 정적 상수 또는 비상 수 또는 정적 멤버 함수는 상수가 아니기 때문에 데이터 멤버를 변경할 수 있습니다.
이 클래스 정의에서
class A
{
public:
int a;
void set() const
{
a = 10;
}
};
비 정적 데이터 멤버 a
는 클래스 유형 객체의 하위 객체입니다. 멤버 함수에서 액세스하려면이 구문의 멤버 액세스 구문이 내포되어 있습니다. 상수 포인터 this
를 사용 하여 데이터 멤버를 수정할 수 없습니다 . 그리고 포인터 this는 실제로 함수가 한정자로 선언되기 때문에 const A *
함수 내에서 유형을 set
갖습니다 const
. 이 경우 함수에 한정자가 없으면 데이터 멤버를 변경할 수 있습니다.
답변
문제는 클래스의 멤버 함수 A
가 const
인 경우 유형이 this
이므로 const X*
비 정적 데이터 멤버가 변경되는 것을 방지합니다 (예 : C ++ 표준 ).
9.3.2 this 포인터 [class.this]
비 정적 (9.3) 멤버 함수의 본문에서 this 키워드는 해당 값이 함수가 호출되는 객체의 주소 인 prvalue 표현식입니다. 클래스 X의 멤버 함수에서 이것의 유형은 X *입니다. 멤버 함수가 const로 선언 된 경우이 유형은 const X *, …
경우 a
비 정적 데이터 부재는, 다음 a=10
과 같이 동일한 this->a = 10
유형이 경우 허용되지 않는, this
인 const A*
및 a
선언되지 않았다 mutable
. 따라서 void set() const
는 this
존재 유형이므로이 const A*
액세스는 허용되지 않습니다.
경우 a
정적 데이터 멤버 인 반면, 다음 a=10
이 포함되지 않는 this
전혀; 오래 같이 static int a
자체로 선언되지 않은 의한 const
, 문이 a=10
허용됩니다.
답변
const
A의 규정 멤버 함수 수정 할 수 없음을 의미 non-mutable
, non-static
클래스 데이터 멤버 .