일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- exception
- more effective c++
- 오블완
- 상속
- 반복자
- 메타테이블
- UE4
- 영화 리뷰
- 게임
- 참조자
- reference
- 루아
- 티스토리챌린지
- effective stl
- 스마트 포인터
- 암시적 변환
- resource management class
- virtual function
- 다형성
- 영화
- 비교 함수 객체
- Smart Pointer
- lua
- Effective c++
- 함수 객체
- 언리얼
- 예외
- implicit conversion
- operator new
- c++
Archives
- Today
- Total
스토리텔링 개발자
[More Effective C++] 1. 포인터 vs 참조자 본문
728x90
항목 1 : 포인터와 참조자를 구분하자
포인터와 참조자의 차이
- 참조자 개념에선 '널 참조자(null reference)'라는 것이 없다. 즉,
- 포인터 사용
- 어떤 변수가 참조하는 부분에 객체가 없을 수도 있는 상황.
- 참조자 사용
- 어떤 변수가 가리키는 메모리가 항상 유효한 객체여야 하는 상황
- 포인터 사용
- C++ 스펙에 의하면 참조자는 선언될 때 반드시 초기화해야 한다.
// 참조자의 경우
string& rs; // 컴파일 에러. 초기화가 없다.
string s("xyzzy");
string& rs = s; // 컴파일 성공.
// 포인터의 경우
string* ps; // 초기화 되지 않은 포인터. 컴파일 성공. 허나, 무슨 값이 들어있을지..
- 참조자는 중간에 다른 객체를 참조하게 할 수 없다.
- 포인터의 경우
- 다른 객체의 주소값으로 얼마든지 바꾸어 셋팅할 수 있다.
- 참조자의 경우
- 초기화될 때 참조했던 객체만 참조할 수 있다.
- 포인터의 경우
string s1("Nancy");
string s2("Clancy");
string& rs = s1; // 참조자
string* ps = &s1; // 포인터
rs = s2; // ps는 여전히 s1이며, s1의 값에 Clancy가 덮어씌워진다.
ps = &s2; // ps는 s2를 가리키며, s1의 값은 변경되지 않는다.
미정의 동작을 유발하는 코드
char* pc = nullptr;
char& rc = *pc; // 널 포인터를 역참조한 것을 참조자에 할당!
- 컴파일은 되겠지만, 실행 결과는 예측할 수 없다.
- 이런 코드를 만들거면 차라리 참조자를 쓰지 말자..
포인터보다는 참조자를 쓰는 것이 더 효율적일 수 있다?
- 널 참조자가 없다 는 스펙이 참조자가 더 효율적임을 암시한다.
- 참조자는 쓰기 전에 유효성을 검사할 필요가 없다는 뜻이기 때문이다.
// 참조자의 경우
void printDouble(const double& rd)
{
// rd 유효성 검사 불필요.
// rd는 참조자이므로 값이 없을 리 없다.
coud << rd;
}
// 포인터의 경우
void printDouble(const double* pd)
{
if(pd) // 널 포인터인지 유효성 검사 필요
{
cout << *pd;
}
}
정리
- 포인터를 써야 하는 경우
- 딱히 가리킬 객체의 주소가 없을 때
- 하나의 변수를 가지고 여러 개의 객체를 바꾸어 참조해야 할 때
- 참조자를 써야 하는 경우
- 참조할 포인터가 처음부터 끝까지 존재할 것임을 알고 있을 때
- 참조하는 대상 객체를 바꿀 필요가 없을 때
- (특수 상황) 연산자 함수를 구현할 때
operator[] 함수 구현
- 이 연산자는 대입 연산자의 좌변으로 쓸 수 있도록 값을 반환해 주어야 한다.
- 즉, 참조자를 리턴하게 된다.
vector<int> v(10);
// 참조자 리턴의 경우
v[5] = 10; // operator[]의 반환값이 operator=의 좌변이 된다.
// 만약 포인터 리턴이라면?
// 사용성이 매우 불편해진다.
*v[5] = 10; // 이런 식으로 사용되어야 할 것이다.
- 포인터 리턴 형태의 단점
- *를 달고 사용해야 하므로, 사용성이 불편하다.
- 더군다나 *은 포인터의 벡터인 것처럼 보이게 만든다.
- 그러므로 참조자를 반환하도록 하자. (항목 30 참조)
참조
728x90
'개발 > More Effective C++' 카테고리의 다른 글
[More Effective C++] 6. operator++ / operator-- (0) | 2024.08.06 |
---|---|
[More Effective C++] 5. 암시적 변환 지양하기 (0) | 2024.08.05 |
[More Effective C++] 4. 불필요한 기본 생성자 미제공하기 (0) | 2024.08.04 |
[More Effective C++] 3. 다형성 객체의 배열 지양하기 (0) | 2024.08.03 |
[More Effective C++] 2. C++ 스타일 캐스팅 (0) | 2024.08.02 |
Comments