코드를 한 줄씩 자세히 분석하여 const_cast
의 활용에 대해 설명하겠습니다.
String
클래스 (String.h
파일)class String
{
private:
char* _chars;
public:
String(const char* chars)
: _chars(new char[strlen(chars) + 1])
{
strcpy(_chars, chars);
}
String
클래스는 문자열을 저장하는 기능을 가지고 있습니다.strcpy
를 사용하여 초기화합니다.operator[]
연산자 오버로딩기존 코드에서 operator[]
는 두 버전으로 오버로드되어 있었습니다:
//char& operator[](int index)
//{
// return _chars[index];
//}
//const char& operator[](int index) const
//{
// return _chars[index];
//}
char&
반환을 통해 배열의 각 문자를 수정할 수 있습니다.const
객체에 대해 사용되며, const char&
반환을 통해 읽기 전용으로 제공합니다.const_cast
를 이용한 중복 코드 제거중복 코드를 제거하기 위해 const_cast
를 활용한 방식으로 수정되었습니다:
char& operator[](int index)
{
const String& s = *this;
const char& c = s[index];
return const_cast<char&>(c);
}
const char& operator[](int index) const
{
return _chars[index];
}
operator[]
에서 상수 객체로의 참조 s
를 생성하여, 상수 버전의 operator[]
를 호출합니다.const char&
타입을 const_cast
를 이용해 char&
로 변환하여, 상수 버전 코드 재사용을 가능하게 하면서도 비상수화된 객체에서 수정이 가능하게 합니다.const_cast
는 상수성을 제거하지만, 상수 객체에 대한 잘못된 수정 시 정의되지 않은 동작을 초래할 수 있으므로 주의가 필요합니다.stringFunc
함수void stringFunc()
{
String s0("abc");
std::cout << s0[0] << std::endl;
const String& s1 = s0;
std::cout << s1[0] << std::endl;
}
s0[0]
은 상수화되지 않은 객체이므로 char& operator[]
버전이 호출됩니다.s1[0]
은 const
객체이므로 const char& operator[]
버전이 호출되어 읽기 전용 접근만 가능합니다.volotileFunc
함수 (main.cpp
파일)volatile int i = 0;
i++;
i++;
i++;
volatile
키워드는 변수 i
가 최적화되지 않고 매번 메모리에서 읽히도록 합니다.func
함수 - const_cast
사용 예시void func(const int& i)
{
int& j = const_cast<int&>(i);
j = 10;
}
i
를 int&
로 변환하여 상수성을 제거합니다.const_cast<int&>(i)
를 통해 int
타입의 상수성을 제거하여 j
에 할당하고, 이를 통해 i
의 값을 수정할 수 있게 합니다.main
함수int main()
{
int i = 0;
func(i); // 안전한 사용 - 원본이 상수가 아님
const int j = 0;
func(j); // 위험한 사용 - 원본이 const, 정의되지 않은 동작 발생 가능
}
func(i);
는 상수가 아닌 변수 i
를 전달하여 안전하게 동작합니다.func(j);
는 상수 변수 j
를 전달하며, 정의되지 않은 동작을 일으킬 수 있습니다. 상수 데이터를 const_cast
로 수정하려는 시도는 예측 불가한 결과를 초래할 수 있습니다.이와 같이 const_cast
는 상수성을 제거하는 강력한 도구지만, 오용하면 프로그램의 신뢰성을 크게 떨어뜨릴 수 있으므로 신중히 사용해야 합니다.