浅谈C++的浅拷贝出现的错误

 更新时间:2017年01月05日 09:33:58   投稿:jingxian  
下面小编就为大家带来一篇浅谈C++的浅拷贝出现的错误。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

之前看一些资料提到浅拷贝的问题,即在复制对象时,只是对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝。如果对象中存在动态成员,如指针,那么仅仅做浅拷贝是不够的,并且容易引发错误,最经典的例子:

#include <iostream>
#include <stdio.h> 

using namespace std;

class A{
  public:
    A(){m_p = new int(10);};
    ~A(){cout << "destruction function" << endl;delete m_p;}; 
    int* m_p; 
};

void copyTest(A atmp){
  ;
}

int main(){
  A a;
  copyTest(a);
}

执行这段代码会出现崩溃,因为析构函数里的delete m_p执行了两次,而m_p指向的是同一块内存。因为在调用copyTest时传入了对象a,atmp利用a作为参数执行了默认拷贝构造函数,但是只是简单地把对象a的m_p的内存地址拷贝给atmp的m_p,因此这个时候atmp.m_p只是指向了和a.m_p相同的内存块。

当copyTest执行完毕后,临时变量atmp会被销毁,这个时候析构函数被调用,delete了m_p指向的内存。而当main函数执行完毕后,a对象也需要被销毁,这个时候析构函数再次被执行,而这个时候m_p已经不知道指向什么地方了,delete操作引发程序崩溃。

解决这个问题的方法有很多:一种方法是实现智能指针,对m_p进行引用计数,当引用值为0时才执行delete;也可以每次把m_p的初始值设为NULL,每次执行delete操作前先检查m_p是否为NULL,delete后再让m_p指向NULL,这个方法其实道理和智能指针差不多,只是智能指针更合理有效地利用类进行管理;还有一种做法是重写拷贝构造函数,确保在对象复制时进行深拷贝,即重新分配内存空间,并且把a中m_p指向内存的内容拷贝到分配的空间。

以上这种情况只有在利用“值传递”复制对象时才发生,如果我们传递的是指针,就不会有这种情况了:

#include <iostream>
#include <stdio.h> 

using namespace std;

class A{
  public:
    A(){m_p = new int(10);};
    ~A(){cout << "destruction function" << endl;delete m_p;}; 
    int* m_p; 
};

void copyTest(A* atmp){
  ;
}

int main(){
  A* a;
  copyTest(a);
}

因为传递到copyTest的参数只是一个地址,指向的还是对象a,并没有发生对象的复制,当然就不存在上面的深浅拷贝问题了。

以上就是小编为大家带来的浅谈C++的浅拷贝出现的错误全部内容了,希望大家多多支持脚本之家~

相关文章

  • C++中的friend函数详细解析

    C++中的friend函数详细解析

    本篇文章主要介绍了C++中的friend函数详细解析,对初学c++的人有一定的帮助,有需要的可以了解一下。
    2016-11-11
  • c++特殊构造函数详解

    c++特殊构造函数详解

    大家好,本篇文章主要讲的是c++特殊构造函数详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • C++实现下载的代码

    C++实现下载的代码

    这篇文章主要介绍了C++实现下载的代码,以下载百度图片为例较为完整的讲述了C++下载的具体实现方法,需要的朋友可以参考下
    2014-10-10
  • C语言 联合(union)用法案例详解

    C语言 联合(union)用法案例详解

    这篇文章主要介绍了C语言 联合(union)用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C语言安全之数组长度与指针实例解析

    C语言安全之数组长度与指针实例解析

    这篇文章主要介绍了C语言安全之数组长度与指针,需要的朋友可以参考下
    2014-07-07
  • C语言如何实现翻转字符串中的单词

    C语言如何实现翻转字符串中的单词

    这篇文章主要介绍了C语言如何实现翻转字符串中的单词,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C语言实现BMP图像处理(彩色图转灰度图)

    C语言实现BMP图像处理(彩色图转灰度图)

    这篇文章主要为大家详细介绍了C语言实现BMP图像处理,彩色图转灰度图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • C++实现将输入的内容输出到文本文件

    C++实现将输入的内容输出到文本文件

    这篇文章主要介绍了C++实现将输入的内容输出到文本文件问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • C/C++字节序的深入理解

    C/C++字节序的深入理解

    本文主要介绍了C/C++字节序的深入理解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C语言中函数的声明、定义及使用的入门教程

    C语言中函数的声明、定义及使用的入门教程

    这篇文章主要介绍了C语言中函数的声明、定义及使用的入门教程,重点讲述了main函数的相关知识,需要的朋友可以参考下
    2015-12-12

最新评论