回答編集履歴

3

修正

2016/01/20 07:21

投稿

Toyoshima
Toyoshima

スコア422

test CHANGED
@@ -1,5 +1,15 @@
1
- すいません、間違えたので修正します。
1
+
2
2
 
3
3
  __cloneは、複製時に呼ばれるんですね。。
4
4
 
5
5
 
6
+
7
+ なので、__clone 内部の $this はコピーされた新しいFooクラスのインスタンスですね。。。
8
+
9
+ 失礼しました。
10
+
11
+
12
+
13
+
14
+
15
+

2

修正します

2016/01/20 07:21

投稿

Toyoshima
Toyoshima

スコア422

test CHANGED
@@ -1 +1,5 @@
1
- すいません、間違えたのでします。
1
+ すいません、間違えたので修正します。
2
+
3
+ __cloneは、複製時に呼ばれるんですね。。
4
+
5
+

1

間違えた

2016/01/20 07:17

投稿

Toyoshima
Toyoshima

スコア422

test CHANGED
@@ -1,211 +1 @@
1
- こんにちは。
2
-
3
-
4
-
5
- __clone は、オブジェクトの複製方法を定義する関数です。
6
-
7
- かならず、同じクラスの別インスタンスを return する必要があります。
8
-
9
-
10
-
11
- おそらく実装したい__cloneメソッドの正解は以下のようになると推察します。
12
-
13
- ```PHP
14
-
15
- public function __clone(){
16
-
17
- $f = new Foo();
18
-
19
- $f->bar= clone $this->bar;
20
-
21
- return $f;
22
-
23
- }
24
-
25
- ```
26
-
27
-
28
-
29
- 例えば、次のようなクラスがあったとします。
30
-
31
- メンバ変数の $data は数値データ、 $barはBarクラスのインスタンスとします。
32
-
33
- ```PHP
34
-
35
- class Foo {
36
-
37
- private $data;
38
-
39
- private $bar;
40
-
41
-
42
-
43
- public function setData($data) { $this->data = $data; }
44
-
45
- public function getData() { return $this->data; }
46
-
47
-
48
-
49
- public function setBar($bar) { $this->bar = $bar; }
50
-
51
- public function getBar() { return $this->bar; }
52
-
53
- }
54
-
55
- ```
56
-
57
-
58
-
59
- このクラスを複製する場合、メンバ変数のdata、barもそっくりそのままコピーすべきかどうか?
60
-
61
- ・・・というのはきっと、クラスの持つ性質や使われ方によって、変わってきます。
62
-
63
-
64
-
65
- ここでは、dataはコピーするけど、barはコピーしたくないとしましょう。
66
-
67
- その場合、次のように__cloneを実装します。
68
-
69
-
70
-
71
- ```PHP
72
-
73
- class Foo {
74
-
75
- private $data;
76
-
77
- private $bar;
78
-
79
-
80
-
81
- public function setData($data) { $this->data = $data; }
82
-
83
- public function getData() { return $this->data; }
84
-
85
-
86
-
87
- public function setBar($bar) { $this->bar = $bar; }
88
-
89
- public function getBar() { return $this->bar; }
90
-
91
-
92
-
93
- public function __clone() {
94
-
95
- $f = new Foo();
96
-
97
- $f->data = $this->data;
98
-
99
- return $f;
100
-
101
- }
102
-
103
- }
104
-
105
- ```
106
-
107
-
108
-
109
- このように、__clone では
110
-
111
- $f = new Foo()
112
-
113
- で新しい自分自身のインスタンスを作り出し、それを return する必要があります。
114
-
115
-
116
-
117
-
118
-
119
- さて今度は、Barもコピーしたいとしましょう。
120
-
121
- その場合、次のcloneメソッドでは、意図するものと違う動きをする可能性があります。
122
-
123
- ```PHP
124
-
125
- public function __clone() {
126
-
127
- $f = new Foo();
128
-
129
- $f->data = $this->data;
130
-
131
- $f->bar = $this->bar;
132
-
133
- return $f;
134
-
135
- }
136
-
137
- ```
138
-
139
- なぜかというと、bar変数に入っているのは、Barクラスのインスタンスですから、
140
-
141
- 例えばこんなコードがあったとすると
142
-
143
- ```PHP
144
-
145
-
146
-
147
- $bar = new Bar();
148
-
149
- $bar->value = 1:
150
-
151
-
152
-
153
- $a = new Foo();
154
-
155
- $a->bar = $bar;
156
-
157
-
158
-
159
- $b = clone $a;
160
-
161
-
162
-
163
- $bar = $a->getBar();
164
-
165
- $bar->value = 10000;
166
-
167
-
168
-
169
- $bar2 = $b->getBar();
170
-
171
- echo $bar2->value;
172
-
173
- ```
174
-
175
- 結果は、10000です。
176
-
177
- $a の内部のBarクラスのインスタンスに加えた変化が、$b の内部のBarクラスのインスタンスにも反映されてしまいます。
178
-
179
-
180
-
181
- ```PHP
182
-
183
- $f->bar = $this->bar ;
184
-
185
- ```
186
-
187
- 複製時にこのようにしてしまうと、同じBarクラスのインスタンスを与えてしまっているためです。
188
-
189
-
190
-
191
- そのめ、こようにします。
1
+ すいません、間違えたので消します。
192
-
193
- ```PHP
194
-
195
- public function __clone() {
196
-
197
- $f = new Foo();
198
-
199
- $f->data = $this->data;
200
-
201
- $f->bar = clone $this->bar;
202
-
203
- return $f;
204
-
205
- }
206
-
207
- ```
208
-
209
- barを別のインスタンスにするために clone を使います。
210
-
211
- clone を利用する以上、Barクラスにも、__cloneの実装が必要ですが・・・。