#include<iostream>
#include<string>
using namespace std;

class Person {
public:
    int * p_age;
    int * p_height;   //指针
public:
    Person() {
        cout << "执行无参构造函数" << endl;
    };

    Person(int age, int height) {
        p_age = new int(age);
        p_height = new int(height);   //指针只能指向内存区域,所以只能开辟新内存返回内存地址给指针接收
        cout << "执行有参构造函数" << endl;
        cout << "Height的内存地址是:" << p_height << "\tAge的内存地址是:" << p_age << endl; //与拷贝构造函数的内存地址是不同的

    };

    ~Person() {
        cout << "执行析构函数" << endl;
        if (p_height !=NULL & p_age !=NULL)
        {
            delete p_height;
            delete p_age;
            p_height = NULL;  //确保安全,指向NULL
        }
    };

    Person(const Person& p) {
        p_age = new int(*p.p_age);
        p_height = new int(*p.p_height);  //在堆区开辟新内存区域存放.这就叫深拷贝
        //p_height = p.p_height;  会报堆区错误
        cout << "Height的内存地址是:"<<p_height <<"\tAge的内存地址是:"<<p_age<< endl; //与有参构造函数的内存地址是不同的
        //cout必须是p_height而不是p.p_height,因为p.p_height依然是传入进来的实参地址
        cout << "执行拷贝构造函数" << endl;
        //如果不在堆区创建新内存,浅拷贝手动释放的时候就会带来重复释放堆区的问题
    };


};
void test01() {
    //Person p1;     //执行无参构造函数
    Person p(10,20); //执行有参构造函数
    Person p2(p);    //执行拷贝构造函数
};


int main() {
    test01();
}
//总结:
//如果属性有在堆区开辟内存的,一定要自己写拷贝函数和析构函数,防止浅拷贝带来的问题.
//calss类一旦创建,系统会自动执行创建三个函数, 1构造函数(空构造) 2析构函数(空构造) 3拷贝函数
//如果2自建了,系统会取消建立1,如果3自建了,系统会取消1和2
//按照顺序,被系统取消的,如果需要,则你需要自建.

如果到这里自学的朋友们看不懂,那就看书看视频去.自此节开始,算作入门

最后修改:2022 年 12 月 05 日
如果觉得我的文章对你有用,请随意赞赏