개발 및 공부

C++) const의 쓰임

Hㅏㄴ량 2023. 12. 5. 23:40

const

const 키워드가 붙은 객체는 외부 변경이 불가능

char str[] = "Hello";

// 비상수 포인터, 비상수 데이터
char *p = str;

// 비상수 포인터, 상수 데이터
const char *p = str;

// 상수 포인터, 비상수 데이터
char* const p = str;

// 상수 포인터, 상수 데이터
const char* const p = str;

const가 * 왼쪽에 있을 경우 포인터가 가리키는 대상이 상수
const가 * 오른쪽에 있을 경우엔 포인터 자체가 상수

const 참조자의 장점

  1. 상수를 참조할 수 있기 때문에 함수의 parameter로 상수값을 바로 입력할 수 있다
  2. 그냥 자료형을 parameter로 전달할 경우 함수 호출시 내부에서 parameter 크기만큼 메모리 재할당이 일어남(복사 생성자). 참조자를 사용하면 동일한 메모리에 별칭만 부여하는 것이기 때문에 메모리 재할당이 없음
  3. 포인터와 달리 주소값 기반 접근을 하지 않기 때문에 다른 메모리에 접근할 일이 없어 보다 안전

const 멤버 함수

해당 멤버 함수가 const object에 의해 호출될 함수라는 것을 알려주는 역할
-> 객체 전달을 reference-to-const로 진행해 프로그램 성능을 높일 수 있음

참고: 참조와 const (Reference and const), [C++] const reference, return by reference

멤버 함수의 상수성

  • 비트수준 상수성(bitwise constness), 물리적 상수성(physical constness):
    객체를 구성하는 어떤 bit도 건들지 않아야 함. 데이터 객체에 대한 대입 연산이 일어났는지만 확인하면 되기 때문에 컴파일러가 쉽게 잡아냄.

  • 논리적 상수성(logical constness)

    class CTB{
    public:
      char& operator[](std::size_t position) const
      { return pText[position]}
    private:
      char *pText;
    }
    

const CTB cctb("Hello");
char *pc = &cctb[0];
*pc = 'J';
// 이러면 cctb는 "Jello"가 됨

```
위 경우처럼 const object를 생성하고 const 멤버함수를 호출했더니 값이 변하는 경우가 생김. 논리적 상수성은 object의 일부 비트는 바꾸더라도, 사용자가 알아채지 못한다면 괜찮다는 정도.
const 멤버함수 내부에서 값이 수정되기 위해서는 해당 변수에 mutable 키워드를 붙여줘야함.

멤버함수의 const/non-const

같은 함수의 const/non-const 오버로딩을 할 때엔

  1. const 멤버함수를 먼저 선언하고
  2. non-const 멤버함수는 내부에서 argument를 static_cast로 const object로 만들고
  3. const 멤버함수를 호출한 후
  4. return 값을 const_cast로 non-const object로 캐스팅
    하는 방식으로 구현 가능