Post List

2015년 1월 4일 일요일

낌새만 보이면 const를 들이대 보자!

const를 객체에 붙이면 외부 변경을 불가능하게 해준다.

char greeting[] = "Hello";

const char *p1 = greeting; // 상수 Data, 내용 변경 불가
char const *p2 = greeting; // 상수 Data
char * const p3 = greeting; // 상수 Pointer
const char * const p4 = greeting ; // 상수 Data, 상수 Pointer

 * const를 붙여 선언하면 Compiler가 사용상의 Error를 잡아내는데 도움을 줍니다. const는 어떤 유효범위에 있는 객체에도 붙을 수 있으며, 함수 Parameter 및 Return Type에도 붙을 수 있으며, 멤버 함수에도 붙을 수 있습니다.

Programmer의 실수를 Compiler가 알려주는 역할을 합니다.

class R { ... };
const R operator* (const R& lhs, const R& rhs);

R a,b,c;

(a * b) = c; // a * b 를 한 결과에 c를 넣어 ?

if ( a * b = c) ... // == 아닌가 ?

상수 멤버 함수 안에서도 수정이 가능한 변수가 필요하다면 mutable 을 사용하라.


class C {
public:
    std::size_t length() const;
private:
    char *pText;
    mutable std::size_t textLength;
    mutable bool lengthIsValid;
};

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




* Compiler 쪽에서 보면 비트수준 상수성을 지켜야 하지만, Programmer는 논리적인 상수성을 사용해서 프로그래밍해야 합니다.

 Class의 Member로 Pointer가 있는 경우에는 비트수준 상수성을 유지하면서도 Class의 내용을 변화시키는 것이 가능하다. 이럴 경우의 논리적인 상수성을 지키는 것은 Programmer의 몫이다.

* 상수 멤버 및 비상수 멤버 함수가 기능적으로 서로 똑같게 구현되어 있을 경우에는 코드 중복을 피하는 것이 좋은데, 이때 비상수 버전이 상수 버전을 호출하도록 만드세요.


class C {
public:
    const char& operator[](std::size_t position) const {
        ...
        return text[position];
    }
    char& operator[](std::size_t position) {
        return const_cast<char&>( static_cast<const C&>(*this)[position]);
    }
    ...
};

댓글 없음:

댓글 쓰기