정체불명의 모모
[Effective C++] Const에 대해 알아보자 본문
안녕하세요.
이번에는 'effective c++'책에
있는 'const'내용에 대해 정리해 볼 겁니다.
'const'는 제가 알고 있는 이상으로 많은 역할을 한다는것을
책을 보고 알았네요.
역시...공부가 답이다.
여러분들도... ㅡㅜ 복붙이 아닌 공부를 하길...
그럼, 시작하겠습니다!
낌새만 보이면 const를 들이대 보자!
: const의 많은 역할에 대해 알아보자!
ㅁ const 의미 : const는 '의미적인 제약'을 주며(변경이 안되는), 컴파일러가 이 제약을 지켜준다는 것 입니다.
어떤 값을 불변이어야 한다는 제작자의 의도를 컴파일러 및 다른 프그래머와 나눌 수 있는 키워드 입니다.
- 클래스 밖에서 const의 사용 방법
- 전역 혹은 네임스페이스 유효범위의 상수를 선언합니다.
- 파일, 함수 , 블록 유효범위 에서 static으로 선언한 객체에도 const를 붙일 수 있습니다. - 클래스 내부에서 const의 사용 방법
- 정적 멤버 및 비정적 데이터 멤버 모두를 상수로 선언 할 수 있다. - 포인터에서 const의 사용 방법
- 포인터 자체를 상수로 할 수 있다.
- 포인터가 가리키는 데이터를 상수로 지정할 수 있다.
char greeting[] = "Hello"; // 비상수 포인터 char * p = greeting; // 비상수 데이터 const char *p = greeting; // 비상수 포인터, 상수 데이터 char * const p = greeting; // 상수 포인터, 비상수 데이터 const char * const p = greeting; // 상수 포인터, 상수 데이터
const 키워드가 *표의 왼쪽에 있으면 포인터가 가리키는 대상이 상수인 반면,
const가 *표의 오른쪽에 있는 경우엔 포인터 자체가 상수 입니다.
const 가 * 표의 양쪽에 다 있으면 포인터가 가리키는 대상 및 포인터가 다 상수라는 뜻입니다.
4. 반복자에서 const의 사용 방법
ㅁ STL 반복자는 포인터를 본뜬 것이기 때문에, 기본적인 동작 원리가 T* 포인터와 진짜 흡사합니다.
반복자는 자신이 가리키는 대상이 아닌 것을 가리키는 경우가 허용되지 않지만, 반복자가 가리키는 대상 자체는
변경이 가능합니다.
- 반복자를 const로 선언하면 포인터를 상수로 선언하는 것 과 같습니다.
- 변경이 불가능한 객체를 가리키는 반복자를 원하면 const_iterator를 이용하면 됩니다.
std::vector<int> vec;
// iter는 T* const 처럼 동작 합나디ㅏ.
const std::vector<int>::iterator iter = vec.begin();
*iter = 10; // 가르키는 대상의 데이터는 변경이 가능 하지만,
++iter; // Error! 가르키는 대상을 변경할 수 없습니다.
// cIter는 const T* 처럼 동작합니다.
std::vector<int>::const_iterator cIter = vec.begin();
*cIter = 10; // Error!가르키는 대상의 데이터를 변경 할 수 없습니다.
++cIter; // 대상은 변경할 수 있습니다.
5. 함수 선언에서의 const 의 사용 방법
- const 는 함수 반환 값, 각각의 매개변수, 멤버 함수 앞에 붙을 수 있고, 함수 전체에 대해 const의 성질을 붙일 수 있습니다.
- 함수 반환 값을 상수로 정해 주면, 안전성이나 효울을 포기하지 않고도 사용자 측의 에러 돌발 상황을 줄이는 효과를 가져다 줍니다.
6. const 매개변수
- 매개변수 혹은 지역 객체를 수정할 수 없게 하는것을 목적으로 선언 합니다.
7. 멤버 함수에 const 역할
- 해당 멤버 함수가 상수 객채에 대해 소출될 함수이다 라는 사실을 알려주는 것 입니다.
1. 클래스의 인터페이스를 이해하기 좋게 하기 위해서
: 클래스로 만들어진 객체를 변결할 수 있는 함수는 무엇이고, 또 변경할 수 없는 함수는 무엇인가를 사용자 쪽에서 알고 있어야
하는 것입니다.
2. 상수 객체를 사용할 수 있게 하자는 것입니다.
: 코드의 효율을 위해 아주 중요한 부분이기도 합니다.
객체 전달을 '상수 객체에 대한 참조자'로 진행하는 것이기 때문입니다.
위 내용이 제대로 할 수 있기 위해선 상수 상태로 전달된 객체를 조작할 수 있는 const 멤버 함수, 즉 상수 멤버 함수가 준비
되어야 한다는 것이 포인트 입니다.
※ const 키워드가 있고 없고의 차이만 있는 멤버 함수들은 오버로딩이 가능합니다.
ㅁ 어떤 멤버 함수가 상수 멤버라는 것이 어떤 의미 일까요??
1. 비트수준 상수성(물리적 상수성)
: 비트 수준 상수성은 어떤 멤버 함수가 그 객체의 어떤 데이터 멤버도 건드리지 않아야 그 멤버 함수가 'const'임을 인정하는 개념입니다.
즉, 그 객체를 구성하는 비트들 중 어떤 것도 바꾸면 안된다는 것 입니다.
비트 수준 상수성을 사용하면 상수성 위반을 발견하는데 힘이 많이 들지 않습니다.
c++에서 정의하고 있는 상수성이 비트 수준 상수성입니다.
그리고 상수 멤버 함수는 그 함수가 호출된 객체의 어떤 비정적 멤버도 수정할 수 없게 되어 있습니다.
2. 논리적 상수성
: 상수 멤버 함수라고 해서 객체의 한비트도 수정할 수 없는 것이 아니라 일부 몇 비트 정도는 바꿀 수 있되, 그것을 사용자측에서
알아채지 못하게만 하면 상수 멤버 자격이 있다는 것입니다.
! 이것만은 잊지 말자 !
* const를 붙여 선언하면 컴파일러가 사용상의 에러를 잡아내는 데 도움을 줍니다. const는 어떤 유효범위에 있는 객체에도 붙을 수 있으며, 함수 매개변수 및 반환 타입에도 붙을 수 있으며, 멤버 함수에도 붙을 수 있습니다. |
* 컴파일러 쪽에서 보면 비트 수준 상수성을 지켜야 하지만, 개념ㅈ먹인 상수성을 사용해서 프로그래밍 해야 합니다. |
* 상수 멤버 및 비상수 멤버 함수가 기능적으로 서로 똑같게 구현되어 있을 경우에는 코드 중복을 피하는 것이 좋은데, 이때 비상수 버전을 호출하도록 만드세요. |
'프로그래밍(c++)' 카테고리의 다른 글
[Effective c++] 캐스팅 4종류(종합 정리) (0) | 2021.10.26 |
---|---|
[C++] 가상 함수(virtual function) 와 가상함수테이블(virtual table) (0) | 2021.10.08 |
[c++] reinterpret_cast (0) | 2021.09.15 |
[c++ / 리눅스] Condition Variable (0) | 2021.09.15 |
[c언어] Mutex , cond 기본정리 (0) | 2021.09.14 |