공부중

[C++] const 위치에 따른 상수화 되는 대상 본문

Programing/C, C++

[C++] const 위치에 따른 상수화 되는 대상

곤란 2020. 11. 9. 21:59
반응형

오늘은 const에 대해서 공부좀 해보려고한다.

매번 const에 대해서 공부하지만 머리가 안좋은 나는 매번 까먹는다.

그리고 이 블로그에 정리도 안되어있는걸보고 이번에 해봐야겠다고 생각했다.

 

const 키워드는 객체 또는 데이터 수정을 할 수 없도록 상수화해주는 키워드이다.

const int a = 100;
static const int b = 200;
const AAA aaa(20);

위와같이 사용이 가능하며 a와 b는 상수화가 되어서 각각 100, 200에서 변경이 불가능하다.

마지막 라인처럼 객체에 const 선언이 붙게 되면 이 객체는 const 멤버함수만 호출이 가능하다!

-> 이 객체의 데이터 변경을 허용하지 않으므로 변경가능성이 없는 const  멤버함수만 호출이 가능하기 때문.

 

위의 내용까지는 그러려니 하겠지만 조금은(?) 변태같은 아래의 소스코드를 보자.

#include <iostream>

int main()
{
	int a = 10;
	int* pa = &a;

	int b = 20;

	int const* pa1 = &a;
	int *const pa2 = &a;
	const int* pa3 = &a;
	const int const* pa4 = &a;
	const int* const pa5 = &a;
	int const* const pa6 = &a;

	pa1 = &b;
	*pa1 = 100;

	pa2 = &b;  
	*pa2 = 200;

	pa3 = &b;
	*pa3 = 300;

	pa4 = &b;
	*pa4 = 400;

	pa5 = &b;  
	*pa5 = 500;

	pa6 = &b;  
	*pa6 = 600;  

	return 0;
}

위의 코드에서 문제가 될 부분은 어디인가?

위의 코드를 보면 뭔가 const를 못쓰고 죽은 귀신이 적은듯한 그러한 코드인데..

정답은 아래와 같다.

#include <iostream>

int main()
{
	int a = 10;
	int* pa = &a;

	int b = 20;

	int const* pa1 = &a;
	int *const pa2 = &a;
	const int* pa3 = &a;
	const int const* pa4 = &a;
	const int* const pa5 = &a;
	int const* const pa6 = &a;

	pa1 = &b;
	//*pa1 = 100;  컴파일 에러

	//pa2 = &b;  컴파일 에러
	*pa2 = 200;

	pa3 = &b;
	//*pa3 = 300;  컴파일 에러

	pa4 = &b;
	//*pa4 = 400;  컴파일 에러

	//pa5 = &b;  컴파일 에러
	//*pa5 = 500;  컴파일 에러

	//pa6 = &b;  컴파일 에러
	//*pa6 = 600;  컴파일 에러

	return 0;
}

정답은 위와 같은데 이것에대한 해법을 말하자면 *의 위치에 따라서 달라진다.

*의 기준으로 const 키워드가 왼쪽에 있으면 포인터가 가리키는 대상이 상수가 된다.

*의 기준으로 const 키워드가 오른쪽에 있으면 포인터 자체가 상수가 된다.

*의 기준으로 양쪽에 있으면 포인터가 가리키는 대상과 포인터 자체 모두 상수가 된다.

 

하지만 곰곰히 생각을 해보았다.

뭔가 암기과목처럼 외우려면 저런 내용이겠지만

이건 *의 기준으로 const가 왼쪽에 있는것과 오른쪽에있는것으로 나뉘게 되는지에대한 답변은 되지 못한다.

 

2020/11/14 - [Programing/C, C++] - [C/C++] Right to Left Rules(오른쪽-왼쪽 규칙)

이 글을 읽어보면 *는 오른쪽에서 왼쪽으로 결합되는 방향이다. 그렇기 때문에 

int a = 10;
int b = 20;
int * const pa = &a;

pa = &b;    // 컴파일 에러
*pa = 100;

*의 우측은 const를 먼저 만나게 되므로 포인터 변수인 주소값을 변경할 수가 없게 되고

int a = 10;
int b = 20;
int const * pa = &a;

pa = &b;    
*pa = 100;    // 컴파일 에러

*의 왼쪽은 const를 읽고난 뒤 자료형을 만나게 된다. 즉 포인터가 가리키고 있는 자료형의 값을 변경할 수 없게된다.

int a = 10;
int b = 20;
const int * pa = &a;

pa = &b;    
*pa = 100;    // 컴파일 에러

이와같은 경우 const의 왼쪽에 *가 없으므로 포인터 변수인 주소값이 아닌 포인터가 가리키고 있는 자료형의 값을 변경할 수 없게 된다.

 

참고 : isocpp.org/wiki/faq/const-correctness#const-ptr-vs-ptr-const

 

반응형