const_cast

Jaemyeong Lee·2024년 11월 7일
0

FastCampusC++

목록 보기
76/78

코드를 한 줄씩 자세히 분석하여 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;
}
  • 이 함수는 상수 참조 iint&로 변환하여 상수성을 제거합니다.
  • 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는 상수성을 제거하는 강력한 도구지만, 오용하면 프로그램의 신뢰성을 크게 떨어뜨릴 수 있으므로 신중히 사용해야 합니다.

profile
李家네_공부방

0개의 댓글