2

每一种面向对象的语言(或支持 OOP 的语言),无论是 C++、Java、Python、PHP 都有clone自己的函数,它可以返回对象的深拷贝或浅拷贝。谁能告诉我如何clone从头开始创建我自己的函数,无论是深拷贝还是浅拷贝?显然我不能使用任何语言结构serialize,更不用说clone它自己了!一个例子PHP会很棒,尽管任何其他语言也很好,但我需要知道如何去做,仅此而已。

4

2 回答 2

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

我假设您需要复制复杂对象的所有子元素(如图 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)
于 2012-10-20T11:42:50.967 回答
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 克隆 $obj; 和反序列化(序列化($obj));避开 __construct()-or。这样,您无需将其放入烤箱即可获得烘烤的物体。要克隆自己,您需要将其放入烤箱(更新)。但是你不知道每个对象的参数和 __construct-or 可能会破坏你!

不要重新发明核心语言轮子。你几乎不能!

PS也有无法克隆的对象。我现在想到了 SimpleXMLElement。您需要使用 simplexml_load_string($sxe->asXML()) 重新解析这个或导入到 DOM 节点并返回到 SXE。

于 2012-10-20T12:02:24.367 回答