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