C++深拷贝与浅拷贝
拷贝有两种:深拷贝,浅拷贝。
当出现类的等号赋值时,会调用拷贝函数,在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函数——即浅拷贝,它能够完成成员的一一复制。当数据成员中没有指针时,浅拷贝是可行的。但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址,当对象快结束时,会调用两次析构函数,而导致指针悬挂现象。所以,这时,必须采用深拷贝。
深拷贝与浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间来储存数据,从而也就解决了指针悬挂的问题。简而言之,当数据成员中有指针时,必须要用深拷贝。
----------------------------------
补充.NET相关知识:
引用对象的浅拷贝原理:
引用对象之间的赋值之所以执行的是浅拷贝动作,与引用对象的特性有关,一个引用对象一般来说由两个部分组成
(1)一个具名的Handle,也就是我们所说的声明(如变量);
(2)一个内部(不具名)的对象,也就是具名Handle的内部对象。它在Manged Heap(托管堆)中分配,一般由新增引用对象的New方法是进行创建;
如果这个内部对象已被创建,那么具名的Handle就指向这个内部对象在Manged Heap中的地址,否则就是null(从某个方面来讲,如果这个具名的handle可以被赋值为null,说明这是一个引用对象,当然不是绝对)。两个引用对象如果进行赋值,它们仅仅是复制这个内部对象的地址,内部对象仍然是同一个,因此,源对象或拷贝对象的修改都会影响对方。这也就是浅拷贝。
MemberwiseClone是一个Protected方法,很多Class(如Array)的Clone方法其实上调用的MemberwiseClone方法,执行的是浅拷贝,该方法定义在object class上。
附题目:
1、SqlConnection con = new SqlConnection(); SqlConnection c = con; c = null;
为什么执行上面语句后con对象没有为null呢?
答案:con是一个引用对象,因此有两个部分handle和对象,将设con所持有的handle叫 HandleA.接下来当声明了sqlconnection c时,c具有另外的一个handle,假设叫HandleB.将con赋给c后,只是HandleB也指向HandleA所指向的对象.即内部对象一样,但是指向对象的Handle不一样了.当执行c=null时,仅仅是将HandleB指向了null.原先指向的对象仍然不变,所以con对象不为null
2、经典java面试题
①String str=new String("abc");
这行代码究竟创建了几个String对象呢?相信大家对这道题并不陌生,答案也是众所周知的,2个。
②String a="abc"; String b="abc";
那这里呢?答案是一个。
③String a="ab"+"cd";
答案是三个。
解答地址:http://www.iteye.com/topic/209904