你好你好!
以下内容仅为当前认识,可能有不足之处,欢迎讨论!
深拷贝与浅拷贝
场景:如果在类中,出现了成员属性是指针,指针指向的是一块地址。那么,在类中,利用构造函数给该指针在内存空间—堆区开辟空间,需要在析构函数中由开发者销毁这块空间。这对于一个对象来说没有问题。但是,若两个及以上的对象,如果还是使用浅拷贝(系统拷贝构造函数),就会出现问题——对于第二个对象销毁的对象——指针指向的地址——是什么呢?
比如以下代码:
#include<iostream>
#include<string>
using namespace std;
//#include"Person.h"
//#include"section2functions.h"
class Person {
public:
int* person_age;
Person() {
cout << "==================" << endl;
cout << "无参构造函数调用。" << endl;
cout << "==================\n" << endl;
}
Person(int age) {
person_age = new int(age);//在堆区中开辟的空间,需要在析构函数中手动释放。
cout << "==================" << endl;
cout << "有参构造函数调用。" << endl;
cout << "==================\n" << endl;
}
~Person() {
if (person_age) {
delete person_age;
person_age = NULL;
}
cout << "==============" << endl;
cout << "析构函数调用。" << endl;
cout << "==============\n" << endl;
}
};
void test_22() {
Person p_orginal = Person(20);
cout << "p_orginal年龄为:" << *p_orginal.person_age << "." << endl;
Person p_after(p_orginal);
cout << "p_after的年龄为:" << *p_after.person_age << "." << endl;
}
int main() {
cout << "hello world !" << endl;
test_22();
system("pause");
return 0;
}
运行结果如图:
可以看到运行到第二个析构函数的调用时发生了错误,为什么?因为析构函数是对象销毁前调用的,但第一个对象销毁时,把浅拷贝中的堆区的内存给释放了,导致在第二个对象删除指针时,不知道应该释放堆区哪块地址,从而报错。
何以解决?自定义拷贝构造函数并避免重复释放。
#include<iostream>
#include<string>
using namespace std;
class Person {
public:
int* person_age;
Person() {
cout << "==================" << endl;
cout << "无参构造函数调用。" << endl;
cout << "==================\n" << endl;
}
Person(int age) {
person_age = new int(age);//在堆区中开辟的空间,需要在析构函数中手动释放。
cout << "==================" << endl;
cout << "有参构造函数调用。" << endl;
cout << "==================\n" << endl;
}
//重写拷贝构造函数
Person(const Person &person) {
person_age = new int(*person.person_age);
//手动开辟另一块内存空间,从而释放时不重复释放。
cout << "==================" << endl;
cout << "拷贝构造函数调用。" << endl;
cout << "==================\n" << endl;
}
~Person() {
if (person_age) {
delete person_age;
person_age = NULL;
}
cout << "==============" << endl;
cout << "析构函数调用。" << endl;
cout << "==============\n" << endl;
}
};
void test_22() {
Person p_orginal = Person(20);
cout << "p_orginal年龄为:" << *p_orginal.person_age << "." << endl;
Person p_after(p_orginal);
cout << "p_after的年龄为:" << *p_after.person_age << "." << endl;
}
int main() {
cout << "hello world !" << endl;
test_22();
system("pause");
return 0;
}
运行结果,可以看到调用了两次析构函数,成功释放掉内存。
类和对象——成员函数的初始化
用途:用在成员属性的初始化上。
代码:
#include<iostream>
#include<string>
using namespace std;
class Person {
int person_age;
public :
Person() {
cout << "==================" << endl;
cout << "无参构造函数调用。" << endl;
cout << "==================" << endl;
}
Person(int age) :person_age(age) {
cout << "==================" << endl;
cout << "有参构造函数调用。" << endl;
cout << "==================" << endl;
}
~Person() {
cout << "==================" << endl;
cout << "=析构函数的调用。=" << endl;
cout << "==================" << endl;
}
void print_age() {
cout << "person age = " << person_age << "." << endl;
}
};
void test2_2_20() {
int age = 20;
Person person(age);
person.print_age();
}
int main() {
cout << "hello world !" << endl;
test2_2_20();
system("pause");
return 0;
}
运行结果:
可以看到在构造函数后方写类名:成员属性(属性值),...,成员属性(属性值)
可以帮助初始化成员属性。
以上是我的学习笔记,希望对你有所帮助!
如有不当之处欢迎指出!谢谢!