레퍼런스(Reference)에 대한 고찰.

프로그래밍/C++ 2007/10/17 17:26
C++ 에서 쓰는 & 기호는 매우 여러가지의 의미가 있다.

1. 비트연산자로써 AND
2. 어드레스연산자로서 변수의 주소를 지칭한다
3. 레퍼런스를 정의한다.

1번의 경우 객체와 객체사이에 존재한다.  a & b
2번의 경우 객체앞에 존재 &a
3번의 경우 객체뒤에 존재 a&

The C++ Programming Language 에서 정의한 레퍼런스의 정의는 다음과 같다.

참조자(reference)는 객체에 대한 다른 이름(대체명)이다.
(A reference is an alternative name for an object 원문)

(이부분은 류광님의 트랙백으로 원문과 한글판이 틀린점을 확인하였기때문에 원문을
기준으로 원글을 수정합니다. 한글문장을 보았을때 원문이 alias의 뜻이라고 생각을
하였지만 제가 원서를 가지고 있지 않았기 때문에 확인하지 못한부분이었는데
류광님의 트렉백(http://occamsrazr.net/tt/166) 을 통해서 알 수 있었습니다.
또한 트랙백에서 참조에 대한 최적화 부분의 이야기도 나옵니다.
관심있는 분들은 트랙백을 꼭 보시기 바랍니다.
트랙백 감사합니다.

또 한가지  분명 책에는 두루뭉술로 서있는것을 책을 보면서 인용을 했는데도
두리뭉실로 썼다는 것은 두루뭉술이라는 올바른 한글을 지금까지 제대로
인식하지 못했었다는 것입니다. 이것에 대해서도 감사합니다.
수정: 두리뭉실 , 두루뭉술 모두 표준어라고한다. 단 두리뭉술 은 비표준어

예전에 포스트한 http://www.xevious7.com/204 인간의 인식능력에 관한글
처럼 , 역시 인간은 인식하고 있는 단어로 파악하는 뇌 구조를 가지고
있는 것 같습니다. 한 글자로 인식하는게 아닌 단어단위 또는 문장단위로
인식한다고 합니다. )

레퍼런스를 정의하는데는 다음과 같은 제약이있다.

1. 선언시 초기화 되어야된다.
2. 설정된 레퍼런스 값은 변경할 수 없다.

또한 참조자의 포인터를 받아 올 수도 없고 참조자의 배열을 정의하는 것도
불가하다. 참조자를 구현하는 방식은 여러방식이 있겠지만 책에서
설명한 방식은 단순하게 역참조 방식이다. 즉 포인터가 가르키는
주소를  참조한다. &a 이런씩이다. 이런이유로 레퍼런스 연산자가
&가 되지 않았을까 추정해본다. 개인적으로는 다른 적당한 기호가
남았다면 중의적으로 쓰면서 생기는 많은 오류를 제거할 수 있기 때문에
다른 기호를 섰을것이라고 생각된다.

더욱더 중요한것은 비야네씨가 레퍼런스를 만든 목적이다.

다시 비야네 스트롭스트룹씨가 쓴 The C++ Programming Language 의 문구를 살펴보면,

이 참조자는 함수의 인자와 반환값을 정희하는 데 일반적으로 잘 쓰이며,
특히 오버로딩 되는 연산자의 인자와 반환값을 정의하는 데도 주로 쓰인다.

특히라는 말에 주목할 필요가 있다. 왜 스트롭스트룹씨가 레퍼런스를 C++에
탄생시켰을까 라는 면을 볼수 있는 대목이다.
일단 만들어진 후에는 규칙대로 사람에 따라서 여러가지로 응용해서
쓸수 있겠으나 ,

원래의 목적은 바로 연산자의 인자와 반환값을 정의하는데 쓰기 위함이었다는
것이다.

다시말하면 , 간결한 코드를 위함이다.
이런 목적으로 본다면 레퍼런스를 써서 코드가 더욱더 애매해지고 복잡하게
하는 것은 원래의 목적과는 맞지 않는 사용방법이라 생각된다.
어떻게 사용하느냐는 취향이겠지만..

결국 전통적인 C에서의 call by reference 라 불리는 참조자(레퍼런스)라는 것이
C++에서 탄생하면서 구분을 위해  call by pointer 라 불리는 방식에 있어서 
값을 계산할때 * 연산자를 항상 써야 하는 불편을 해소하고 보기 좋게 만들기 위해서
만들어진 것이 레퍼런스라고 생각되어진다. 


(이 부분은 비야네씨가 직접 홈페이지에 써놓은 부분이 있다.
http://www.research.att.com/~bs/bs_faq2.html#pointers-and-references )

위 링크를 따라가면 볼수 있으나 적어보면,
void f1(const complex* x, const complex* y) // without references
{
complex z = *x+*y; // ugly
// ...
}

void f2(const complex& x, const complex& y) // with references
{
complex z = x+y; // better
// ...
}

윗 부분의 내용이다.  즉 * 연산자를 사용해되는 포인터와  정의후에
사용하지 않는 레퍼런스의 차이이다.

한가지 주목할 점은 이 답변이 나온 질문 그 자체이다.
why does c++ have both pointers and references?
즉 , 왜 c++은 포인터와 레퍼런스 두가지를 모두 가지고 있습니까?

라는 질문인데 다시말해서 레퍼런스는 위에서 언급한 편리함이 있을뿐이지
기능상으로만 보면 pointer만 충분하다.

물론 그 편리함의 이익과 손해에 대해서는 케이스바이케이스 일 것이고
사람의 취향이기 때문에 어떤것이 옳다 그르다라는 논쟁은 무의미 한것으로
생각된다.

개인적인 의견은 , 애초에 만든 목적에 맞게 사용하는 정도가 적당할 것 같다.

또하나는 이 참조자(Reference)로 인해 오해하는 용어가 있다

바로 Call by reference 라는 용어에 대한 것이다.

원래 Call by reference 는 컴퓨터과학에서 널리 쓰여지는 일반적인 용어로
C++ 에서는 언어자체에서 참조자(Reference)를 가지고 있기 때문에
call by reference 라 하면 이 참조자를 통한 접근방식으로 생각하지만
원래의 call by reference의 의미는 확정된 값대신(call by value방식)
함축적인 참조자를 쓴다는 의미이다.
즉 엄밀하게 말하면 C++에서 말하는 call by pointer 방식 call by Reference 방식
모두 call by reference 방식이다. 하지만 용어를 동일하게 쓰는 바람에
아마도 비야네 씨는 call by reference 라는 용어로 부터 Reference 라
명명 했겠지만 어찌되었든 많은 프로그래머에게 용어의 혼동을 일으키고 있다.

call by reference에 대해서 명확하지 상태에서 C++ 을 알고 있는 프로그래머에게
call by reference 라고 하면 C++의 언어에 정의는 참조자(Reference)에 의한
접근방식이라고 생각해버리는 오해를 일으킨다는 것이다.
그렇기 때문에 이런 용어를 쓸때 C++ 참조자에 의한 방식인지 원래의 의미의
call by reference 인지 (C++참조자에 의한 방식도 call by reference지만
원래 말하는 call by reference의 하나인것이지 전부인것이 아니다.)
설명해야 된다는 것이다. 벌써 이것을 설명하는 것도 같은 용어를 써버린
이유로 설명이 굉장히 복잡해진다.

참조자(Reference)덕분에 오로지 C++ 프로그래밍에서만
call by reference가 C++에서 제공되는 참조자에 의한 접근방식으로 알려져 있다는
사실을 알 필요가 있다.




top

Trackback Address :: http://xevious7.com/trackback/278

  1. Tracked from 류광의 번역 이야기 2007/10/20 19:05 DELETE

    Subject: C++의 참조에 대해

    별칭(alias)으로서의 참조(reference)에 대해(C++). TaocpHelp에도 참여하셨던 xevious7님의 레퍼런스(Reference)에 대한 고찰을 읽다가 한 가지 눈에 띈 것이 있어서 글을 씁니다. "참조자(reference)는 객체에 ..
  1. Appler 2008/02/29 14:34 MODIFY/DELETE REPLY

    이글을 참고 자료로 퍼 가겠습니다.

    Call by Reference 정의에 대해 이야기 나누고 싶어서요.

    삭제 요청하시면 바로 지우겠습니다.

    • xevious7 2008/02/29 23:39 MODIFY/DELETE

      기본적으로 링크를 권장합니다만,
      출처를 명확히 하신다면 괜챦습니다. :)

  2. 때릴꺼야 2010/10/03 18:36 MODIFY/DELETE REPLY

    네이버에 있는 C 카페로 퍼가려고 합니다. 전문을 가져가는 것은 아니고, 단지 링크로 '참고하세요' 정도...랄까요? ^^;;

Write a comment