phpclass/객체모델2002. 12. 21. 15:16
객체 역참조(Object Dereferencing)
참조 변수를 통한 역참조
Zend 엔진 1.0이 탑재된 PHP 4.0.4 이상 버전에서의 객체 역참조는 참조 연산자 &로 정의된 참조 변수를 통해 구현할 수 있었습니다.
[code php;gutter:false] <?php
class test {
var $mb;

function test($mb="default") {
$this->mb = $mb;
}
}

$a = &new test; // 객체 참조
?> [/code]
위의 예제에서 '$a = &new test'를 수행하게 되면 클래스 test로부터 생성된 객체 원본에 대한 참조변수 $a를 정의하게 됩니다.
[code php;gutter:false] <?php
.
. 생략
.

$a = &new test; // 객체 참조
echo $a->mb; // 객체 역참조
?> [/code]
'$a->mb'와 같이 참조변수 $a를 통하여 test로부터 생성된 객체 원본의 모든 멤버에 접근할 수 있으며 이와 같이 객체 참조를 통해서 역으로 객체 멤버에 접근하는 과정을 역참조(dereference)라 합니다.
Zend 엔진 2.0부터는 자바와 같이 객체가 참조로 전달되기 때문에 참조 연산자 &를 명기하지 않습니다. 위의 역참조 소스를 Zend 엔진 2.0이 탑재된 PHP 4 CVS (4.3.0-dev)용으로 재작성한다면 아래와 같게 되겠지요.
[code php;gutter:false] <?php
class test {
var $mb;

function test($mb="default") {
$this->mb = $mb;
}
}

$a = new test; // 객체 참조
echo $a->mb; // 객체 역참조
?> [/code]
Zend 엔진 2.0에서의 객체 역참조
Zend 엔진 2.0에서는 참조변수가 아닌 함수 또는 메소드로부터 반환된 객체를 통해 역참조할 수 있습니다. 이때 함수 또는 메소드로부터 반환된 객체는 당연히 참조가 되겠지요.
함수로부터 반환된 객체의 역참조(dereferencing objects returned from functions)
우선 Zend 엔진 1.0이 탑재된 PHP 4.0.4 이상 버전에서 함수로부터 반환된 객체를 역참조하는 예를 들어보지요.
[code php;gutter:false] <?php
class Circle {
function draw() {
print "Circle\n";
}
}

class Square {
function draw() {
print "Square\n";
}
}

function &ShapeFactoryMethod($shape) {
switch ($shape) {
case "Circle":
return new Circle();
case "Square":
return new Square();
}
}

$obj = &ShapeFactoryMethod("Circle"); // 함수로부터 반환된 객체 참조
$obj->draw(); // 객체 역참조
$obj = &ShapeFactoryMethod("Square") // 함수로부터 반환된 객체 참조
$obj->draw(); // 객체 역참조
?> [/code]
Zend 엔진 1.0이 탑재된 PHP 4.0.4 이상 버전에서는 위의 예에서 보는 것과 같이 반환되는 변수의 타입이 객체일 때 객체 그 자체가 아닌 참조로 반환하기 위해서는 참조 연산자 &를 붙여야 합니다.
그러나 Zend 엔진 2.0이 탑재된 PHP 4 CVS (4.3.0-dev)에서는 반환되는 변수의 타입이 객체인 경우에 참조 연산자 &를 붙이지 않더라도 기본적으로 객체 참조가 반환됩니다.
또한 Zend 엔진 1.0과는 달리 반환된 객체 참조를 또 다른 참조 $obj를 거치지 않더러도 함수로부터 반환된 객체 참조를 가지고 바로 역참조할 수 있습니다.
아래는 Zend 엔진 2.0이 탑재된 PHP 4 CVS (4.3.0-dev)에서 함수로부터 반환된 객체 참조를 가지고 역참조하는 예를 보여줍니다.
[code php;gutter:false] <?php
class Circle {
function draw() {
print "Circle\n";
}
}

class Square {
function draw() {
print "Square\n";
}
}

function ShapeFactoryMethod($shape) {
switch ($shape) {
case "Circle":
return new Circle();
case "Square":
return new Square();
}
}

ShapeFactoryMethod("Circle")->draw();
ShapeFactoryMethod("Square")->draw();
?> [/code]
정적 함수를 통한 또 다른 예를 보면 아래와 같습니다.
[code php;gutter:false] <?php
class Counter {
var $counter = 0;

function increment_and_print() {
print ++$this->counter;
print "\n";
}
}

class SingletonCounter {
static $m_instance = NULL;

function Instance() {
if (self::$m_instance == NULL) {
self::$m_instance = new Counter();
}
return self::$m_instance;
}
}

SingletonCounter::Instance()->increment_and_print();
SingletonCounter::Instance()->increment_and_print();
SingletonCounter::Instance()->increment_and_print();
?> [/code]
메소드로부터 반환된 객체의 다중 역참조(Multiple dereferencing of objects returned from methods)
아래의 예와 같이 역참조로 반환된 객체 참조를 가지고도 반복해서 역참조할 수 있습니다.
[code php;gutter:false] <?php
class Name {
function Name($_name) {
$this->name = $_name;
}

function display() {
print $this->name;
print "\n";
}
}

class Person {
function Person($_name, $_address) {
$this->name = new Name($_name);
}

function getName() {
return $this->name;
}
}

$person = new Person("John", "New York");
print $person->getName()->display();
?> [/code]
역참조된 멤버변수에 값 할당하기
역참조에 의해 메소드를 호출하거나 메소드의 값을 되돌려 받을 수 있음을 위에서 알아보았습니다. 역참조에 의해 접근된 멤버변수에 대하여도 값을 읽을 수도 있고 더 나아가 아래와 같이 값을 할당할 수도 있습니다.
[code php;gutter:false] <?php
class Name {
var $id;

function Name($_name) {
$this->name = $_name;
}

function display() {
print $this->name;
print "\n";
}
}

class Person {
function Person($_name, $_address) {
$this->name = new Name($_name);
}

function getName() {
return $this->name;
}
}

$person = new Person("John", "New York");
$person->getName()->id = "hwooky";
?> [/code]

Posted by 방글24