개발하는 리프터 꽃게맨입니다.

[C++] const 를 언제 사용해야 할까? 본문

기타 개발 지식

[C++] const 를 언제 사용해야 할까?

파워꽃게맨 2023. 12. 28. 00:41

const라는 수식어는 Constant에서 따온 것으로

수학적으로 '상수'라고 부르며 '변하지 않는 값'을 뜻합니다.

 

항상 변할수 있는 값인 '변수'와는 반대 개념이죠.

 

처음에는 '상수'라는 개념을 어디에 사용하는지 궁금했으나,

대부분 상수의 능력은 프로그램이 어느 정도 커졌을 때 빛을 발합니다.

 

간단하게 상수가 사용되는 예시를 보여드리겠습니다.

 

1. 하드 코딩 방지

하드 코딩이란 데이터를 코드 내부에 직접 입력하는 것을 뜻합니다.

int main()
{
	int arr[100];

	for (int i = 0; i < 100; i++)
		arr[i] = 0;

}

 

위 코드는 전혀 이상한 코드가 아닙니다.

근데, for문의 '조건 블럭'을 보면 그냥 직접 100이라고 코딩해 두었죠.

만약, 배열의 사이즈가 50으로 바뀌면 어떻게 될까요?

 

맞습니다. 그냥 arr [50]에 맞춰 i < 50으로 바꾸면 되죠.

 

근데, for 이 하나가 아니라면?

for 이 50개만 되어도

사이즈만 바꾸고 싶으면 51개의 값을 수정해야 합니다.

골치 아프죠.

 

그래서 프로젝트를 진행할 경우

데이터의 값은 직접 넣는 것이 아닌 상수로 관리하는 것을 지향합니다.

 

int main()
{
	const int arr_size = 100;

	int arr[arr_size];

	for (int i = 0; i < arr_size; i++)
		arr[i] = 0;

}

 

이러면 arr_size 만 바꿔주면, 간단하게 코드를 조작할 수 있습니다.

 

만약, 거대학 수학 계산 프로그램이 있다고 칩시다.

분명 원에 대한 계산도 있겠고 원주율 값이 필요하겠죠.

 

이때, 모든 원에 대한 계산을 ~~ * 3.14처럼 하드 코딩했을 때,

"계산기에 대한 정확도를 높여야 하니, 3.14 1592로 변경하는 게 좋을 것 같습니다~"

라는 요청이 들어오면 매우 아찔한 상황이겠죠

 

그러므로, 진짜 필요한 경우가 아니라면 숫자를 직접 사용하지 않고

상수를 사용하여 코딩하는 것을 지향하도록 합니다.

 

2. 클래스 멤버 함수에서 굳이 멤버 변수에 쓰기(Write)를 하지 않을 때

C++ 코드나 문법을 뜯어보다 보면 다음과 같은 멤버 함수를 볼 수 있습니다.

class MyClass
{
public:
	int GetV1() const
	{
		return _v1;
	}

private:
	int _v1;
	int _v2;
};

 

멤버 함수 옆에 const가 붙어있는 모습인데,

const 멤버 함수는 해당 객체의 멤버 변수를 조작하지 못하도록 막습니다.

컴파일 에러를 발생시키죠.

 

이런 식으로 쓰기(Write)를 하지 않고 오로지 읽기(Read)만 할 것이다. 를 명시적으로 적어주면 좋은 점이

후에 프로그램이 커지면, 스스로도 자신이 무슨 함수를 작성했는지 까먹는 경우가 많습니다.

또, 협업할 경우에도 이것이 건드려도 되는 함수인지 아닌지 긴가민가 하는 경우도 많고요.

 

이 경우 const를 붙여주는 것만으로도

이 함수가 어떤 동작을 하는지, 내가 이 함수에 어떤 코드를 추가해야 하는지에 대한 힌트를 얻을 수 있습니다.

 

저는 가능하면 읽기 기능만 하는 함수에는 const를 명시하도록 신경 씁니다.

 

3. 매개 변수의 값을 변경하지 않고 읽기(Read)만 하고 싶은 경우

MyClass(const MyClass& other)
	: _v1(other._v1)
	, _v2(other._v2)
{

}

 

위 코드처럼 매개변수를 const로 받는 방법이 있습니다.

이 방법은 '매개변수로 받는 값을 읽기만 할 것이고 쓰기는 하지 않을 것이다.'라는 의도를 명시하고 있습니다.

 

이것이 상당히 쓸만한 경우는 레퍼런스(참조자), 포인터를 사용할 경우입니다.

'Call By Value' 방식으로 매개변수를 받았다면, 원본에 영향을 미치지 못하는 별개의 값이기 때문에

혹여나 실수로 데이터를 훼손시켰다 해도 큰 영향을 미치지 않습니다.

 

그러나 'Call By Address', 'Call By Reference'로 매개변수를 받았을 경우,

실수로 데이터를 훼손시켰을 때, 원본 데이터를 조작하는 참사가 발생할 수 있기에

매개변수를 읽기만 한다면 const 매개변수를 호출하도록 명시하는 것이 좋습니다.

 

 

흔히 이런 말이 있죠.

"개발하는 시간 이상으로 디버그/유지/보수 시간이 많이 걸린다."

개발을 공부하면 할수록 점점 공감되는 말입니다.

 

조금이라도 이런 사소한 실수를 막기 위해서, 언어 개발자들은

virtual, const, out, override ... 등 

많은 예방책을 만들어 놨죠.

 

프로젝트를 하다가 팀원들과의 불화를 피하기 위해

또, 자신을 위해

이런 문법을 최대한 신경쓰는 것을 지향하도록 합시다.