#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
//按照顺序,被系统取消的,如果需要,则你需要自建.
如果到这里自学的朋友们看不懂,那就看书看视频去.自此节开始,算作入门