浅谈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++实现LeetCode(61.旋转链表)

    C++实现LeetCode(61.旋转链表)

    这篇文章主要介绍了C++实现LeetCode(61.旋转链表),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • OpenCV实现图像连通域

    OpenCV实现图像连通域

    这篇文章主要为大家详细介绍了OpenCV实现图像连通域,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C++实现LeetCode(198.打家劫舍)

    C++实现LeetCode(198.打家劫舍)

    这篇文章主要介绍了C++实现LeetCode(198.打家劫舍),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C++  系统IO流介绍

    C++  系统IO流介绍

    这篇文章主要介绍了C++系统IO流,大部分人都是从输出"Hello World"开始的,本文会介绍C++中的IO细节,需要的朋友可以参考一下,希望对大家有所帮助
    2021-12-12
  • C++11线程、互斥量以及条件变量示例详解

    C++11线程、互斥量以及条件变量示例详解

    这篇文章主要介绍了C++11线程、互斥量以及条件变量,C++11增加了线程以及线程相关的类,很方便地支持了并发编程,使得编写多线程程序的可移植性得到了很大的提高,本文通过实例代码给大家详细讲解,需要的朋友可以参考下
    2023-03-03
  • 图文详解C语言位运算基础知识

    图文详解C语言位运算基础知识

    这篇文章主要以图文结合的方式为大家详细介绍了C语言位运算基础知识,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • C语言循环链表的原理与使用操作

    C语言循环链表的原理与使用操作

    无论是静态链表还是动态链表,有时在解决具体问题时,需要我们对其结构进行稍微地调整。比如,可以把链表的两头连接,使其成为了一个环状链表,通常称为循环链表
    2022-05-05
  • C语言实现opencv提取直线、轮廓及ROI实例详解

    C语言实现opencv提取直线、轮廓及ROI实例详解

    这篇文章主要介绍了C语言实现opencv提取直线、轮廓及ROI实例详解,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • C++中的STL中map用法详解(零基础入门)

    C++中的STL中map用法详解(零基础入门)

    map在编程中是经常使用的一个容器,本文来讲解一下STL中的map,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • C语言中宏定义的教学详解

    C语言中宏定义的教学详解

    在C语言中,宏定义是预处理器的指令,主要用于为各种数据创建别名,这篇文章主要来和大家分享一下宏定义的相关基础知识,需要的小伙伴可以了解一下
    2023-07-07

最新评论