如何编写我自己的克隆功能

时间:2012-10-20 11:36:46

标签: php oop clone

每种面向对象的语言(或支持OOP的语言),无论是C ++,Java,Python,PHP都有自己的clone函数,可以返回对象的深层或浅层副本。任何人都可以告诉我如何从头开始创建我自己的clone函数,用于深度和浅层复制?显然我不能使用serialize之类的任何语言构造,更不用说clone本身了! PHP中的一个例子会很棒,虽然任何其他语言都很好,我需要知道如何做到这一点,就是这样。

2 个答案:

答案 0 :(得分:6)

第1部分

/* 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/

第2部分

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。