栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++深拷贝与浅拷贝两种解决方案

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++深拷贝与浅拷贝两种解决方案

问题描述

含有指针的对象,在相互拷贝时(浅拷贝:简单的赋值),会在析构函数重复释放相同地址的堆区空间而产生错误。
例如以下程序:

#include "bits/stdc++.h"
using namespace std;

class demo
{
public:
    demo() {}
    //有参构造函数
    demo(const int age=0)
    {
        m_age = new int(age);
    }

    //析构函数 
    ~demo()
    {
        cout << "m_age指向的地址是:" << m_age << endl;
        if (m_age != nullptr)
        {
            delete m_age;
            m_age = nullptr;
        }
    }

private:
    int *m_age;
};

int main(int argc, char **argv)
{
    demo d1(22);
    demo d2(d1);

    return 0;
}

运行结果如下:

m_age指向的地址是:0x55db53c67e70
m_age指向的地址是:0x55db53c67e70
free(): double free detected in tcache 2
已放弃 (核心已转储)

可见使用默认拷贝构造时,简单的值拷贝会使得指针m_age指向同一个堆区内存,重复释放必然会错误。

重载等号运算符号的方式解决
     demo &operator=(const demo &obj)
     {
         //先释放旧有内存
         if (this->m_age != nullptr)
         {
             delete m_age;
             m_age = nullptr;
         }
         //再创建新内存
         m_age = new int(*obj.m_age);
         return *this;
    }
重写拷贝构造函数的方式解决
     demo(const demo &obj)
     {
         m_age = new int(*obj.m_age);
     }

上述两种方式采用深拷贝,在堆区重新申请空间,进行拷贝操作,释放时释放各自申请的堆区内存,避免了重复释放

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/976935.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号