const키워드는 대상을 상수화하여 초기화 이후로 값 수정을 하지 못하게 만드는 키워드입니다.
상수에 대해서는 경쟁 상태가 발생하지 않으며, 프로그램 내의 객체가 값이 바뀔 수 없다는 것을 알면 프로그램을 해석하기가 매우 쉬워집니다.
c언어를 주로 사용했던 사람은 매크로를 사용하여 매직넘버를 대체하는 습관이 있는 경우가 있는데, c++에서는 이러한 케이스를 상수로 처리하는 것을 선호합니다.
- 매크로는 영향 범위가 너무 넓다
- 매크로보다 상수가 디버깅하기 쉽다
- 상수가 변경에 더 유리하다. (예: const 변수였던 것이 기획 의도 변경 등으로 런타임에 값이 변경되게 바뀌는 경우)
포인터 상수
// 포인터가 가리키는 대상의 값을 변경하지 못하게 막음
const int* val;
// 포인터가 가리키는 대상을 변경하지 못하게 막음
int* const val;
// 대상과 대상의 값 모두 변경하지 못하게 막음
const int* const val;
포인터에 상수 키워드를 사용하는 경우, 상수 키워드의 위치에 따라 다르게 동작합니다.
멤버함수와 상수
// 해당 함수 내에서 객체의 직접적인 수정이 일어나지 않음
int foo() const {...}
/// 해당 함수 내에서 a의 값은 불변
int bar(const int a) {...}
멤버함수의 파라메터에 const 키워드를 붙여 해당 파라메터가 상수라고 표기하거나, 멤버함수의 이름 뒤에 const 키워드를 사용함으로써 해당 함수 내에서 데이터 변수들의 수정이 일어나지 않음을 보장할 수 있습니다.
함수의 인자들의 값이 변경되는 경우도 드물지만, 이들에 대해 항상 const키워드를 적용하지는 않습니다. 이를 과하다고 보는 사람들도 있고, 해줘야 좋다고 생각하는 사람들도 있는듯. (단 포인터와 참조는 기본적으로 const 파라메터로 전달해 주는 것이 좋습니다)
기본적으로 멤버 함수들은 const로 만들어 주는게 좋습니다. 이렇게 해야 디자인의 의도를 더욱 명확히하며, 가독성을 높이고, 컴파일러가 더 많은 오류를 잡아낼 수 있게 도와줍니다.
const 멤버 함수의 경우에도 mutable하거나 포인터 멤버를 통해 접근되는 객체에 대해서는 값을 수정할 수 있습니다.
constexpr
객체나 함수 앞에 붙일 수 있는 키워드로, 해당 객체나 함수의 리턴값을 컴파일 타임에 알 수 있다는 의미를 가집니다.
constexpr키워드를 함수에 리턴 타입에 붙임으로써, 해당 함수의 결과가 컴파일 타임에 결정되는 것을 결정할 수 있습니다.
이러한 컴파일 타임 상수들은 별도의 헤더파일에 모아서 관리하는게 깔끔합니다.
const_cast
- const가 const가 아닌 걸로 바꾸는건 엄격히 제한이 되어서 포인터만 변경이 된다
- 다만, 이러한 경우 컴파일의 결과를 예측하기 매우 힘들어진다.
- 그냥 const로 정의된 변수를 런타임에 변경하려는 시도 자체를 하지 말자
참고
---
따배시++: https://www.youtube.com/watch?v=GC8cteuF-7E
https://www.youtube.com/watch?v=agrnNIyh7II
C++CoreGuidelines
'프로그래밍 > C++' 카테고리의 다른 글
230806 C++ 라이브러리 (0) | 2023.08.06 |
---|