-
Notifications
You must be signed in to change notification settings - Fork 105
/
Copy pathcloning.xml
171 lines (144 loc) · 3.96 KB
/
cloning.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 28529d3539b850e870e3aa97570f4db0e53daa03 Maintainer: Haohappy Status: ready -->
<!-- CREDITS: Luffy -->
<sect1 xml:id="language.oop5.cloning" xmlns="http://docbook.org/ns/docbook">
<title>对象复制</title>
<para>
在多数情况下,我们并不需要完全复制一个对象来获得其中属性。但有一个情况下确实需要:如果你有一个
GTK 窗口对象,该对象持有窗口相关的资源。你可能会想复制一个新的窗口,保持所有属性与原来的窗口相同,但必须是一个新的对象(因为如果不是新的对象,那么一个窗口中的改变就会影响到另一个窗口)。还有一种情况:如果对象
A 中保存着对象 B 的引用,当你复制对象 A 时,你想其中使用的对象不再是对象 B 而是 B
的一个副本,那么你必须得到对象 A 的一个副本。
</para>
<para>
对象复制可以通过 <literal>clone</literal> 关键字来完成(如果可能,这将调用对象的
<link linkend="object.clone">__clone()</link> 方法)。
</para>
<informalexample>
<programlisting>
<![CDATA[
$copy_of_object = clone $object;
]]>
</programlisting>
</informalexample>
<para>
当对象被复制后,PHP 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性
仍然会是一个指向原来的变量的引用。
</para>
<methodsynopsis xml:id="object.clone">
<type>void</type><methodname>__clone</methodname>
<void/>
</methodsynopsis>
<para>
当复制完成时,如果定义了 <link linkend="object.clone">__clone()</link>
方法,则新创建的对象(复制生成的对象)中的 <link linkend="object.clone">__clone()</link>
方法会被调用,可用于修改属性的值(如果有必要的话)。
</para>
<example>
<title>复制一个对象</title>
<programlisting role="php">
<![CDATA[
<?php
class SubObject
{
static $instances = 0;
public $instance;
public function __construct() {
$this->instance = ++self::$instances;
}
public function __clone() {
$this->instance = ++self::$instances;
}
}
class MyCloneable
{
public $object1;
public $object2;
function __clone()
{
// 强制复制一份this->object, 否则仍然指向同一个对象
$this->object1 = clone $this->object1;
}
}
$obj = new MyCloneable();
$obj->object1 = new SubObject();
$obj->object2 = new SubObject();
$obj2 = clone $obj;
print "Original Object:\n";
print_r($obj);
print "Cloned Object:\n";
print_r($obj2);
?>
]]>
</programlisting>
&example.outputs;
<screen role="php">
<![CDATA[
Original Object:
MyCloneable Object
(
[object1] => SubObject Object
(
[instance] => 1
)
[object2] => SubObject Object
(
[instance] => 2
)
)
Cloned Object:
MyCloneable Object
(
[object1] => SubObject Object
(
[instance] => 3
)
[object2] => SubObject Object
(
[instance] => 2
)
)
]]>
</screen>
</example>
<para>
可以在单个表达式中访问刚刚克隆的对象的成员:
</para>
<example>
<title>访问新克隆的对象的成员</title>
<programlisting role="php">
<![CDATA[
<?php
$dateTime = new DateTime();
echo (clone $dateTime)->format('Y');
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
2016
]]>
</screen>
</example>
</sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->