2013-07-24 5 views
3

상수로 선언 된 객체를 수정하는 것이 UB라는 것을 알고 있습니다. 제목에서 언급 된 좀 더 복잡한 예는 무엇입니까?const 객체의 비 const 멤버 수정하기

class Foo 
{ 
    public: 
     Foo (void) { } 
     int data; 
}; 

int main (void) 
{ 
    const Foo foo; 
    const_cast<Foo&>(foo).data = 0; // UB? 
    return 0; 
} 

data은 비 const로 선언되었으므로 수정하는 것이 좋습니다. 그러나 foo은 const로 선언됩니다. 그래서 우리는 그것을 수정할 수없는 것 같습니다. 따라서 나는 UB가 여기에서 호출된다고 믿는다. 내가 맞습니까?

업데이트 : 그래서 그것은 실제로 UB라는 것입니다. 즉, 가변 멤버를 수정하는 가짜 상수 멤버가있는 모든 클래스는 상수 인스턴스에서 UB를 생성합니다.

class Foo 
{ 
    public: 
     mutable int data; 
     Foo (void) { } 
     void foo (void) const 
     { 
      some_modifications_of_data(); 
     } 
}; 


const Foo foo; 
foo.foo(); // UB? 

는 당신이 클래스의이 종류를 디자인 할 경우 명시 적으로 어떠한 상황 아무도에서 일정한 경우에이 방법을 호출 할 수 있음을 언급해야한다는 것을 의미합니까?

+1

아니요, 개체가 const이므로 수정할 수 없습니다. – chris

+1

예, 표준에 따라 정의되지 않았습니다. 이 옵션은 "정의되지 않은 동작"의 가능한 결과 중 하나이기 때문에 특정 컴파일러에서 제대로 작동 할 수 있습니다 (예 : 예상대로 설정 데이터가 0 인 경우). –

+0

@chris :'const_cast'는'const'를 없애기 때문에 컴파일러는 이것을 컴파일하여 실제로 작동하거나하지 않을 수도있는 코드를 생성합니다. –

답변

5

데이터 구조를 const으로 수정하기 위해 const_cast을 사용하면 실제로 정의되지 않은 동작입니다. 예외는 mutable으로 표시된 항목입니다. 이 값의 요점은 객체의 나머지 부분이 const 일 때도 수정할 수 있다는 것입니다. 그것은 정말로 "그러나 이것은 하나도 아닙니다 const"을 의미합니다.

const의 거의 전부가 컴파일러 감지 수정에 관한 것이기 때문에 기술적으로 컴파일러는 "비 쓰기 가능한 메모리"에 변수 const을 배치 할 수 있습니다. mutable 키워드는 constness의 "우회"를 허용하기 때문에 컴파일러는 변경 가능 구성 요소가있는 경우 쓰기 불가능한 메모리에 const 객체를 넣지 않으며 물론 "객체"가 const이되지 않습니다 객체가 변경 가능한 구성 요소에서 수정되는 경우 - const 함수 내부에서도 마찬가지입니다.

+0

설명해 주셔서 감사합니다. – Kolyunya

관련 문제