C++ const 이해하기

Understanding C++ const keyword

Posted by dydtjr1128 on January 08, 2020 · 5 mins read CPP

Intro

const 키워드는 값을 상수로 선언할 수 있도록 도와주는 키워드 이다. 즉, 값을 변경할 수 없도록 한다.

const int a = 10;
a = 20; // error!

위 코드와 같이 한번 설정된 a는 read-only memeory에 올라가게 되고 변경할 수 없게 된다. 이처럼 const는 값을 한번 설정하고 그 값을 유지하면서 사용해야 할 때 필요하다.

포인터와 const

상수를 가리키는 포인터가 가리키는 공간은 수정할 수 없는(const) 공간이지만 상수 변수의 주소를 가리키는 포인터는 수정할 수 있는(non-const) 포인터 이다.

int value = 5, value2 = 11;
const int * ptr = &value;
// *ptr = 10; // error! can't change const value
value = 10; // ok!
std::cout << value << " " << *ptr << std::endl; // 10 10
value = 7;
ptr = &value2;
std::cout << value << " " << *ptr << std::endl; // 7 11

위의 코드처럼 ptr이라는 포인터는 변수 value의 주소를 가지고 있는 포인터 이다. 여기서 const는 const int*가 아닌 const int에 적용 되므로 포인터가 가리키고 있는 값을 바꿀 수는 없지만 주소값은 바꿀수 있다.

상수 포인터

위에서 나왔던 포인터는 가리키는 값은 변경 불가능하지만 다른 변수의 주소값으로 변경이 가능했다.

상수 포인터는 위에서 나왔던 내용과 달리 주소를 바꿀 수 없도록 되어 있다.

int value = 5, value2 = 11;
int* const ptr = &value;
*ptr = 10; // ok! can change non-const value
value = 10; // ok!
std::cout << value << " " << *ptr << std::endl; // 10 10
value = 7;
//ptr = &value2; // error! can't change pointer address
std::cout << value << " " << *ptr << std::endl; // 7 7

위의 결과 처럼 ptr의 주소를 변경하려고 하면 오류를 발생시킨다. 포인터가 상수이기 때문에 포인터 값을 변경할 수가 없다.

하지만 포인터가 상수이지 포인터가 가리키는 값은 상수가 아니기 때문에 *ptr = 10과 같이 포인터가 가리키는 값을 변경하는 것은 가능하다.

상수를 가리키는 상수 포인터

int value = 5, value2 = 11;
const int* const ptr = &value;
//*ptr = 10; //  error! can't change const value
value = 10; // ok!
std::cout << value << " " << *ptr << std::endl; // 10 10
value = 7;
//ptr = &value2; // error! can't change pointer address
std::cout << value << " " << *ptr << std::endl; // 7 7

위의 코드는 앞서 본 2가지 케이스를 합친 형태로 포인터가 가리키는 값도 상수이며 포인터 또한 상수로써 가리키는 값을 바꾸거나 다른 주소를 가리키도록 수정을 할수 없다.

이처럼 const 의 위치에 따라 동작하는 방식이 다르기 때문에 이를 유의해서 사용하는것이 중요하다.

Summary

  • 상수를 가리키는 비 상수 포인터는 가리키는 값을 수정 불가능하지만 다른 변수를 가리키도록 자신의 주소를 바꿀 수 있다.
  • 일반 변수를 가리키는 상수 포인터는 자신이 가리키는 주소를 수정 할 수 없지만 포인터가 가리키는 값을 변경 할 수 있다.
  • 상수를 가리키는 상수 포인터는 자신이 가리키는 주소를 수정 할 수 없고 포인터가 가리키는 값도 수정 할 수 없다.
int value = 5;
const int* ptr1 = &value; // ptr1으로 value값 수정불가능(상수), 주소값 변경 가능
int* const ptr2 = &value; //  ptr2으로 value값 수정 가능, 주소값 변경 불가능(상수포인터)
const int* const ptr3 = &value; // ptr3으로 value 값 수정 불가능(상수), 주소값 변경 물가능(상수 포인터)

쉽게 이해하기 위해서 다음 처럼 이해할 수 있다.

C++ const