1.析构顺序
在程序中先创建的对象后析构。
Person p1;
Person p2;
p2先析构。
2.值类型与引用类型
在介绍深拷贝与浅拷贝之前,我们要再次强调一下引用类型与值类型。
值类型:存储区域存放的是变量的值。
引用类型:存储区域存放的是值变量的地址,可以根据值的地址找到值。
3.数据的存储
数据分配内存由两种方式:直接分配与动态创建。
直接分配: int a[3] = {0};直接创建的数据分配的内存在栈中。
动态创建:int *a = new int[3];动态使用malloc或者new创建的数据创建在堆区中。
4. 浅拷贝与深拷贝
若在成员变量中含有指针变量,先释放指针指向的空间,再释放对象所占用的空间。因为堆区的内存需要程序员手动释放。
4.1 浅拷贝
class Person {
public:
int m_age;
int* m_score;
//有参构造函数
Person(int age, int score) {
m_age = age;
m_score = new int(score);
}
//析构函数
~Person() {
if (m_score != NULL) {
delete m_score;
}
}
//系统默认实现的拷贝构造函数
Person(const Person &p) {
m_age = p.m_age;
m_score = p.score;
}
};
int main() {
Person p1(10, 95);
cout << *p1.m_score << endl;
Person p2(p1);
//先构造后析构先析构p2,再p1
}
这里实现的是浅拷贝,无法输出 *p2.score,会提示p2为null是因为拷贝函数是const 引用实现 ,所以p1 p2共同指向一片空间,当析构p2时,p2所指向的空间在析构p1时会被重复释放。
4.2 深拷贝
//自己创建拷贝构造函数
Person(const Person &p) {
m_age = p.m_age;
m_score = new int(*p.m_score);
}