每种面向对象的语言(或支持OOP的语言),无论是C ++,Java,Python,PHP都有自己的clone
函数,可以返回对象的深层或浅层副本。任何人都可以告诉我如何从头开始创建我自己的clone
函数,用于深度和浅层复制?显然我不能使用serialize
之类的任何语言构造,更不用说clone
本身了! PHP
中的一个例子会很棒,虽然任何其他语言都很好,我需要知道如何做到这一点,就是这样。
答案 0 :(得分:6)
/* memcpy example */
#include <stdio.h>
#include <string.h>
struct {
char name[40];
int age;
} person, person_copy;
int main ()
{
char myname[] = "Pierre de Fermat";
/* using memcpy to copy string: */
memcpy ( person.name, myname, strlen(myname)+1 );
person.age = 46;
/* using memcpy to copy structure: */
memcpy ( &person_copy, &person, sizeof(person) );
printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );
return 0;
}
取自http://www.cplusplus.com/reference/clibrary/cstring/memcpy/
1 http://i45.tinypic.com/176ddy.png
我假设您需要复制复杂对象的所有子元素(如在图1中复制虚构对象A,如果您只需要复制黑色对象但保留上面链接的代码,则可以使用其他作为参考,下面的伪代码适用于如果你想复制其所有子项目) 上图显示了现实以及我们如何看待对象
function MyCloneRecursive(object A) : object
{
pointer Cpy;
allocate memory to Cpy;
memcpy(&Cpy,&A,sizeof(A))
//now copy all its child elements
//assuming there is a way to do a foreach that
//for object A there are A.B,A.C and inside A.B there is D
//and childname={"B","C"} and inside of B childname={"D"}
for each childname in object A
{
eval("Cpy." + childname + "=MyCloneRecursive(A." + childname + ")");
}
}
//note this is really bad programming
//clone function is better written in the runtime
//(or its a part of the intepreter not a includable code)
答案 1 :(得分:1)
我将在这里介绍PHP:
// Bad class
class Obj{
private $_Property = 'value';
public function __construct(){
if(!func_num_args()){
throw new \InvalidArgumentException('Needs arguments.');
}
}
}
// Instantiate
$obj = new Obj(1);
// Clone
$obj1 = clone $obj;
// Deep clone
$obj2 = unserialize(serialize($obj));
// Dump all (see it worked)
var_dump($obj);
var_dump($obj1);
var_dump($obj2);
// Now try to clone yourself
$objclass = get_class($obj);
// But you don't know the arguments for every class.
// And drama unfolds here, exceptions get thrown!
$obj3 = new $objclass();
PHP clone $ obj;和反序列化(serialize($ obj));避开__construct() - 或。通过这种方式,您可以在不将其放入烤箱的情况下获得烘焙物品要克隆自己,你需要将它放入烤箱(新的)。但是你不知道每个对象的参数和__construct - 或者可能会破坏你!
不要重新发明核心语言轮。你几乎不能!
PS :还有一些无法克隆的对象。 SimpleXMLElement现在浮现在我的脑海中。您需要使用simplexml_load_string($ sxe-&gt; asXML())重新解析这个,或者导入到DOM节点并返回到SXE。