-
[const_cast] 제한적으로 활용하자개발/C·C++ 2021. 4. 27. 16:33
const_cast는 객체(변수)의 상수성을 없애주는 연산자입니다. 안정성 관점에서 없던 상수성이 생기는 건 괜찮지만 있던 상수성이 사라지는 건 위험합니다. 상수성을 부여해서 객체를 만든 이유가 있을 것이기 때문입니다. 그래서 const_cast는 정말 쓰지 않으면 안 되는 곳에, 고심해보고 사용해야 합니다. 다음은 연산자를 오버로딩해서 사용할 때 중복 코드를 방지하면서 코드 길이를 줄이는 과정에 const_cast가 사용되는 케이스입니다.
class String { private: char* _chars; public: String(const char* chars) : _chars(new char[strlen(chars) + 1] { strcpy(_chars, chars); } char& operator[](int index) { return _chars[index]; } ~String() { delete[] _chars; } } int main() { String str0("kim"); cout << str0[0] << endl; }
일반 객체를 선언해서 사용할 때는 문제가 딱히 문제될 것이 없습니다. 상황에 따라서 객체에 상수성을 부여해야 상황이 생길 수 있습니다. 예제에서는 객체를 const를 만들면 인덱스 연산자([])를 사용할 수 없습니다. const 객체는 const 함수만 호출할 수 있기 때문입니다. 따라서 const 함수를 따로 정의해줘야 합니다. 예제에서는 함수 본문이 한 줄밖에 되지 않으므로 본문을 복사 붙여넣기 해도 됩니다만, 정의부가 긴 함수를 그대로 복사 붙여넣는 것은 효율적이지 못합니다. 이 때 const_cast를 활용할 수 있습니다.
class String { private: char* _chars; public: String(const char* chars) : _chars(new char[strlen(chars) + 1] { strcpy(_chars, chars); } char& operator[](int index) { const String& str = *this; const char& ch = str[index]; return const_cast<char&>(ch); } // 리턴에도 const를 붙여야 반환값을 수정할 수 없게 된다 const char& operator[](int index) const { return _chars[index]; } ~String() { delete[] _chars; } } int main() { String str0("kim"); cout << str0[0] << endl; const String str1("kim"); cout << str[1] << endl; }
일반 함수는 자기 자신에게 상수성을 부여하고, 그 객체에서 상수성 함수를 호출한 뒤에 리턴값에 상수성을 없앴습니다. 이 코드는 필요에 의해 일반 객체에 임시적으로 상수성을 부여했다가 반환 타입에 맞게 상수성을 제거한 것이므로 문제가 없습니다. 코드 중복 문제도 해결됩니다.
'개발 > C·C++' 카테고리의 다른 글
[예외 처리] 너라고 예외는 아니야 (0) 2021.04.28 [volatile] 컴파일러! 나대지 마라 (0) 2021.04.27 [객체의 복사와 대입 연산자] 의도하는 동작이 있다면 구현하라 (0) 2021.04.26 [const member function] 이면에 있는 조금 더 복잡한 것 (0) 2021.04.22 객체 지향 개론 (0) 2021.04.21