객체 참조를 위한 레퍼런스 언제 사용하나

레퍼런스와 포인터

저는 프로그램을 작성할 때 객체를 저장할 위치와 프로그램의 각 모듈에서 객체를 가져오기 위한 방법에 대해서 항상 고민을 합니다. 객체는 레퍼런스와 포인터를 이용하여 참조할 수 있는데 레퍼런스와 포인터의 가장 큰 차이점은 참조하고 있는 객체가 항상 유효한지의 여부입니다.

레퍼런스는 참조 대상과 함께 초기화되어야 하기 때문에 의미 없는 객체를 참조할 수 없습니다. 반면, 포인터 변수에는 어떠한 값이든 저장할 수 있기 때문에 널 포인터를 포함해서 존재하지 않는 객체까지도 초기화할 수 있습니다. 그렇기 때문에 포인터로 참조하는 객체는 사실 포인터를 사용하기 전에 포인터의 값이 유효한지 미리 검사해야 합니다. 그러나 레퍼런스는 이러한 검사가 필요없습니다.

레퍼런스는 안전한가?

객체를 안전하게 참조하기 위해 항상 레퍼런스를 사용하면 좋을 것 같습니다만 어떤 경우는 참조 대상을 변경해야할 필요가 있는데 그런 경우는 포인터를 사용할 수 밖에 없습니다. 그러면 참조 대상을 변경할 필요가 없고, 참조 대상을 결정할 수 있을 때는 항상 레퍼런스를 사용할 수 있을까요?

불행이도 그렇지 않습니다. 레퍼런스는 참조 대상과 함께 초기화되어야 하지만, 이는 레퍼런스의 값이 항상 무언가를 참조하고 있다는 것이지 그 대상이 항상 유효하다는 것을 의미하지는 않습니다. 레퍼런스가 어떤 객체를 참조하도록 초기화된 뒤에 레퍼런스가 여전히 유효한 상태에서 레퍼런스가 참조하고 있는 객체는 해제될 수도 있습니다. 멀티 쓰레드 환경에서 충분히 가능한 상황이며 멀티 쓰레드 환경이 아니더라도 레퍼런스가 클래스 멤버 변수 등 긴 시간 동안 유지되는 경우라면 그렇습니다.

참조 대상과 함께 초기화 할 수 있고, 참조 대상을 변경할 필요가 없으며 동시에 개발자의 관점에서 참조 대상이 항상 유효한 범위 내에서만 레퍼런스를 사용해야 합니다. 만일 레퍼런스가 항상 유효할 것이라도 확신이 가지 않는다면 레퍼런스 보다는 포인터로 객체를 참조하고 포인터를 사용하기 전에 미리 포인터의 값이 유효한지 확인하는 것이 좋습니다.

레퍼런스를 사용하기 가장 좋은 곳은 바로 함수에서 객체를 전달받는 경우입니다. 함수를 호출하는 측에서는 객체를 포인터로 관리하더라도 함수의 파라미터로 전달된 객체가 함수 내부에서만 참조하고 더 이상 관여하지 않는다면 이러한 함수에서 객체를 참조할 때는 레퍼런스 변수로 참조하는 것이 좋습니다.

Comments are closed.

Website Built by WordPress.com.

Up ↑