스토리텔링 개발자

[Effective C++] 3. const 선호하기 본문

개발/Effective C++

[Effective C++] 3. const 선호하기

김디트 2024. 5. 14. 11:02
728x90

항목 3. 낌새만 보이면 const를 들이대보자

 

 

 

const
  • 소스코드 수준에서 외부 변경이 불가능하다는 의미적 제약을 붙이며, 컴파일러가 이 제약을 단단히 지켜준다.
  • 사용 범위
    1. 전역 및 네임 스페이스 유효 범위 안에서 상수 선언(정의)시
    2. 파일, 함수, 블록 유효 범위 내에서 static 객체 선언 시
    3. 클래스 내 정적 / 비정적 데이터 멤버 선언 시
    4. 포인터 자체 및 포인터가 가리키는 데이터 선언 시
    5. 함수 선언 시
      • 함수 반환값을 상수로 하면 안전성과 효율에 더해 사용 시 에러도 감소한다.
      • 매개변수, 지역객체의 수정이 필요 없다면 const를 붙이자.
      • 상수 멤버 함수로 선언하는 것의 이점 : 상수 객체만 호출할 수 있는 함수임을 표기함으로써 용도를 확실히 한다.

 

 

 

상수 포인터 사용법
  • * 을 기준으로 좌, 우에 붙는 const는 아래와 같은 의미이다.
    • const(포인터가 가리키는 대상) * const(포인터 자체)
  • STL 반복자는 포인터를 본뜬 것이므로 각각 다음의 의미를 가진다.
    • const iterator = T* const
    • const_iterator = const T*

 

 

 

const 사용 시 이점
  1. 클래스의 인터페이스 가독성이 좋아진다.
    • 사용자가 객체 함수로 객체를 변경 가능한지 불가한지 쉽게 인지할 수 있다.
  2. 상수 객체를 사용하여 코드 효율을 높인다.
    • 객체 전달을 상수 객체 참조자로 처리하면 포인터 만큼의 크기만 전달되므로 효율적이다.
  3. const 키워드 유무만으로도 함수 오버로딩이 가능하다.

 

 

 

'어떤 멤버 함수가 상수 멤버(const)'라는 의미
  1. 비트 수준 상수성(bitwise constness)( = 물리적 상수성(physical constness))
    • 어떤 멤버 함수가 그 객체의 어떤 데이터 멤버도 건드리지 않아야 const가 인정된다.
    • C++에서 정의하는 상수성이다.
    • 비트 수준 상수성 아래에서는 포인터가 가리키는 대상을 수정할 수 있으므로 이 경우엔 문제가 된다.
      • 포인터의 비트 자체는 변화하지 않으므로 비트 수준 상수성의 조건은 만족한다.
  2. 논리적 상수성(logical constness)
    • 일부 몇 비트 정도는 바꿀 수 있되 그걸 사용자측에서 알아채지 못하면 cosnt를 인정한다.
    • 되도록 논리적 상수성을 지킬 수 있도록 하자.
    • 내부에서 비트 수정을 하게 허용하려면 mutable 키워드(어느 순간에도 수정 가능하게 하는 키워드)를 사용하여 변수 선언을 해준다.

 

 

 

상수 멤버/ 비상수 멤버 함수가 기능적으로 같을 시
  • 코드 중복을 피하기 위해 비상수 버전이 상수 버전을 호출하게 만들자. 
return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]);
  • 상수 버전이 비상수 버전을 호출하면 안 되는 이유
    1. 상수 버전에서는 비상수 멤버 함수를 호출할 수 없다.(컴파일러 에러)
    2. 또한 비상수 멤버를 호출하게 하려면 상수 버전의 this(즉 const *this)에 const_cast를 적용해야 하나, 이는 재앙의 씨앗이 된다.
728x90
Comments