浅谈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++的浅拷贝出现的错误全部内容了,希望大家多多支持脚本之家~

相关文章

  • Qt自定义美化滑动条

    Qt自定义美化滑动条

    这篇文章主要为大家详细介绍了Qt自定义美化滑动条的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-11-11
  • C语言rand和srand函数使用方法介绍

    C语言rand和srand函数使用方法介绍

    rand()函数用来产生随机数,但是,rand()的内部实现是用线性同余法实现的,是伪随机数,由于周期较长,因此在一定范围内可以看成是随机的。srand()用来设置rand()产生随机数时的随机数种子。参数seed是整数,通常可以利用time(0)或geypid(0)的返回值作为seed
    2023-02-02
  • OpenCV利用霍夫变换进行直线检测

    OpenCV利用霍夫变换进行直线检测

    这篇文章主要为大家详细介绍了OpenCV利用霍夫变换进行直线检测,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • 基于结构体与指针的详解

    基于结构体与指针的详解

    本篇文章是对结构体与指针进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++设计模式之单例模式

    C++设计模式之单例模式

    这篇文章主要介绍了C++设计模式之单例模式,本文同时给出了4种单例模式的实现代码,需要的朋友可以参考下
    2014-09-09
  • C/C++中CJSON的使用(创建与解析JSON数据)

    C/C++中CJSON的使用(创建与解析JSON数据)

    cJSON是一个超轻巧的JSON解析器,本文主要介绍了C/C++中CJSON的使用(创建与解析JSON数据),具有一定的参考价值,感兴趣的可以了解一下
    2021-09-09
  • C++实现LeetCode(138.拷贝带有随机指针的链表)

    C++实现LeetCode(138.拷贝带有随机指针的链表)

    这篇文章主要介绍了C++实现LeetCode(138.拷贝带有随机指针的链表),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • 深入探讨:main函数执行完毕后,是否可能会再执行一段代码?

    深入探讨:main函数执行完毕后,是否可能会再执行一段代码?

    本篇文章是对main函数执行完毕后,是否可能会再执行一段代码,进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言实现飞机游戏(进阶版)的示例代码

    C语言实现飞机游戏(进阶版)的示例代码

    在前文中,已经带大家利用C语言实现了简单的飞机游戏,但它还存在一些缺陷。因此,本文将给大家带来进阶版的飞机游戏,需要的可以参考一下
    2022-10-10
  • 用C语言实现简单版9*9扫雷小游戏

    用C语言实现简单版9*9扫雷小游戏

    这篇文章主要介绍了用C语言实现简单版9*9扫雷小游戏,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03

最新评论