2007년 04월 05일
[C++]3. 낌새만 보이면 const 를 들이대 보자!(3)
비트수준 상수성(bitwise constness)과 논리적 상수성(logical constness)
비트수준 상수성 ( 물리적 상수성, physical constness )
멤버 함수가 그 객체의 어떤 데이터 멤버도 건드리지 않아야(정적 멤버 제외) 그 멤버 함수가 'const' 이다
즉, 멤버 함수가 객체의 구성요소들 중 아무것도 건드리지 말아야 한다는 것이지만
class CTextBlock {
public:
…
char& operator[] ( std::size_t position ) const //부적절 하지만 비트 수준 상수성에 있어
{ return pText[position]; } //허용되는 선언
private:
char* pText; // string 으로 선언할 수도 있으나 혹시나 C 와의 호환성을 위해 선언했다면
};
위와 같은 경우에서는 다음과 같은 경우가 발생한다
const CTextBlock cctb( "Hello" ); //상수 객체 선언의도하지 않은 결과가 나올 수도 있기 때문에 이를 보완하기 위해 생겨난 개념이 논리적 상수성이다char *pc = &cctb[0]; //상수 버전의 operator[]를 호출 cctb내부데이터의 포인터획득
*pc = 'J'; // cctb 는 "Jello"라는 값을 가지게 된다.
논리적 상수성
일부 몇 비트는 바꿀 수 있되, 그것을 사용자 측에서만 알아채지 못하게만 하면 상수 멤버의 자격이 있다.
class CTextBlock {CTextBlock의 상수 객체에 대해선 문제가 없어야 할 것 같은 코드이지만public:
…
std::size_t length() const;private:
char *pText;
std::size_t textLength; //바로 직전에 계산한 텍스트 길이
bool lengthIsValid; //이 길이가 현재 유효한가?
};std::size_t CTextBlock::length() const
{
if ( !lengthIsValid ) {
textLength = std::strlen( pText ); //Error! 상수멤버안에서는
lengthIsValid = true; // textlength , lengthIsValid에 대입할 수 없다
}
return textLength;
}
length 의 구현은 비트수준 상수성과 너무 거리가 멀어 컴파일러의 검열을 통과할 수가 없습니다.
mutable
mutable 은 비정적 데이터 멤버를 비트수준의 상수성의 족쇄에서 풀어주는 약수 같은 키워드이다
class CTextBlock {public:
…
std::size_t length() const;private:
std::size_t CTextBlock::length() const
char *pText;
mutable std::size_t textLength; //이제 이 데이터 들은 어떤 순간에도(상수멤버
mutable bool lengthIsValid; // 함수안이라도) 수정이 가능합니다.
};
{
if ( !lengthIsValid ) {
textLength = std::strlen( pText ); //OK!
lengthIsValid = true; // OK!
}
return textLength;
}
# by | 2007/04/05 21:10 | Effective C++ | 트랙백




