-
ch01-03. const 들이대기 2effective c++ & c++ 2022. 8. 31. 21:33
상수 멤버 함수
해당 멤버 함수가 상수 객체에 의해 호출될 함수임을 의미.
상수 멤버 함수의 의미
1. 물리적 상수성(=비트 수준의 상수성)
2. 논리적 상수성
물리적 상수성(=비트 수준의 상수성)
어떤 멤버 함수가 그 객체의 어떤 데이터 멤버도 건드리지 않아야 정적 멤버 함수임을 인정.
컴파일러는 테이터 멤버에 대입 연산의 수행 여부만 파악하면 된다.
class CTextBlock { private: char* pText; public: char& operator(size_t pos) const { return pText[pos]; } }; ... const CTextBlock cctb("Hello"); char *pc = &cctb[0]; *pc = 'J'; // 물리적 상수성은 만족하지만 멤버함수 반환형이 const가 아니여서 참조를 통한 값 변경 가능.
논리적 상수성
상수 멤버 함수라 해서 객체의 한 비트도 수정할 수 없는 것이 아니라, 일부 몇 비트 정도는 바꿀 수 있되
그것을 사용자측에서 알아채지 못하게 한다면 상수 멤버 자격이 있음을 의미.
mutable 키워드를 통해 구현 가능하다.
class CTextBlock { private: char *pText; mutable size_t textLength; //pText의 길이값이기 때문에 사용자가 이를 직접 수정할 수 없게 해야함. mutable bool lengthIsValid; public: size_t length() const; }; size_t CTextBlock::length() const { if(!lengthIsValid) { textLength = strlen(pText); lengthIsValid = true; } return textLength; }
** mutable 키워드는 const가 붙은 구조체나 클래스,멤버 함수에서 특정 멤버 변수의 수정을 허용하는 키워드이다.
mutable int a; int mutable b;
멤버 변수의 자료형 앞,뒤에 붙는 게 동일한 의미이고 가능하다.
상수 멤버 함수가 중요한 이유
1. 해당 멤버 함수로 구성된 클래스의 객체를 변경할 수 있는 함수를 구분.
2. 상수 객체를 사용 가능하게 함. (상수 객체는 상수 멤버 함수만 호출 가능하기 때문이다.)
** 상수 객체가 생성되는 경우에는
1. 상수 객체에 대한 포인터로 객체가 전달되는 경우
2. 상수 객체에 대한 참조자로 객체가 전달되는 경우 -> 프로그램의 실행 성능을 높이는 핵심 기법 중 하나.
두가지가 있다.
void print(const TextBlock& tb) // 상수 객체로 사용된 tb { cout<<tb[0]; ... }
const의 있고 없고의 차이만으로 멤버 함수의 오버로딩이 가능하다.
class TextBlock { private: string text; public: const char& operator[](size_t pos) const { return text[pos]; } char& operator[](size_t pos) { return text[pos]; } };
상수 멤버 함수와 비상수 멤버함수가 const를 제외한 모든 기능이 동일할 경우
비상수 버전의 멤버함수에서 상수 멤버 함수를 호출하도록 만든다.
(상수 멤버 함수에서 비상수 멤버 함수를 호출하는 것은 안정성에 문제가 된다.)
class TextBlock { public: const char& operator[](size_t pos) const { ... return text[pos]; } char& operator[](size_t pos) { return const_cast<char&> //상수 operator[]의 반환값에서 const를 떼어내는 캐스팅 ( static_cast<const TextBlock&>(*this)[pos] //*this에 const를 붙이는 캐스팅 ); } ... };
# const_cast와 static_cast 에 대해 복습해보자.
- 형 변환 연산자
1. static_cast 연산자
- static_cast <T> (변환의 대상) 형태로 사용.
- T에는 객체의 포인터 또는 참조형이 와야한다.
- 유도 클래스의 포인터 및 참조형 데이터를 기초 클래스의 포인터 및 참조형 데이터로 형 변환 가능.
- 기초 클래스의 포인터 및 참조형 데이터를 유도 클래스의 포인터 및 참조형 데이터로 형 변환 가능.
class Car { ... } class Truck : public Car { ... } int main() { Car* pcar2=new Car(120); Truck* ptruck2=static_cast<Truck*>(pcar2); }
- 기본 자료형 데이터 간의 형 변환에도 사용 된다.
- 상수 객체 -> 비상수 객체로의 변환을 허용하지 않는다.
2. const_cast 연산자
- const의 성향을 삭제하는 형 변환을 목적으로 한다.
- const_cast<T>(expr)
- const 선언으로 인한 형의 불일치가 발생해서 인자의 전달이 불가능한 경우에 유용하게 사용된다.
'effective c++ & c++' 카테고리의 다른 글
ch02-1. 생성자, 복사 생성자, 복사 대입 연산자, 소멸자 (2) 2022.09.21 ch01-4. 객체를 사용하기 전에 객체를 반드시 초기화하자. (0) 2022.09.06 ch 01- 03 . const 들이대기1 (0) 2022.08.29 ch01. 가급적 선행 처리자 보다 컴파일러를 활용하자. (0) 2022.08.25 ch.01 c++을 어떻게 바라보면 좋을까 (0) 2022.08.23