[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 {

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;
}

CTextBlock의 상수 객체에 대해선 문제가 없어야 할 것 같은 코드이지만
length 의 구현은 비트수준 상수성과 너무 거리가 멀어 컴파일러의 검열을 통과할 수가 없습니다.


mutable

mutable 은 비정적 데이터 멤버를 비트수준의 상수성의 족쇄에서 풀어주는 약수 같은 키워드이다
class CTextBlock {

public:

    std::size_t length() const;

private:
    char *pText;
    mutable std::size_t textLength; //이제 이 데이터 들은 어떤 순간에도(상수멤버
    mutable bool lengthIsValid;     // 함수안이라도) 수정이 가능합니다.
};

std::size_t CTextBlock::length() const
{
    if ( !lengthIsValid ) {
        textLength = std::strlen( pText ); //OK!
        lengthIsValid = true;           // OK!
    }
    return textLength;
}

by 일찍자라 | 2007/04/05 21:10 | Effective C++ | 트랙백

◀ 이전 페이지          다음 페이지 ▶