【C++】C++学习之深拷贝和浅拷贝(六)

1. 深拷贝和浅拷贝

1)默认复制构造函数可以完成对象的数据成员值简单的复制
2)对象的数据资源是由指针指示的堆时,默认复制构造函数仅作指针值复制
1. 1 浅拷贝
1)对象中什么样的操作的浅拷贝?如下代码,可以看到这个类只有构造函数以及析构函数,当执行Name obj2 = obj1语句时,浅拷贝就发生了,回报错程序,为什么?

class Name
{
    
    
public:
	Name(const char *pname)  //构造函数
	{
    
    
		size = strlen(pname);
		pName = (char *)malloc(size + 1);
		strcpy(pName, pname);
	}
	
	~Name()
	{
    
    
		cout<<"开始析构"<<endl;
		if (pName!=NULL)
		{
    
    
			free(pName);
			pName = NULL;
			size = 0;
		}
	}
protected:
private:
	char *pName;
	int size;
};


void playObj()
{
    
    
	Name obj1("abcdefg");
	Name obj2 = obj1; //obj2创建并初始化
}

void main()
{
    
    
	playObj();
	system("pause");
}

首先我们知道先创建的对象后析构,因此在执行这个语句中obj1已经初始化然后用它这个对象去初始化另一个对象obj2,但是由于这个类结构中不含有赋值构造函数,此时C++编译器就会调用默认的赋值构造函数,【默认复制构造函数仅作简单指针值复制】即就仅仅是将obj1中的指针变量指向的地址与len值赋值到obj2对象的变量中,并没有开辟新的空间,此时obj1与obj2指向堆中同一个空间。最后就是赋值完成后,obj2要进行析构了,执行free(pName);,堆中空间被释放且obj2中的p=NULL;但是当obj2析构完后到了obj1析构时,此时obj1指针p由于obj2的析构已经是一个野指针,而自己又要析构一次,即又要执行free(pName)进行对空间释放;但已经释放且指针指向为野指针(被析构两次)编译运行时会触发程序中断。
在这里插入图片描述

//对象的初始化 和 对象之间=号操作是两个不同的概念
void playObj()
{
    
    
Name obj1("obj1.....");
Name obj2 = obj1; //obj2创建并初始化
Name obj3("obj3...");
//重载=号操作符
obj2 = obj3; //=号操作
cout<<"业务操作。。。5000"<<endl;
}

在这里插入图片描述
2)

1.2 深拷贝
1)那么针对上面问题,怎么使得对象的初始化成功呢?即我们的目标是让希望在堆中开辟一个同样大小的新空间,再将obj1的值赋值到obj2的指针指向的新空间中,然后当在进行析构时,两个对象互补影响【实现代码如下】

Name(Name &obj)
{
    
    
//用obj来初始化自己
pName = (char *)malloc(obj.size + 1);
strcpy(pName, obj.pName);
size = obj.size;
}

2)至于图二中的浅拷贝形势,要解决就需要重载=操作符才行

猜你喜欢

转载自blog.csdn.net/qq_32643313/article/details/105506311