The default copy constructor performs: B
A. Deep copy
B. Shallow copy
C. Hard copy
D. Soft copy
⑴浅复制(浅克隆,Shallow copy)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
⑵深复制(深克隆,Deep copy)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
在构造函数中,如果含有动态内存分配(即用malloc()或者new分配的内存),那么必须声明自己的实现(重新分配一个内存,将被拷贝内存中的数据拷贝过来),不可采用默认的构造函数(默认的是实现位拷贝(浅拷贝),机械的将拷贝对象中的指针指向被拷贝对象的内存)。假如不实现自己的拷贝函数,那么在传值调用的时候,它会产生问题。看看下面的例子:
void DoNothing(String localstring)
{
}
String s = "Hello, my house!";
DoNothing(s);
上面的代码看起来好象没有问题,但假如String类没有自己实现构造函数,那么就会出问题。因为被传递的参数localstring是一个值传递,如下图所示,它必须从s通过(缺省)拷贝构造函数进行初始化。由于String类没有自己实现一个拷贝构造函数,默认的拷贝构造函数将被调用。于是localstring拥有了一个s内的指针的拷贝(即localstring这个拷贝对象同样指向了s的内存部分)。当DoNothing()结束运行时,localstring离开了其生存空间,调用析构函数。其结果也将是:s包含一个指向localstring早已删除的内存的指针。
typdef struct _struct1
{
int a;
char b;
}struct1;
struct1 s1 = {1, ‘a’};
struct1 s2 = s1;//可以
typdef struct _struct2
{
int a;
char *p;
}struct2;
struct2 s1;
s1.a = 10;
s1.p = (char *)malloc(100);
struct2 s2 = s1;//这是一个浅拷贝,此时s1.p和s2.p指向了同一块内存,一旦将s1.p释放了,s2.p就是一个野指针了
free(s1.p);
s2.p=?野指针
深拷贝需要程序员自己实现:
struct2 s1;
s1.a = 10;
s1.p = (char *)malloc(100);
struct2 s2;
s2.a=s1.a;
s2.p=(char *)malloc(100);
memcpy(s2.p,s1.p,100);
free(s1.p);
即使将s1.p释放了,s2.p此时也不是野指针了,依然有效
Copyright 2011-2020 © MallocFree. All rights reserved.