Adaid's Workroom
[세가] 팁:참조 본문
간단하게 말하자면 참조는 기능을 제한한 포인터이다.
참조와 포인터
//만들때
int& aRef = a;
int* aPtr = &a;
포인터는 &를 붙여서 주소로 만들어야 하지만 참조는 그럴 필요가 없다.
//사용할 때
aRef = 10;
*aPtr = &a;
포인터는 *를 붙여야 하지만 참조는 *을 붙이지 않아도 된다.
차이1: 초기화 필요
포인터는 무엇을 가리키는지 알 수 없는 것도 만들 수 있지만 참조는 반드시 무언가로 초기화해야한 한다.
차이2: 가리키는 대상 변경 불가
참조는 도중에 참조하는 대상을 변경할 수 없다.
차이3: 첨자, 덧셈 사용 불가
포인터는 배열에 접근하거나 숫자를 더해 다음 요소를 가리킬 수 있지만 참조는 불가능하다,
참조의 유용한 점
1. 반드시 뭔가 지정해야 하므로 초기화를 잊는 실수가 일어나지 않음
2. 지정한 대상이 변경되어 생길 수 있는 실수가 일어나지 않음
3. 배열 접근으로 인한 실수가 일어나지 않음
참조는 포인터에서 위험한 부분을 보완할 수 있다.
예를 들어 함수에 포인터를 전달해서 포인터 안에 계산 결과를 넣는 일이 자주 있는데
이때 void foo(int& a) 와 같이 참조를 사용하면 안정성을 높일 수 있다.
반환값을 사용할 수 없는 사정이 있을 때는 인수로 포인터를 전달해 값을 얻어오는데
여기서 참조를 대신 사용하면 포인터를 조작할 떄 생길 수 있는 위험을 막을 수 있다.
성능 향상을 위한 포인터와 참조
C++에서 클래스를 그대로 함수에 전달하면 복사본이 만들어진다.
이런 때는 포인터를 사용할 수 있다.
int sum(const T* t)...
int r = sum(&t); //호출
t에 있는 내용을 변경할 계획이 없으므로 const T*라 작성하였다.
포인터로 전달하는 경우에는원본이 바뀌기 때문에 변경되는 것을 막고자 const가 필요하다.
int sum(const T& t)...
int r = sum(t); //호출
포인터를 참조로 바꾸면 다음과 같은 장점이 있다.
1. &를 쓰지 않아 편리
2. 포인터를 쓸 때 생기는 위험을 방지
3. 함수 안 코드 깔끔
그래서 int, float 이외 클래스를 함수에 전달할 때는 대개 참조를 사용한다.
참조의 문제점
참조를 사용할때의 문제점은 함수안에서 인수 내용이 변경될 가능성이 있는지 유무는 호출하는 쪽 코드만 봐선 알 수 없다는 것이다.
만약 포인터로 sum(&t)와 같이 건넸다면 함수를 호출하는 형식을 보고
'여기서 내용이 변경되었을지도 모른다'고 의심할 수 있지만 참조는 그럴수 없다.
그래서 '값이 변경될 때는 포인터를 건네고 변경되지 않을 때는 참조를 사용한다'는 규칙을 세우면 좋다.
이 규칙을 지키면
- &가 붙으면: 내용이 변경되는 함수
- 그대로 전달하면: const가 붙은 참조이므로 안전
라는 것을 알 수 있다.
참조 '반환'에 주의
const A* getA() const { return &a; }
멤버변수의 포인터를 반환하는 함수는 흔히 볼 수 있다.
멤버변수가 int나 float이 아닐 때 복사하는 데 시간이 걸리고, 값이 변경되길 원하지 않으므로 const 포인터로 반환한다.
참조를 사용하게 되면
const A& a = t.getA();
와 같은 떄는 문제가 없으나
A a = t.getA();
는 A클래스가 클 경우 거대한 복사가 발생한다.
그러므로 '멤버 클래스는 포인터로 반환'하는 것을 규칙으로 하는것이 좋다.
지역 참조 반환은 헛수고
포인터와 참조 모두에서 논외로 하는 사용방법이 한 가지 있으므로 주의해아한다.
T& foo() {
T a;
return a;
}
와 같이 함수 안에서 만든 지역변수 참조를 반환하는 것이다.
함수가 종료되는 시점에서 a는 소멸되므로 참조 내용이 올바르지 않게 된다.
포인터 반환도 마찬가지이다.
결국 참조도 포인터의 일종이라는 점을 명심해야 된다.
'서적 공부 > 게임 프로그래밍의 정석' 카테고리의 다른 글
[세가] 팁:포인터와 메모리 (0) | 2017.12.20 |
---|---|
[세가] 팁:플래그 (0) | 2017.12.19 |
[세가] C++ 보충 (2) (0) | 2017.12.19 |
[세가] C++ 보충 (1) (0) | 2017.12.17 |
Comments