浅拷贝的问题

默认提供的拷贝构造就是浅拷贝,如果拷贝的对象中含有成员指针变量指向堆区中的内存空间,那么就会出现两个对象中的成员指针变量指向同一块堆区空间,当方法执行结束后,对象就会被释放,调用析构函数(析构函数中存在释放在堆区开辟的内存空间),就会存在一块内存空间被多次释放的问题。

解决办法

自己写拷贝构造,让拷贝构造后的对象中的成员指针变量指向一块新的内存空间。
C++深拷贝与浅拷贝-小白菜博客
image

//
// Created by Administrator on 2023/4/25.
//
#include <iostream>
using namespace std;
// 深拷贝和浅拷贝
class Person {
public:
    int p_age;
    int *p_weight;

    Person() {
        cout << "无参构造" << endl;
    }

    Person(int age, int height) {
        p_age = age;
        p_weight = new int(height);
        cout << "有参构造" << endl;
    }

    // 析构函数 用于释放手动在堆区开辟的空间
    ~Person() {
        if (p_weight != NULL) {
            delete p_weight;
            // 防止野指针
            p_weight = NULL;
        }
        cout << "析构函数" << endl;
    }

    // 拷贝构造 不写让编译器生成
    // 防止 浅拷贝带来的问题 自己写拷贝构造 避免这个问题
    Person(const Person &p) {
        cout << "自己写的拷贝构造,避免浅拷贝的问题" << endl;
        p_age = p.p_age;
        // 这是浅拷贝
        // p_height = p.p_height; 自动生成的就是这样

        // 深拷贝 重新开一块空间 防止出现重复释放的问题
        p_weight = new int(*p.p_weight);
    }
};

void test() {
    Person p1(10, 120);
    cout << "年龄为: " << p1.p_age << ", 体重为: " << *p1.p_weight << endl;
    Person p2(p1);
    cout << "年龄为: " << p2.p_age << ", 体重为: " << *p2.p_weight << endl;
    // 会 先释放p2 在释放p1
    // 释放p2后析构函数会将 堆区中开辟的空间释放了 p1在此执行析构 在此操作那块内存就会报错
}

int main() {
    test();
    return 0;
}