Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ const_cast 완벽 정리: 상수성을 제거하는 타입 캐스팅 연산자


const_cast는 C++의 타입 캐스팅 연산자 중 하나로, 객체의 상수성(constness)을 제거하거나 변경하는 데 사용됩니다. 즉, const로 선언된 객체의 '상수' 속성을 벗겨내어 값을 수정할 수 있도록 만들어 주는 역할을 합니다.

대부분의 경우 상수 값을 유지하지만 특정 시점에만 값이 변경되어야 하는 객체가 있는 프로그램에서 const_cast가 유용하게 활용됩니다.

문법

const_cast의 기본 문법은 다음과 같습니다.

const_cast<타입 이름>(표현식)

기본 예제

입력:
const int x = 50;
const int* y = &x;
cout << "old value is" << *y << "\n";
int* z = const_cast<int *>(y);
*z = 100;
cout << "new value is" << *y;

출력:
old value is 50
new value is 100

위 예제는 const_cast의 가장 기본적인 사용법을 보여줍니다. 먼저 int형 상수 변수 x를 선언하고 50으로 초기화한 뒤, 이 변수를 가리키는 상수 포인터 y를 선언했습니다.

const_cast를 사용하려면 세 번째 포인터가 필요합니다. 여기서는 같은 데이터 타입인 int형 포인터 z를 생성했습니다.

상수 변수 x를 가리키고 있는 상수 포인터 y를 const_cast에 전달하여 일반 포인터 z에 할당하면, 이제 z를 통해 상수였던 값에 접근하고 수정할 수 있게 됩니다.

이처럼 const_cast를 사용하면 상수 값 50을 100으로 변경할 수 있습니다.

반면 const_cast 없이 포인터 y가 가리키는 값 x를 직접 변경하려고 하면 컴파일러는 "assignment of read-only location(읽기 전용 위치에 할당)" 오류를 발생시킵니다.

동작 단계

아래 프로그램에서 사용된 접근 방식은 다음과 같습니다.

  • 먼저 int형 상수 변수를 하나 생성하고 적절한 값으로 초기화합니다. 여기서는 변수 이름을 a, 값을 20으로 지정합니다.
  • 같은 데이터 타입의 상수 포인터 b를 생성하고, 상수 변수 a의 주소를 할당합니다.
  • const_cast에 사용할 세 번째 포인터 c를 int형으로 생성합니다.
  • 상수 포인터 b를 const_cast에 전달하고 그 결과를 포인터 c에 저장합니다.
  • 마지막으로 포인터 c의 값을 변경합니다. 그러면 상수 포인터 b가 가리키는 값도 자동으로 함께 변경됩니다.

알고리즘

Start
Step 1 -> main() 함수에서
int형 상수 a=20 선언
상수 포인터 int* b=&a 선언
포인터 int* c = const_cast<int *>(b) 선언
*c=40 할당
Stop

전체 코드

#include <iostream>
using namespace std;
int main() {
    const int a = 20;
    const int* b = &a;
    cout<<"old value is"<<*b<<"\n";
    int* c=const_cast<int *>(b);
    *c=40;
    cout<<"new value is"<<*b;
    return 0;
}

출력 결과

위 코드를 실행하면 다음과 같은 출력이 생성됩니다.

old value is 20
new value is 40

여기서 상수 포인터 b는 값이 20으로 고정되어 변경할 수 없는 상수 변수 a를 가리키고 있습니다. 하지만 같은 데이터 타입의 비상수(non-constant) 포인터 c를 새로 만들고 const_cast를 적용하면 해당 상수 값을 변경할 수 있습니다.

포인터 c의 값 변경은 상수 포인터 b가 가리키던 상수 값 20의 변경으로 이어졌습니다. 따라서 const_cast를 사용하기 전 출력 값은 20이었지만, 사용 후에는 40으로 바뀌었습니다.

const_cast의 다른 활용법

프로그램에서 const_cast는 상수 데이터를 매개변수로 받지 않는 함수에 상수 데이터를 전달해야 할 때도 사용할 수 있습니다.

예제

#include <iostream>
using namespace std;
int change(int* p2) {
    return (*p2 * 10);
}
int main() {
    const int num = 100;
    const int *p = &num;
    int *p1 = const_cast <int *>(p);
    cout << change(p1);
    return 0;
}

출력 결과

위 코드를 실행하면 다음과 같은 출력이 생성됩니다.

1000

이 프로그램은 const_cast를 사용하여 상수 값 100을, 어떤 상수 데이터도 받지 않는 change() 함수에 전달하는 과정을 보여줍니다.

change() 함수는 전달받은 값에 10을 곱한 뒤 그 결과를 main() 함수로 반환하고, main() 함수는 최종 출력인 1000을 화면에 표시합니다.

만약 const_cast 없이 동일한 프로그램을 실행하면서 상수 값을 change() 함수에 직접 전달하려고 하면 컴파일 오류가 발생합니다.

주의 사항

const_cast는 강력한 도구이지만 신중하게 사용해야 합니다. 원래부터 const로 선언된 객체의 값을 const_cast로 수정하는 것은 C++ 표준에서 정의되지 않은 동작(undefined behavior)으로 간주됩니다. 컴파일러 최적화에 따라 예상과 다른 결과가 나올 수 있으므로, const_cast는 호출하려는 함수가 실제로는 값을 수정하지 않는다는 것이 확실한 경우(예: const 문자열을 오래된 C 스타일 API에 전달할 때)에 한해 사용하는 것이 안전합니다.