浅拷贝就比如像引用类型,而深拷贝就比如值类型。
浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。举个例子,一个人一开始叫张三,后来改名叫李四了,可是还是同一个人,不管是张三缺胳膊少腿还是李四缺胳膊少腿,都是这个人倒霉。
深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。比较典型的就是Value(值)对象,如预定义类型Int32,Double,以及结构(struct),枚举(Enum)等。
C#中有两种类型变量,一种 是值类型变量,一种是引用类型变量。对于前者,copy是属于全盘复制;而对于后者,一般的copy只是浅copy,相当于只传递一个引用指针一样。因此 对于后者进行真正copy的时候,也是最费事的,具体的说,必须为其实现ICloneable接口中提供的Clone方法。
浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用.
深拷贝(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的.
浅 拷贝和深拷贝之间的区别:浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象 中引用型字段的值他将反映在原是对象中,也就是说原始对象中对应的字段也会发生变化。深拷贝与浅拷贝不同的是对于引用的处理,深拷贝将会在新对象中创建一 个新的和原是对象中对应字段相同(内容相同)的字段,也就是说这个引用和原是对象的引用是不同的,我们在改变新对象中的这个字段的时候是不会影响到原始对 象中对应字段的内容。所以对于原型模式也有不同的两种处理方法:对象的浅拷贝和深拷贝。
class Test{ public: Test(int num) : _val(new int(num)) {} //Test(const Test &t) : _val(new int(*(t._val))) {} ~Test(){ delete _val; } private: int *_val; }; 现在定义两个对象, Test t1(9); Test t2(t1); 如果你不提供copy构造函数(注释掉的那个), 那么t1和t2的成员_val指向同一个对象, 当析构的时候, 同一个对象被析构了两次, 肯定出问题了. 反之, 提供了被注释的copy构造函数, t2的_val指向了一个新对象, 这样程序就没问题了. 前者就是潜拷贝, 后者就是深拷贝.
再次列举一个例子来说: 在编写C++程序中有时会用到,操作符的重载。最能体现深层拷贝与浅层拷贝的,就是‘=’的重载。 看下面一个简单的程序: class string { char *m_str; public: string(char *s) { m_str=s; } string(){}; string&operator=(const string s) { m_str=s.m_str; return *this} }; int main() { string s1("abc"),s2; s2=s1; cout<<s2.m_str; } 上面的 =重载其是就是实现了浅拷贝原因。是由于对象之中含有指针数据类型.s1,s2恰好指向同一各内存。所以是浅拷贝。而你如果修改一下原来的程序: string&operator(const string&s) { if(strlen(m_str)!=strlen(s.m_str)) m_str=new char[strlen(s.m_str)+1]; if(*this!=s) strcmp(m_str,s.m_str); return *this; } 这样你就实现了深拷贝,原因是你为被赋值对象申请了一个新的内存所以就是深拷贝。