2007년 04월 05일
[C++]3. 낌새만 보이면 const 를 들이대 보자!(4)
상수멤버 및 비상수 멤버함수에서 코드중복 현상을 피하는 방법
mutable은 생각지도 않던 비트 수준 상수성을 단어 하나로 깔끔하게 해결해 준다.
경계검사라든지 접근정보로깅, 자료무결성검증과 같은 코드들이 들어간다면 상수/비상수 버전의 코드에는
똑같은 코드들이 Ctrl+C , Ctrl+V 되게 될 것이다.
class TextBlock{
public:
…
const char& operator[] ( std::size_t position ) const
{
... //경계검사 -- Ctrl+C
... //접근데이터로깅-- Ctrl+C
... //자료무결성검증-- Ctrl+C
return text[position];
}char& operator[] ( std::size_t position )
{
... //경계검사 -- Ctrl+V
... //접근데이터로깅-- Ctrl+V
... //자료무결성검증-- Ctrl+V
return text[position];
}
private:
std::string text;
};
operator의 핵심 기능은 한 번만 구현하고 두 번 사용은 못할까?
const 를 캐스팅으로 날려보자!
기본적으론 좋지 않은 아이디어이지만
비상수 operator[]를 호출한다면 거기엔 비상수 객체가 우선적으로 들어있을 것이기 때문에 안정성이 있다.
따라서, 비상수 operator[]가 상수 버전을 호출하도록 구현을 하자
class TextBlock{
public:
…
const char& operator[] ( std::size_t position ) const
{
... //이전과 동일
return text[position];
}char& operator[] ( std::size_t position ) //상수 버전 op를 호출한다
{
return
const_cast<char&> ( //op[]의 반환형에 캐스팅을 하여 const를 때고
static_cast<const TextBlock&> // *this의 타입에 const를 붙여
(*this)[position] ); //op[]의 상수 버전을 호출
}private:
std::string text;
};
그냥 operator[]를 호출하면 무한 루프가 돌기 때문에 상수 operator[]를 호출 하기위해 *this 를
const TextBlock& 으로 캐스팅을 하였고 그 다음에 operator[]의 반환 값에서 const를 떼어 내야 하기 때문에 두 번의 캐스팅이 시행되었다.
const를 붙이는 캐스팅은 안전한 타입 변환(비상수 객체에서 상수 객체로 바꾸는)을 강제로 진행하는 것뿐이라
static_cast만 사용 하고 const를 제거 하는 캐스팅은 const_cast 밖에 없기 때문에 사용을 하였다.
하지만 상수 멤버에서 비상수 멤버를 호출 하게 해서는 절대 안된다. 상수 멤버함수는 해당객체의 논리적인
상태를 바꾸지 않겠다고 컴파일러와 협의가 되어 있지만 비상수 멤버함수는 그렇지 않기 때문이다.
# by | 2007/04/05 21:29 | Effective C++ | 트랙백




