浅拷贝
是栈区中的对象引用都是指向同一个堆区的空间内存。
注意:此时栈区的对象多次被释放,引发同一个内存地址重复释放的错误。
深拷贝
在堆区开辟多个内存空间,让赋值的引用对象指向不同的堆区内存地址。
场景如下
A、栈区中,子函数return 对象,进行赋值操作;B、栈区中,传递对象给子函数进行传递引用。
注:默认的拷贝构造函数里使用的是浅拷贝:在栈区先构建新地址,然后进行赋值。
//存在类 Student
class Student{
Student(){}
Student(char * name){
// TODO: name成员属性在堆内存开辟空间了
this->name = (char *)malloc(sizeof(char * 10));
strcpy(this->name,name);
}
Student(const Student & stu){
//自定义拷贝构造函数
//3、TODO:深拷贝: 给在堆区的成员属性,重新开辟内存空间
this->name = (char *)malloc(sizeof(char * 10)); //name成员属性在堆内存开辟空间了
strcpy(this->name,name);
}
};
Student getStudent(){
Student stu("name");
return stu;
}
Student setStudent(Student stu){
count<< &stu<< endl;
}
void main(){
// 1、 此 = 等号赋值操作程序执行流程:1、getStudent子函数里先执行Student的构造函数,然后执行拷贝构造函数返回栈区中新的地址引用给stu1,最后getStudent弹栈调用析构函数释放旧地址;
Student stu1 = getStudent();
// 2、此 参数传递 操作程序执行流程:1、stu2先执行Student的构造函数,然后执行拷贝构造函数返回栈区中新的地址引用给setStudent,最后setStudent弹栈调用析构函数释放新地址;
Student stu2;
setStudent(stu2);
}
以上代码案例,若拷贝构造函数中不进行深拷贝,则在mian函数中 student对象多次赋值,程序执行后,setStudent()弹栈、main()弹栈时都会出现同一个内存被释放多次的错误;
总结:一旦成员属性涉及堆内存空间,一定需要深拷贝。
问题bug:多次重复释放同一内存地址的错误的;解决方法:对于在堆区的成员属性,在自定义拷贝构造函数中重新开辟内存地址,如:
this->name = (char *)malloc(sizeof(char * 10));
strcpy(this->name,name);