프로그래밍/C/C++2009. 8. 20. 17:32
포인터와 레퍼런스는 분명 차이가 있는 개념이지만 쉽게 혼용해서 사용할수 있기때문에 초보자들의 경우 많은 오해를 할 수 있습니다. 여느 C/C++ 프로그램들이 그렇듯이 잘못된 포인터, 레퍼런스의 사용은 프로그램을 hang 시키는 아주 심각한 결과를 초래하게 되므로 이에 대한 정확한 이해가 필요합니다.(참고로 C++에서는  포인터, 레퍼런스를 모두 지원하지만 Java, C#과 같은 고수준 언어에서는 레퍼런스만 지원합니다.)

포인터는 C/C++를 공부하는 사람이라면 누구나 아는것처럼 어떤 대상을 가리키는 것입니다.
레퍼런스는 어떤 대상을 지칭하는 또 하나의 이름이라는 의미가 있습니다.

무슨 말장난 처럼 들리겠지만 이 둘 사이에는 다음과 같이 분명하고 확실한 차이점이 있습니다.


1. NULL 포인터는 존재하지만 NULL 레퍼런스는 존재하지 않는다.
포인터는 어떤 대상을 가리킬수 있지만, 아무것도 가리키지 않을수도 있습니다. 후자의 경우 일반적으로 NULL 포인터라고 말합니다. 이와는 대조적으로 NULL 레퍼런스라는 것은 존재하지 않습니다. 이유가 무엇일까요?
레퍼런스란 어떤 대상을 지칭하는 또 하나의 이름이라는 뜻이 있다고 했는데, 여기서 말하는 어떤 대상이랑 반드시 존재하는 것입니다. 어떤 사람이 있다고 할때 이 사람의 이름과 이사람들 지칭하는 많은 별명들이 있을수 있습니다. 별명은 그 사람이 존재할 때 의미가 있는것이지, 존재하지도 않는 사람한테 별명을 붙일수는 없는 노릇이지요.
레퍼런스도 마찬가지 입니다. 존재하지 않는 대상에 대한 레퍼런스 따위는 아무 의미도 없습니다.
int main()
{
	int *a; // 정상
	int &b; // 에러
}
위 코드에서 처럼 초기화를 하지 않는 포인터의 선언은 가능하지만, 초기화를 하지 않는 레퍼런스의 선언은 컴파일러가 에러로 처리합니다. 레퍼런스는 반드시 선언과 동시에 초기화를 해야합니다.(멤버변수일 경우 생성자에서 초기화를 처리해줘야 합니다.)


2. 포인터는 가리키는 대상을 변경할 수 있지만 레퍼런스는 한번 대상을 지칭하면 변경할수 없다.
포인터는 타입만 다르지 않다면 한개의 포인터를 가지고 어떤 대상이든 자유롭게 가리킬수 있습니다.(설사 타입이 다르더라도 가능합니다!)  하지만 레퍼런스에서는 초기화시에 한번 지칭한 대상을 끝까지 변경할 수 없습니다.


만약 어떤 대상이 있고 이 대상을 포인터로 가리켜야 할지 레퍼런스로 참조해야 할지 헷갈린다면 다음과 같은 가이드라인을 따르도록 합니다.

  • 존재할수도 있고 아닐수도 있는 객체라면 이것은 포인터로 가리키게 한다.
  • 객체가 언제나 존재한다면 레퍼런스로 참조한다.
  • 특정 객체를 가리키고 있다가 다른 객체를 가리키고 싶다면 포인터를 사용한다.
  • 특정 객체의 생명주기를 예측할수 없다면 포인터를 사용한다.

보다 자세한 내용은 C++ 프로그래머의 필독서 이펙티브 C++(스캇 마이어스) 1장을 찾아보길 권합니다.
Posted by devop

댓글을 달아 주세요

  1. 지나가는이

    노란글씨가 보이지 않아요...
    좋은내용인데 글씨가 안보여서 건의드립니다..

    2011.12.22 10:38 [ ADDR : EDIT/ DEL : REPLY ]