참조 – 2.객체생성에서의 참조

생성된 객체를 복사하기

이 방법은 여러분이 지금까지 사용하였던 방법입니다.

위의 예를 통해 생성된 객체가 어떤 경로를 통해 $a 변수에 저장되는지 살펴보기로 하겠습니다.

1. new test

이 부분에 의해 클래스 test에 정의된 생성자 test() 함수가 실행됩니다. 생성자 내용이 모두 처리되면 생성자는 현재 생성된 객체를 나타내는 $this라는 특별한 변수를 되돌려 줍니다. 따라서 “new test”를 처리한 후 되돌려 받게 되는 값은 new 연산자에 의해 생성된 객체를 나타내는 $this라는 변수가 됩니다.

2. $a = new test

“new test”가 되돌려 주는 것이 새로 생성된 객체를 나타내는 $this라는 객체변수이므로 “$a = new test”는 “$a = $this”라고 생각할 수 있습니다. 실제로 이렇게 코딩하면 에러가 나겠지요. 왜냐하면 $this라는 변수는 객체 내에서만 사용되는 특수한 변수이므로 객체 외부에서는 절대로 사용할 수 없습니다. 그냥 이해한다는 면에서 “$a = $this”라고 한다면 이것은 일반적으로 알고 있는 $this라는 변수를 새로운 변수 $a에 할당하는 것이며, 결국 새로운 객체변수 $a를 생성되는 동시에 $this의 내용을 복사하게 된다는 것입니다.

< 객체 복사 >

위 그림에서는 멤버변수만 나타내었습니다. 메소드의 표현 방법은 멤버변수와는 전혀 다르기 때문에 여기서 생략하며 이에 대한 자세한 내용은 메뉴 “핍클래스홈 >> 객체에 관련된 정보”에서 “클래스와 인스턴스” 부분을 읽어 보시기 바랍니다.

3. echo $a->mb

복사된 객체 $a를 통해 멤버변수 $mb에 접근합니다.

생성된 객체를 참조하기

위의 소스 코드에서 클래스 정의 부분은 동일하며 아래 부분만 참조에 의해 수정하면 다음과 같습니다.

객체 복사와 같은 방법으로 생성된 객체가 어떤 경로를 통해 $a 변수에 저장되는지 살펴보기로 하겠습니다.

1. new test

이 부분은 객체 복사와 동일합니다.

2. $a = &new test

“new test”가 되돌려 주는 것이 새로 생성된 객체를 나타내는 $this라는 객체변수이므로 “$a = &new test”는 “$a = &$this”라고 생각할 수 있습니다. 이것은 앞장에서 살펴보았듯이 “new test”에 의해 생성된 $this라는 객체변수에 대한 별명(참조)을 하나 만드는 것입니다.

< 객체 참조 >

3. echo $a->mb

이 부분은 객체 복사와 동일합니다.

메모리 자원 사용

생성자에 있는 $this의 참조를 사용하기 위해서는 참조할당(reference assignment)을 사용하여야 하며 그렇지 않으면 두 개의 서로 다른 객체를 가지게 될 것입니다.

$this 라는 것은 “new test”를 수행할 때 생성자에서 되돌려 주는 $this를 의미합니다. new 연산자로 생성된 객체를 복사로 받으나 아니면 참조로 받으나 실행에는 전혀 차이가 없습니다. 차이가 있다면 서버 자원(resource)을 얼마나 효율적으로 사용하느냐는 것이지요. 첫번째 처럼 객체를 복사하게 되면 메모리 0x6000에 있는 객체는 페이지가 종료될 때까지 전혀 사용하지도 못하면서 서버 자원만 낭비하고 있는 것이지요. 하지만 객체를 참조하게 되면 생성된 객체를 $b에서 그대로 사용하기 때문에 자원 낭비가 전혀 없게 됩니다.

객체 복사할 때의 메모리

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

< 심볼 테이블 >

객체 참조할 때의 메모리

변수명 변수값이 저장된 메모리 주소 설명
$this 0x6000 원본
$a 0x6000 참조

< 심볼 테이블 >

메모리 자원을 사용하는데 있어 참조의 장점을 개념상 설명을 하였습니다만 PHP가 실제로 이 개념대로 구현된 것 같지는 않습니다. 정확한 것은 소스를 분석해 보아야 하겠으나 문서상의 설명으로 보면 객체 복사가 오히려 객체 참조보다 수행속도가 미세하나마 빠른 것으로 볼 때 PHP의 참조에 관련된 내부 구현 방식이 개념상 자바나 C++과는 다소 다른 것 같습니다. 따라서 현 시점(PHP 4.0.4 기준)에서 볼 때는 객체 참조가 꼭 요구되지 않는다면 객체 복사를 이용하는 것이 나을 것 같습니다. 그러나 향후 이 문제에 대하여는 PHP가 개선이 있어야 할 것으로 보입니다. 그러니 앞으로 객체 참조가 더 개선될 것을 대비하고 코드의 재사용을 고려하고 객체 복사와 객체 참조의 실행속도가 거의 차이가 없다는 것을 염두에 둔다면 그냥 객체 참조를 사용하는 것이 괜찮으리라 봅니다.

[Zend 엔진 2.0에서의 객체] Zend 엔진 1.0에서는 객체를 전달할 때 기본적으로 복사되어집니다. 그러나 Zend 엔진 2.0부터는 기본적으로 참조로 전달되어 집니다. 즉, 객체를 전달할 때는 참조기호 &가 필요없어진 것이지요. 그러니 PHP3 또는 Zend 엔진 1.0가 탑재된 PHP4로 작성된 문서에서 특별한 문제만 없다면 향후 호환성을 위하여 객체를 전달할 때는 참조기호 &를 사용하지 말기를 바랍니다.

답글 남기기