<C++略识>之浅拷贝与深拷贝
2016-07-20 15:23
246 查看
浅拷贝:又称之为位拷贝,是指当进行对象拷贝时,只是将数据成员的值进行了简单拷贝。
深拷贝:又称之为值拷贝,是指当进行对象拷贝时,不是简单的做值的拷贝,而是将堆中内存的数据也进行了拷贝。
浅拷贝和深拷贝两者的区别如下:
深拷贝在创建新的对象时,该对象自己在堆区申请一个内存空间,这样就不会出现在调用析构的时候找不到内存空间;因为如果是浅拷贝的话,所有的指针都指向同一个内存空间,当有一个对象生命周期结束后,那么该对象的内存空间要被回收,这样其他对象在析构的时候就找不到对应的内存空间,会崩溃!!
用一句简单的话来说就是: 浅拷贝,只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
深拷贝和浅拷贝也可以简单理解为: 如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
[注意]: C++编译器默认的拷贝构造函数是浅拷贝。
深浅拷贝的实现方法举例:
这里当调用浅拷贝时,arr2和arr1中的指针m_pArr就会指向内存中的同一块内存空间,这样当我们去销毁arr1这个对象的时候,我们为了避免内存泄漏,肯定会释放掉m_pArr所指向的这段内存。如果我们已经释放掉了这段内存,我们再去销毁arr2这个对象时,我们肯定也会以同样的方式去释放掉arr2中m_pArr这个指针所指向的这段内存,那么就相当于,同一块内存被释放了两次,造成程序崩溃。
而当我们调用深拷贝时,拷贝的时候不是将指针的地址简单的拷贝过来,而是将指针所指向的内存当中的每一个元素依次的拷贝过来,即:在拷贝函数中先申请了一段内存,然后将arr中的m_pArr所指向的每一个元素都拷贝到当前的m_pArr所指向的相应的内存当中去。由于arr1中的m_pArr和arr2中的m_pArr指向的是两个不同的内存空间,所以无论我们对arr1和arr2中的哪一个进行销毁与否,都不会影响另外一个。
深拷贝:又称之为值拷贝,是指当进行对象拷贝时,不是简单的做值的拷贝,而是将堆中内存的数据也进行了拷贝。
浅拷贝和深拷贝两者的区别如下:
深拷贝在创建新的对象时,该对象自己在堆区申请一个内存空间,这样就不会出现在调用析构的时候找不到内存空间;因为如果是浅拷贝的话,所有的指针都指向同一个内存空间,当有一个对象生命周期结束后,那么该对象的内存空间要被回收,这样其他对象在析构的时候就找不到对应的内存空间,会崩溃!!
用一句简单的话来说就是: 浅拷贝,只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
深拷贝和浅拷贝也可以简单理解为: 如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
[注意]: C++编译器默认的拷贝构造函数是浅拷贝。
深浅拷贝的实现方法举例:
//浅拷贝实现 class Array { public: Array() { m_iCount = 5; m_pArr = new int[m_iCount]; } Array(const Array &arr) //拷贝构造函数 { m_iCount = arr.m_iCount; m_pArr = arr.m_pArr; } private: int m_iCount; int *m_pArr; }; //深拷贝实现 class Array { public: Array() { m_iCount = 5; m_pArr = new int[m_iCount]; } Array(const Array &arr) //拷贝构造函数 { m_iCount = arr.m_iCount; m_pArr = new int[m_iCount]; for(int i = 0; i < m_iCount; i++) { m_pArr[i] = arr.m_pArr[i]; } } private: int m_iCount; int *m_pArr; }; int main() { Array arr1; Array arr2 = arr1;//调用拷贝构造函数 return 0; }
这里当调用浅拷贝时,arr2和arr1中的指针m_pArr就会指向内存中的同一块内存空间,这样当我们去销毁arr1这个对象的时候,我们为了避免内存泄漏,肯定会释放掉m_pArr所指向的这段内存。如果我们已经释放掉了这段内存,我们再去销毁arr2这个对象时,我们肯定也会以同样的方式去释放掉arr2中m_pArr这个指针所指向的这段内存,那么就相当于,同一块内存被释放了两次,造成程序崩溃。
而当我们调用深拷贝时,拷贝的时候不是将指针的地址简单的拷贝过来,而是将指针所指向的内存当中的每一个元素依次的拷贝过来,即:在拷贝函数中先申请了一段内存,然后将arr中的m_pArr所指向的每一个元素都拷贝到当前的m_pArr所指向的相应的内存当中去。由于arr1中的m_pArr和arr2中的m_pArr指向的是两个不同的内存空间,所以无论我们对arr1和arr2中的哪一个进行销毁与否,都不会影响另外一个。
相关文章推荐
- C++ vector用法初记
- C语言实现队列
- C语言实现栈
- c++11中的线程、锁和条件变量
- Cpp环境【OpenJudge3344】【Vijos2874】冷血格斗场
- c语言链表初始化
- 在visual Studio上使用C#调用非托管C++生成的DLL文件(图文讲解)
- C语言表驱动法编程实践
- <C++略识>之对象数组与对象成员
- <C++略识>之构造函数及初始化列表
- Leetcode 198. House Robber (Easy) (cpp)
- Spiral Matrix II
- leetcode_c++:栈:Valid Parentheses(020)
- c++中this详解
- Cpp环境【Usaco2.1.3】【Vijos1222】顺序排分数
- C++经典题目上
- 144. Binary Tree Preorder Traversal
- Leetcode 70. Climbing Stairs (Easy) (cpp)
- 【排序专训】练习题 士兵站队(中位数应用) 解题报告
- Coin Change