深拷贝与浅拷贝

 

深拷贝与浅拷贝 

浅拷贝:简单的赋值拷贝操作,或者说编译器自己生成的默认拷贝函数

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

 

复制代码
class Person {
public:
    //无参(默认)构造函数
    Person() {
        cout << "无参构造函数!" << endl;
    }
    //有参构造函数
    Person(int age, int height) {

        cout << "有参构造函数!" << endl;

        m_age = age;
        //因为new是在堆区存储数据,所以用一个指针接收返回数据
        m_height = new int(height);

    }
 

    //析构函数 专门释放堆区数据的
    ~Person() {
        cout << "析构函数!" << endl;
        if (m_height != NULL)
        {
            //释放在堆区中的数据。
            delete m_height;
            //防止野指针出现,设置成空指针。
            m_height = NULL;
        }
    }
public:
    int m_age;
    int* m_height;
};

void test01()
{
    Person p1(18, 180);

    cout << "p1的年龄: " << p1.m_age << " 身高: " << *p1.m_height << endl;

    Person p2(p1);
     
    cout << "p2的年龄: " << p2.m_age << " 身高: " << *p2.m_height << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}
复制代码

 

当前代码运行起来之后会报错:

 

 

因为在有参构造函数中创建了一个堆区的数据,在执行Person p2(p1)的时候编译器默认的拷贝函数也会简单的在栈上存储height的地址,当离开test01这个函数体的时候自动调用析构函数,栈上的数据是先进后出(因为test01函数中没有new,数据在栈上),所以先释放p2的数据,这里的析构函数是自己写的,可以看到释放了m_height在堆上的数据,当在释放p1(注意p1上的m_height存储的是堆地址,此时它是有值的,不会因为p2释放了导致它在栈上的值没有了)的时候又会重新释放,根据栈上的地址找堆,发现找不到了,导致重复释放报错。

上述就是因为编译器默认的浅拷贝造成的,如果属性有在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题

自己创建拷贝函数解决:

复制代码
class Person {
public:
    //无参(默认)构造函数
    Person() {
        cout << "无参构造函数!" << endl;
    }
    //有参构造函数
    Person(int age, int height) {

        cout << "有参构造函数!" << endl;

        m_age = age;
        //因为new是在堆区存储数据,所以用一个指针接收返回数据
        m_height = new int(height);

    }
    //拷贝构造函数  
    Person(const Person& p) {
        cout << "拷贝构造函数!" << endl;
        //如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区问题
        m_age = p.m_age;
        //这样不论调用多少次拷贝函数,前后的m_height中存储的堆地址都不是一样的了
        m_height = new int(*p.m_height);

    }

    //析构函数 专门释放堆区数据的
    ~Person() {
        cout << "析构函数!" << endl;
        if (m_height != NULL)
        {
            //释放在堆区中的数据。
            delete m_height;
            //防止野指针出现,设置成空指针。
            m_height = NULL;
        }
    }
public:
    int m_age;
    int* m_height;
};

void test01()
{
    Person p1(18, 180);

    cout << "p1的年龄: " << p1.m_age << " 身高: " << *p1.m_height << endl;

    Person p2(p1);
     
    cout << "p2的年龄: " << p2.m_age << " 身高: " << *p2.m_height << endl;
}

int main() {

    test01();

    system("pause");

    return 0;
}
复制代码

 

结果:

 

posted @   安静点--  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示