티스토리 뷰
const는 변수를 상수화 시키는 키워드이다.
상수란?
상수란 변하지 않는 값을 뜻한다.
변수란 한 번 선언하면 값을 계속 바꿀 수 있지만,
상수는 처음 선언할 때만 값을 할당할 수 있으며 그다음부터는 값을 바꿀 수 없다.
상수와 리터럴의 구분
리터럴은 "문자 그대로"라는 뜻인데 C/C++에서는 "값 그 자체"를 뜻한다.
상수는 변수처럼 리터럴이 저장된 공간이다.
상수를 왜 쓰나?
프로그램을 작성할 때 고정되어 있어야 할 값을 변수에 저장해서 사용하다 보면 실수로 값을 바꿀 가능성이 있다.
상수는 값을 바꾸는 것을 방지하기 위해 사용하며, 코드의 의도를 명확하게 만들 수 있다.
const의 기본 사용 예시
const int num = 1;
num = 2; // 상수에 값을 할당하였기 때문에 컴파일 에러 발생
const 변수의 위치
아래 코드는 동일한 기능을 한다. 즉, 위치는 상관이 없다.
const int num = 1;
int const num = 1;
const 멤버 변수
const 변수는 반드시 선언 시 초기화를 해야 한다. 즉, 초기화하지 않으면 컴파일 에러가 발생한다.
따라서 class나 struct의 멤버 변수를 const로 선언 시에는 반드시 초기화 리스트(initialize list)를 사용해야 한다.
class ConstExample
{
const int num;
ConstExample(void) : num(3); // 정상
};
class ConstExample
{
const int num;
ConstExample(void)
{
num = 3; // Compile Error
}
};
const 포인터 변수
const 포인터 변수는, 일반 const 변수와 달리 const의 위치에 따라 의미가 달라진다.
1. 맨 앞에 위치할 때
const int * ptr = & num;
*ptr = 3; // compiler error
num = 3; // 정상
이는 포인터 변수가 가리키는 값을 상수화 시키는 것이다.
즉, *ptr의 값을 바꾸는 건 불가능하고, num을 바꾸는 건 가능하다.
2. 중간에 있는 경우
int num1 = 1;
int num2 = 2;
int* const ptr = &num1;
*ptr = 3; // 정상
ptr = &num2 // Compiler Error
포인터 변수 자체를 상수화 시킨다.
포인터 변수란 대상의 주소 값을 지정하는 변수이다. 위의 ptr은 ptr자체를 상수화 시키는 것이기 때문에, ptr의 주소 값을 바꾸는 것은 불가능하다.
3. 위 두 가지를 모두 사용한다면?
int num1 = 1;
int num2 = 2;
const int* const ptr = &num1;
*ptr = 5 // Compile Error
ptr = &num2 // Compile Error
함수에서의 const 사용
1. 매개 변수 자료형에 사용될 경우
int Function(const int num1, const int num2)
함수의 파라미터를 함수 내에서 변경하면 안 될 때, 이런 식으로 사용한다.
파라미터 값을 읽기만 가능하고 변경이 불가능하다는 이야기다.
2. 함수 선언에 사용되는 const 멤버 함수
class ConstExample
{
void print() const {...}; // const 멤버함수
};
const멤버 함수는 이 함수 내에서 멤버 변수 num1과 num2가 변경이 불가능하다는 뜻이다.
여기서 알아둬야 할 것은 const멤버 함수는 오버 로딩이 가능하다는 것이다.
즉, 보통 매개변수의 개수나 데이터 타입 등으로 구분하는 오버 로딩 방식처럼, const의 유무로 오버 로딩이 가능하다.
class ConstExample
{
void print() const { cout << " const print " << endl; };
void print() const { cout << " normal print " << endl; };
};
그렇다면 함수 호출할 때 어떻게 구분이 될까?
int main()
{
ConstExample object1;
object1.print(); // 실행결과 : normal print
}
const print함수는 const 선언한 객체에서 구분이 된다. 즉 아래와 같은 상황에서 구분이 될 수 있다.
int main()
{
ConstExample object1;
const ConstExample object2;
object1.print(); // 실행결과 : normal print
object2.print(); // 실행결과 : const print
}
3. 함수 맨 앞, 리턴 자료형에 사용하는 const
함수 맨 앞에 리턴 자료형에 있는 const는 말 그대로 리턴 값을 상수화 한다는 것이다.
const int Function()
{
return 10;
}
이 함수를 사용하려면 어떻게 해야 할까? const 키워드를 붙여서 받아야 할까?
const int Function()
{
return 10;
}
int main()
{
int num1 = Function();
const int num2 = Function();
num1 = 30;
num2 = 30; // compiler error
}
num2는 당연히 컴파일 에러가 날 것이고, num1은? 문제가 있을 것 같지만 에러가 나지 않는다.
즉, 리턴 값을 상수화 시켜 보호하는 것이지 , 그걸 할당받아서 사용하는 num1의 값 변경까지 보호하진 않는다. 그렇다면 const를 쓰는 의미가 없지 않나?라는 생각이 든다.
맞다. 함수 리턴 타입에 const를 사용할 때는 레퍼런스를 붙여 사용할 때 의미가 있다.
const int& Function(int n)
{
int& num1 = n; // 레퍼런스 임으로 리터럴 값을 할당할 수 없다.
return num1;
}
int main()
{
int& num2 = Function(); // error
const int& num2 = Function(); // 정상
}
reference : https://dojang.io
'IT > C, C++' 카테고리의 다른 글
[C++] 비트단위의 데이터 저장방법 (3) | 2022.10.06 |
---|---|
[C++] C++의 가상함수 동작 원리 (0) | 2022.09.16 |
[C/C++] Hash Table vs STL map (0) | 2022.09.15 |
Google C/C++ CodeStyle (0) | 2022.08.12 |
[C++] STL Vector 2차원 벡터 초기화(1D, 2D vector init) (0) | 2022.07.31 |
- Total
- Today
- Yesterday
- 리트코드
- 속초
- 기술면접
- 러스트 기초
- DP
- interview question
- Interview
- ProblemSolving
- 솔직후기
- Problem Solving
- PS
- 반드시 알아야 할 자료구조
- 속초 맛집
- 코딩인터뷰
- algorithm
- coding interview
- Medium
- 알고리즘
- Tree
- LeetCode
- 러스트
- 러스트 배우기
- 러스트 입문
- 자료구조
- C++
- 인터뷰
- 맛집
- rust
- 내돈내산
- 트리
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |