-
Effective C++...2일지 2022. 5. 30. 08:51
포인터의 상수 처리
포인터는 const를 어디에 붙이는지에 따라 포인터를 상수 처리할지, 데이터를 상수 처리할지 달라진다.
char greeting[] = "Hello";
char* p = greeting; // 비상수 포인터, 비상수 데이터
const char* p = greeting; // 비상수 포인터, 상수 데이터
char* const p = greeting; // 상수 포인터, 비상수 데이터
const char* const p = greeting; // 상수 포인터, 상수 데이터
※ 값의 수정이 필요한 경우가 아니면 const를 붙여두면 추후 실수를 막을 수 있다.
상수 함수의 오버로딩
클래스의 함수는 상수 여부만으로 오버 로딩이 가능하다.
class TextBlock {
public:
...
const char& operator[] (std::size_t position) const
{ return text[position]; }
char& operator[] (std::size_t position)
{ return text[position]; }
private:
std::string text;
}
논리적 상수성함수 내부적으로 상수성이 지켜지지 않더라도 사용자 측에서 알아채지 못하면 상수로 인정한다는 개념이다.
class CTextBlock {
public:
std::size_t length() const;
private:
char* pText;
mutable std::size_t textLength; // mutable 선언으로 상수 처리를 회피한다.
mutable bool lengthIsValid;
}
std::size_t CTextBlock::length() const
{
if (!lengthIsValid) {
textLength = std::strlen(pText); // 상수 함수 내부에서 의미 있는 처리가 진행될 수 있다.
lengthIsValid = true;
}
return textLength;
}
다만 mutable을 이용한 상수 함수를 생성하면 비상수 함수와 동일한 기능을 수행하는 중복이 발생할 수 있다.
이때, 비상수 함수에서 상수 함수를 호출하는 식으로 처리하면 코드 중복을 막을 수 있다.
char& operator[](std::size_t position)
{
return const_cast<char&> (
static_cast<const TextBlock&>(*this)[position]; // 상수 버전 호출
);
}
※ 상수 함수에서 비상수 함수를 호출하는 것은 값을 바꿀 수 있는 위험이 있으므로 하면 안 된다.