티스토리 뷰

 

https://stackoverflow.com/questions/36092937/should-i-use-const-cast

 

* (미리보기) 절대 이렇게 이용하면 안 된다

const bool do_it = true;
bool *ptr = const_cast<bool*>(&do_it);
*ptr = false;

// optimizer probably thinks this is always true
if (do_it) initiate_nuclear_first_strike(); 

 

c++의 type casting에 대해 공부하던 도중 const, volatile 속성을 없애주는 const_cast에 대해 의문이 생겼다.

 

도대체 상수로 선언한 값을 왜 바꾸고 싶어 하는 걸까?

 

const_casting에서는 non-const 변수에 대해 pointer 나 reference로 접근하는 포인터에 대해 적용한다.

 

원래 변수를 수정하지 못하도록 const로 선언했던 pointer나 reference에서 원래 변수를 수정하고 싶을 때 사용한다.

 

아래 예제를 첨부한다.

 

example1 (잘못된 예제)

 

https://en.cppreference.com/w/cpp/language/const_cast

Two possibly multilevel pointers to the same type may be converted between each other, regardless of cv-qualifiers at each level.

 

const_cast는 포인터 간에 사용해야 한다.

// example 1
// const cast casting pointer to pointer
const int a = 3;
int b = const_cast<int>(a); // error

 

example2 (잘못된 예제)

 

const로 선언한 변수는 수정 할 수 없다.

// example 2
// const value can not change
int c = 3;
const int *d = &c;
d = 4; // error

 

example3 (잘못된 예제)

 

1. const 로 선언된 변수에 대해서는 const_cast를 사용하지 않는다.

2. const_cast를 사용할 때는 변수에 대해 포인터를 새로 만들고 사용해야 한다(아래 예제에서는 변수에 대해 바로 사용)

// example 3
// value not expected
// const casting "const pointer" not "const value"
const int e = 3;
int *ptr_e = const_cast<int *>(&e);
std::cout << &e << ' ' << ptr_e << '\n';

*ptr_e = 5;
std::cout << *ptr_e << '\n';
std::cout << e << '\n';

g++ 에서 결과 (예상치 않은 결과가 나온다)

 

example4

 

결론

const_cast를 사용할 때는 t3의 예제처럼 const로 선언하지 않은 변수를 가리키는 pointer 나 reference에 대해, 포인터 간 const_cast를 사용하여 const 한 속성을 없앤다.

struct type
{
	int i;
	type(int i) : i(i){};

	void foo()
	{
		i++;
	}
	void bar() const
	{
		const_cast<type *>(this)->i++;
	}
};

type t1 = type(3);
t1.foo();
t1.bar();
std::cout << t1.i << '\n';

// not correctly use
const type t2 = type(3);
t2.bar();
// t2.foo(); error
type *ptr_t2 = const_cast<type *>(&t2);
ptr_t2->foo();
std::cout << t2.i << '\n';

// correctly use
type t3 = type(3);
const type& ref_t3 = t3;
// t3.foo(); error
ref_t3.bar();
type *ptr_t3 = const_cast<type *>(&ref_t3);
ptr_t3->foo();
std::cout << t3.i << '\n';

Only the following conversions can be done with const_cast. In particular, only const_cast may be used to cast away (remove) constness or volatility.

 

또한 const한 속성뿐 아니라 volatile 한 속성(메모리에 항상 접근해야 함) 또한 remove 하는 용도로 사용한다.

댓글