본문 바로가기

컴퓨터/C++

const에 관하여

0. 도입

다음의 세 가지 변수 선언에 무슨 차이가 있을까? 차이를 잘 모르겠다면 이 글이 도움이 될지도 모른다ㅎㅎ

int const *            a;
int * const            b;
int const * const    c;

거두절미 하고 const에 대해 알아보자

 

 

 

! 주석처리된 것은 컴파일 오류를 유발하는 코드라인이다. !

 

 

1. 기본

1.1 선언

// const int    foo;
const int        foo = 10;
  • 기본 자료형에 const를 붙이는 경우, 해당 변수는 더이상 수정할 수 없기 때문에 선언과 동시에 초기화 해야 한다.

1.2 데이터 변경

const int        foo = 10;
// foo = 5;
  • const가 붙은 변수는 당연히 수정이 안 된다.

2. 포인터와 함께 쓰이는 경우

결론부터 말하자면 const 키워드가 자료형 앞 뒤로 붙느냐, 혹은 '*' 뒤로 붙느냐에 따라 효과가 달라진다.

  • const 키워드가 자료형 앞 또는 뒤로 붙는 경우는 데이터의 변경에 제한이 생긴다.
  • const 키워드가 '*' 뒤에 붙는 경우는 주소값 변경에 제한이 생긴다.

말로만 봐서는 이해가 어려우므로, 예시를 통해 살펴보자.

2.1 const가 자료형 뒤에 붙는 경우

int                foo = 10;
int                bar = 5;
int const *        ptr = &foo;

ptr = &bar;
// *ptr = 5;
  • ptr의 값(주소)은 다른 값(다른 주소)으로 변경이 가능하다.
  • 해당 주소에 있는 데이터를 변경하는 것에는 제한이 생긴다.

2.2 const가 자료형 앞에 붙는 경우

int                foo = 10;
int                bar = 5;
const int *        ptr = &foo;

ptr = &bar;
// *ptr = 5;
  • 마찬가지로 ptr의 값(주소)은 다른 값(다른 주소)으로 변경이 가능하다.
  • 해당 주소에 있는 데이터를 변경하는 것에는 제한이 생긴다.
  • int constconst int는 같은 의미다.

2.3 const가 * 뒤에 붙는 경우

int                foo = 10;
int                bar = 5;
int * const        ptr = &foo;

// ptr = &bar;
*ptr = 5;
  • 이 경우에는 ptr을 변경하는 것에 제한이 생긴다. 즉 다른 주소를 담을 수 없다.
  • 해당 주소에 있는 값을 변경하는 것은 가능하다.

2.4 const가 모든 것을 제한하는 경우

int                        foo = 10;
int                        bar = 5;
int const * const        ptr = &foo;

// ptr = &bar;
// *ptr = 5;
  • 이런 경우에는 주소에 있는 값을 변경하는 것도 불가하고, 다른 주소를 담는 것도 불가하다.

3. 함수

const가 함수의 인자로 쓰이는 경우를 다뤄보자. 예시로 쓸 함수를 미리 만들어 본다.

// 매개변수에 const 키워드가 없는 함수
int        function_ptr(int * input)
{
    return 0;
}

// 매개변수에 const 키워드가 있는 함수
int        function_const_ptr(int const * input)
{
    return 0;
}

// 매개변수에 const가 붙어있음에도 변수의 값을 강제로 바꾸는 함수 (주석처리된 부분은 C언어 스타일 변환)
int        function_const_ptr_fraud(int const * input)
{
    const_cast<int&>(*input) = 1;
    // *(int*)input = 1;
    return 0;
}

3.1 인자가 int * const인 경우

int                foo = 10;
int const *        ptr = &foo;

// function(ptr);
function_const_ptr(ptr);
function_const_ptr_fraud(ptr);
  • function(int*)int const *인 ptr을 매개변수로 받을 수 없다.
  • function(int const *)int const *인 ptr을 매개변수로 받을 수 있다.
  • function_const_ptr_fraud(int const * input)constint형 자료의 변경을 제한하고 있음에도 불구하고 강제로 변환하였다.

3.2 인자가 원래 상수형인 경우

int const        foo = 10;
// function_ptr(&foo);
function_const_ptr(&foo);
function_const_ptr_fraud(&foo);
  • function_ptr(int *)은 당연히 "&foo"를 매개변수로 취할 수 없다.
  • function(int const *)은 "&foo"를 매개변수로 취할 수 있다.
  • function_const_ptr_fraud(int const * input)는 아까와 달리 값을 변경하지 못한다.

함수를 만들 때 귀찮더라도 const 키워드를 매개변수에 넣어야 const가 붙은 인자들을 받을 수 있다. const가 붙은 상수형 인자들은 까다로워서 아무 함수에나 안 들어간다. 상수형 인자들은 아무 것도 변경하지 않는 함수일지라도, 아무 것도 변경하지 않을 것임을 명시해야만 함수 안으로 들어간다.

그것이 const니까.

(대충 끄덕 하는 짤)


클래스와 const에 관해서는 다음에...

'컴퓨터 > C++' 카테고리의 다른 글

C++에서 파일 출력  (0) 2021.01.05