클래스 외부:전역, namespace 유효범위의 상수를 선언, static 객체 등에도 const를 붙일 수 있다.
포인터: * 뒤에 const를 붙여 상수포인터로 하거나 * 앞에 const로 포인터가 가리키는 데이터를 상수로 할 수 있고 const char* const p 처럼 상수포인터, 상수데이터로도 만들 수 있다.
const의 가장 강력한 용도는 함수 선언을 할 때이다.
포인터, 반복자와 [포인터•반복자•참조자]가 가리키는 객체, 함수의 반환값과매개변수, 지역변수는 물론 멤버함수, 함수전체 등 여러곳에서 사용될 수 있다.
이 함수 내에서는 멤버변수에 저장된 값을 변경하지 않겠다는 의미로
const 함수 내에서는 const가 아닌 함수의 호출이 제한된다.
const 참조자를 이용한다면 const 함수만 호출이 가능하다.
class Numclass{
private:
int num;
public:
int GetNum() const { return num; }
};
class NumberClass{
private:
int number;
public:
void initNum(const Numclass& num){
number = num.GetNum();
}
};
const 반환값은 안전성과효율성의 증가, 에러돌발상황감소 등 여러 상황을 효과적으로 막을 수 있다.
기존의 const 보다 더 상수성에 충실하며 일반화된 상수표현식 (Generalized constant expression)을 사용할 수 있게 해줌.
변수, 함수, 생성자 함수에 대하여 일반화된 상수표현식을 통해 컴파일 타임에 평가도리 수 있도록 처리해주는 키워드이다.
C++17부터는 람다함수에서도 constexpr키워드의 사용이 가능해졌다.
§ 변수에서의 사용
const와 constexpr의 차이점
[const]:const변수의 초기화를 런타임까지 지연시킬 수 있다.
[constexpr]:반드시 컴파일 타임에 초기화 되어있어야 한다.
따라서 초기화가 안되어있거나 상수가 아닌 값으로 초기화 시도하면 컴파일이 되지 않는다.
constexpr float x = 42.f; // OK
constexpr float y { 108.f }; // OK
constexpr int i; // error C2737: 'i': 'constexpr' 개체를 초기화해야 합니다. (uninitialized 'const i' [-fpermissive])
int j = 0; // error: 'int j' is not const
constexpr int k = j + 1; // error C2131 : 식이 상수로 계산되지 않았습니다.(the value of 'j' is not usable in a constant expression)
§ 함수에서의 사용
constexpr을 함수반환값에 사용시 다음의 제약이 있다.
1. 함수에 constexpr을 붙일 때는 inline을 암시한다.
2. 즉, 컴파일타임에 평가하기에 inline함수들과 같이 컴파일 된다.
만약 constexr의 함수인자들이 constexpr규칙에 어긋나면 컴파일타임에 실행되지 못하고 런타임에 실행된다.
constexpr int factorial(int n) {
// 지역 변수 없음, 하나의 반환문
return n <= 1 ? 1 : (n * factorial(n - 1));
}
// C++11에서는 컴파일 에러 발생
// C++14부터 가능
constexpr int factorial(int n) {
// 지역 변수
int result = 0;
// 여러 개의 반환문
if (n <= 1)
result = 1;
else
result = n * factorial(n - 1);
return result;
}