经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
C++深拷贝与浅拷贝的区别及应用
来源:jb51  时间:2021/4/12 13:52:14  对本文有异议

浅拷贝

只是对指针的拷贝,拷贝后两个指针指向同一个内存空间;

深拷贝

对指针指向的内容进行拷贝(重新分配内存),经深拷贝后的指针是指向不同地址的指针;

因此浅拷贝释放内存的时候很容易出现因为释放两个指针而内存出错。

浅拷贝(释放时,因为多次释放出错)

只拷贝指针

  1. //拷贝构造函数
  2. Vector(const Vector<T>& v)
  3. :_start(nullptr)
  4. ,_finish(nullptr)
  5. ,_endOfStorage(nullptr)
  6. {
  7. _start=v._start;
  8. _finish=v._finish;
  9. _endOfStorage=v._endOfStorage;
  10. }

深拷贝

对资源进行拷贝

  1. Vector(const Vector<T>& v)
  2. :_start(nullptr)
  3. , _finish(nullptr)
  4. , _endOfStorage(nullptr)
  5. {
  6. size_t n = v.capacity();
  7. _start = new T[n];
  8. for (size_t i = 0; i < v.size(); ++i)
  9. {
  10. _start[i] = v[i];
  11. }
  12. _finish = _start + v.size();
  13. _endOfStorage = _start + n;
  14. }

写一个Vector的类

  1. template<class T>
  2. class Vector
  3. {
  4. typedef T* operator;
  5. typedef const T* const_iterator;
  6. iterator _start;
  7. iterator _finish;
  8. iterator _endOfStorage;
  9. public:
  10. //构造函数
  11. Vector()
  12. :_start(nullptr)
  13. , _finish(nullptr)
  14. , _endOfStorage(nullptr)
  15. {}
  16.  
  17. //析构函数
  18. ~Vector()
  19. {
  20. if(_start)
  21. {
  22. delete[] _start;
  23. _star=_finish=_endOfStorage=nullptr;
  24. }
  25. }
  26. T& operator[](size_t pos)
  27. {
  28. if (pos >= 0 && pos < size())
  29. return _start[pos];
  30. }
  31. size_t size() const
  32. {
  33. return _finish - _start;
  34. }
  35. size_t capacity() const
  36. {
  37. return _endOfStorage - _start;
  38. }
  39.  
  40.  
  41. };

可以用自己编辑器,把拷贝放进去试试;

附:c++深拷贝与浅拷贝问题实例

浅拷贝:简单的赋值拷贝操作;

深拷贝:在堆区重新申请空间,再进行拷贝操作;

问题:浅拷贝会带来堆区内存被重复释放的问题,析构函数被调用多次,导致程序运行崩溃;

解决:通过深拷贝解决,在堆区重新申请内存,各自释放自己的内存,避免重复释放;

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class Person
  6. {
  7. public:
  8. Person() {
  9. cout << "Person的默认构造函数调用"<<endl;
  10. }
  11. Person(int age,int height) {
  12. m_Age = age;
  13. m_Height = new int(height);//堆区重新申请空间,进行深拷贝,手动申请,手动释放;
  14. cout << "Person的有参函数调用" << endl;
  15. }
  16. int m_Age;
  17. int *m_Height;
  18.  
  19. //自己实现拷贝构造函数,来避免编译器的拷贝构造函数造成浅拷贝问题;
  20. Person(const Person& p) {
  21. cout << "Person拷贝构造函数" << endl;
  22. m_Age = p.m_Age;
  23. //m_Height = p.m_Height; 浅拷贝,编译器默认实现这行代码;
  24. m_Height = new int(*p.m_Height);//深拷贝
  25. }
  26.  
  27. ~Person() {
  28. //析构代码,将堆区开辟数据做释放操作
  29. if (m_Height != NULL) {
  30. delete m_Height;
  31. m_Height = NULL;
  32. }
  33. cout << "Person的析构函数调用" << endl;
  34. }
  35. };
  36.  
  37. void test01(){
  38. Person p1(18,160);
  39. cout << "p1的年龄为:" << p1.m_Age<<"p1身高为:"<<*p1.m_Height<< endl;
  40. Person p2(p1);//编译器默认调用拷贝构造函数,进行浅拷贝操作
  41. cout << "p2的年龄为:" << p2.m_Age<< "p2身高为:"<<*p2.m_Height << endl;
  42. }
  43.  
  44. int main(){
  45. test01();
  46. system("pause");
  47. }

程序运行结果:

总结

到此这篇关于C++深拷贝与浅拷贝区别及应用的文章就介绍到这了,更多相关C++深拷贝与浅拷贝内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号