참조 – 1.참조변수의 생성

C++에서 사용하던 참조(reference)와 같은 기능을 PHP4에서 제공합니다. 참조는 객체를 사용할 때 필수적인 기능이므로 꼭 익혀두시기 바랍니다.

비유에 의한 설명

명선이라는 여자 아이가 살고 있습니다. 그런데 그 아이의 마음씨가 얼마나 좋은지 사람들이 명선이에게 천사라는 별명을 붙여주었습니다. 제가 천사같은 명선이에게 1000원을 주었다고 할 때 명선이에게 1000원을 주었지만 천사에게도 1000원을 준 것과 동일합니다.

< 본명과 별명 >

PHP에서도 이와 같이 특정 변수에 별명을 붙여 사용할 수 있습니다. PHP에서 이와 같이 별명을 만들 수 있는 기능을 참조(reference)라고 하며 PHP4.0.4부터 본격적으로 제공되기 시작했습니다.

< 변수 $a와 참조 $b >

이러한 별명 즉 참조변수를 생성하기 위해서는 아래와 같이 & 심볼을 사용합니다.

참조란 다른 이름을 가지고 동일한 변수에 접근할 수 있도록 하는 것입니다. C 또는 C++의 포인터와는 다르며 C++에서 새로이 추가된 참조와 같이 앞에서 정의된 변수에 대한 이름(변수명)의 대용으로 작용하는 이름입니다. 즉, 앞서 정의된 변수명에 대한 별명입니다. 따라서 이들 둘은 모두 같은 값, 같은 메모리의 위치를 참조합니다.

참조와 복사

참조가 하나의 변수를 두 개의 이름(변수명)으로 불려지는 것인 반면에 복사는 완전히 독립된 두 개의 변수를 만들게 됩니다.

예를 들어 $a으로 하여금 $b 변수를 참조하도록 만든다면 $a와 $b는 서로 다른 이름을 사용하기는 하지만 $a와 $b는 둘 다 동일한 장소(메모리 위치)를 가리키기 때문에 동일한 내용을 다루게 됩니다.

그러나 $a으로 하여금 $c 변수에 복사하게 되면 처음 복사할 때만 그 내용이 같을 뿐이며 이 후에 $a와 $c는 전혀 관계없이 동작하는 별개의 변수가 됩니다.

< 참조와 복사 >

변수명를 관리하는 심볼 테이블과 변수값이 저장되어 있는 메모리 상태를 살펴보면 다음과 같습니다. 여기서 표현된 것은 설명을 위해 개념적으로 나타낸 것이며 정확한 것은 아닙니다.

변수명 변수값이 저장된 메모리 주소 설명
$a 0x6000 원본
$b 0x6000 참조
$c 0x7000 복사

< 심볼 테이블 >

참조와 포인터

C 또는 C++에서 자주 보게 되는 포인터와 비교해보죠. 사실 참조로 구현할 수 있는 것은 포인터로 모두 구현할 수 있습니다. 그러나 양쪽이 모두 동일한 효과를 얻더라도 소스코드의 가독성를 보면 참조가 훨씬 명료합니다. PHP가 포인터를 지원하지 않으므로 여기서 비교할 필요가 없을 지도 모르겠으나 그냥 참고삼아 보시기 바랍니다. 만약 PHP에서 포인터를 지원한다면 위의 심볼 테이블에서 메모리 주소 0x6000 또는 0x7000 이라는 숫자를 직접 얻을 수 있겠지요.

아래 예는 C++로 작성된 코드로 함수의 매개변수로 전달된 두 변수를 교환하는 방법입니다.

위에서 보는 바와 같이 참조를 사용하면 포인터를 사용할 때보다 코드를 훨씬 쉽게 이해할 수 있습니다. 포인터가 일반적으로 훨씬 강력하고 폭넓은 능력을 발휘하기는 하지만 잘못 사용하면 시스템을 불안하게 하기 때문에 안정성이 우선인 웹프로그래밍 언어에서 포인터를 지원하기는 어려울 것입니다. 하지만 원본을 사용범위(scope)가 다른 곳에서 또는 다른 이름으로 안전하고, 편하게 다루게 해주는 참조가 있기 때문에 개발자는 포인터없이도 별 어려움없이 원하는 기능을 구현할 수 있을 것입니다.

자바에서의 객체 참조

자바에서는 PHP 또는 C++에서와는 달리 객체를 변수에 할당하거나, 객체를 매개변수로 메소드에 전달할 때, 전달되는 것은 이러한 객체의 참조(레퍼런스)이지 객체의 복사본이 아닙니다.

출력결과는 아래와 같습니다.

pt2 의 x와 y 인스턴스 변수 또한 바뀌었습니다. pt1의 값을 pt2로 할당했을 때, 정확히 말하자면 pt2로부터 pt1도 똑같이 참조하는 레퍼런스를 생성한 것입니다. pt2가 참조하는 객체를 바꾸게 되면, pt1이 가리키는 객체 또한 바뀌게 됩니다. 이들은 같은 객체를 참조하기 때문입니다.

만일 pt1과 pt2가 각각의 분리된 객체를 가리키게 하기를 원한다면 pt2 = pt1 대신에 pt2 = new Point(100, 100)을 사용하여야 합니다.

함수의 매개변수로 사용되는 참조

참조를 자주 사용하는 것 중에 하나가 함수에서의 매개변수입니다. 참조를 매개변수로 사용하면 그 함수는 복사본 대신에 자료의 원본을 가지고 작업을 합니다. 매개변수값이 큰 사이즈의 문자열 또는 객체일 때 복사본 가지고 작업한다면 우선 복사하는데 많은 시간이 소요될 것입니다. 또 작업한 내용을 되돌려 주어야 한다면 돌려주는데 또 시간이 많이 소요될 것입니다. 이럴 때는 처음부터 원본가지고 작업하면 유리하겠지요. 참조 기능 중 유일하게 이 부분만(일부이기는 하지만) PHP3에서도 제공되어 왔습니다. 자세한 것은 “참조에 의한 전달”을 보시기 바랍니다.

PHP에서 지원하는 참조 관련 기능

참조에 의한 함수 호출(call by reference)를 제외한 대부분의 기능은 PHP 4.0.4부터 가능합니다. 이러한 참조기능 – 참조변수 생성, 참조에 의한 함수호출 및 반환 – 은 C++의 참조를 모델로 구현되어 있습니다. 따라서 C++에서 참조를 사용하시던 분은 별 어려움없이 PHP 참조를 사용하시리라 봅니다.

답글 남기기