回答編集履歴
3
修正
    
        answer	
    CHANGED
    
    | @@ -1,2 +1,7 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
             | 
| 2 2 | 
             
            __cloneは、複製時に呼ばれるんですね。。
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            なので、__clone 内部の $this はコピーされた新しいFooクラスのインスタンスですね。。。
         | 
| 5 | 
            +
            失礼しました。
         | 
| 6 | 
            +
             | 
| 7 | 
            +
             | 
2
修正します
    
        answer	
    CHANGED
    
    | @@ -1,1 +1,2 @@ | |
| 1 | 
            -
            すいません、間違えたので | 
| 1 | 
            +
            すいません、間違えたので修正します。
         | 
| 2 | 
            +
            __cloneは、複製時に呼ばれるんですね。。
         | 
1
間違えた
    
        answer	
    CHANGED
    
    | @@ -1,106 +1,1 @@ | |
| 1 | 
            -
            こんにちは。
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            __clone は、オブジェクトの複製方法を定義する関数です。
         | 
| 4 | 
            -
            かならず、同じクラスの別インスタンスを return する必要があります。
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            おそらく実装したい__cloneメソッドの正解は以下のようになると推察します。
         | 
| 7 | 
            -
            ```PHP
         | 
| 8 | 
            -
                public function __clone(){
         | 
| 9 | 
            -
                 $f = new Foo();
         | 
| 10 | 
            -
                    $f->bar= clone $this->bar;
         | 
| 11 | 
            -
                    return $f;
         | 
| 12 | 
            -
                }
         | 
| 13 | 
            -
            ```
         | 
| 14 | 
            -
             | 
| 15 | 
            -
            例えば、次のようなクラスがあったとします。
         | 
| 16 | 
            -
            メンバ変数の $data は数値データ、 $barはBarクラスのインスタンスとします。
         | 
| 17 | 
            -
            ```PHP
         | 
| 18 | 
            -
            class Foo {
         | 
| 19 | 
            -
               private $data;
         | 
| 20 | 
            -
               private $bar;
         | 
| 21 | 
            -
             | 
| 22 | 
            -
               public function setData($data) { $this->data = $data; }
         | 
| 23 | 
            -
               public function getData() { return $this->data; }
         | 
| 24 | 
            -
             | 
| 25 | 
            -
               public function setBar($bar) { $this->bar = $bar; }
         | 
| 26 | 
            -
               public function getBar() { return $this->bar; }
         | 
| 27 | 
            -
            }
         | 
| 28 | 
            -
            ```
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            このクラスを複製する場合、メンバ変数のdata、barもそっくりそのままコピーすべきかどうか?
         | 
| 31 | 
            -
            ・・・というのはきっと、クラスの持つ性質や使われ方によって、変わってきます。
         | 
| 32 | 
            -
             | 
| 33 | 
            -
            ここでは、dataはコピーするけど、barはコピーしたくないとしましょう。
         | 
| 34 | 
            -
            その場合、次のように__cloneを実装します。
         | 
| 35 | 
            -
             | 
| 36 | 
            -
            ```PHP
         | 
| 37 | 
            -
            class Foo {
         | 
| 38 | 
            -
               private $data;
         | 
| 39 | 
            -
               private $bar;
         | 
| 40 | 
            -
             | 
| 41 | 
            -
               public function setData($data) { $this->data = $data; }
         | 
| 42 | 
            -
               public function getData() { return $this->data; }
         | 
| 43 | 
            -
             | 
| 44 | 
            -
               public function setBar($bar) { $this->bar = $bar; }
         | 
| 45 | 
            -
               public function getBar() { return $this->bar; }
         | 
| 46 | 
            -
             | 
| 47 | 
            -
               public function __clone() {
         | 
| 48 | 
            -
                    $f = new Foo();
         | 
| 49 | 
            -
                    $f->data = $this->data;
         | 
| 50 | 
            -
                    return $f;
         | 
| 51 | 
            -
               }
         | 
| 52 | 
            -
            }
         | 
| 53 | 
            -
            ```
         | 
| 54 | 
            -
             | 
| 55 | 
            -
            このように、__clone では
         | 
| 56 | 
            -
            $f = new Foo()
         | 
| 57 | 
            -
            で新しい自分自身のインスタンスを作り出し、それを return する必要があります。
         | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
            さて今度は、Barもコピーしたいとしましょう。
         | 
| 61 | 
            -
            その場合、次のcloneメソッドでは、意図するものと違う動きをする可能性があります。
         | 
| 62 | 
            -
            ```PHP
         | 
| 63 | 
            -
               public function __clone() {
         | 
| 64 | 
            -
                    $f = new Foo();
         | 
| 65 | 
            -
                    $f->data = $this->data;
         | 
| 66 | 
            -
                    $f->bar = $this->bar;
         | 
| 67 | 
            -
                    return $f;
         | 
| 68 | 
            -
               }
         | 
| 69 | 
            -
            ```
         | 
| 70 | 
            -
            なぜかというと、bar変数に入っているのは、Barクラスのインスタンスですから、
         | 
| 71 | 
            -
            例えばこんなコードがあったとすると
         | 
| 72 | 
            -
            ```PHP
         | 
| 73 | 
            -
             | 
| 74 | 
            -
            $bar = new Bar();
         | 
| 75 | 
            -
            $bar->value = 1:
         | 
| 76 | 
            -
             | 
| 77 | 
            -
            $a = new Foo();
         | 
| 78 | 
            -
            $a->bar = $bar;
         | 
| 79 | 
            -
             | 
| 80 | 
            -
            $b = clone $a;
         | 
| 81 | 
            -
             | 
| 82 | 
            -
            $bar = $a->getBar();
         | 
| 83 | 
            -
            $bar->value = 10000;
         | 
| 84 | 
            -
             | 
| 85 | 
            -
            $bar2 = $b->getBar();
         | 
| 86 | 
            -
            echo $bar2->value;
         | 
| 87 | 
            -
            ```
         | 
| 88 | 
            -
            結果は、10000です。
         | 
| 89 | 
            -
            $a の内部のBarクラスのインスタンスに加えた変化が、$b の内部のBarクラスのインスタンスにも反映されてしまいます。
         | 
| 90 | 
            -
             | 
| 91 | 
            -
            ```PHP
         | 
| 92 | 
            -
              $f->bar  =  $this->bar ;
         | 
| 93 | 
            -
            ```
         | 
| 94 | 
            -
            複製時にこのようにしてしまうと、同じBarクラスのインスタンスを与えてしまっているためです。
         | 
| 95 | 
            -
             | 
| 96 | 
            -
             | 
| 1 | 
            +
            すいません、間違えたので消します。。
         | 
| 97 | 
            -
            ```PHP
         | 
| 98 | 
            -
               public function __clone() {
         | 
| 99 | 
            -
                    $f = new Foo();
         | 
| 100 | 
            -
                    $f->data = $this->data;
         | 
| 101 | 
            -
                    $f->bar = clone $this->bar;
         | 
| 102 | 
            -
                    return $f;
         | 
| 103 | 
            -
               }
         | 
| 104 | 
            -
            ```
         | 
| 105 | 
            -
            barを別のインスタンスにするために clone を使います。
         | 
| 106 | 
            -
            clone を利用する以上、Barクラスにも、__cloneの実装が必要ですが・・・。
         | 
