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]); } ... };
댓글 없음:
댓글 쓰기