C++拷贝控制含有指针成员的类

当定义一个类时,我们显式地或隐式地指定了此类型的对象在拷贝、赋值和销毁时做什么。一个类通过定义五种种特殊的成员函数来控制这些操作:拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符和析构函数。


在一个类中,如果类 没有指针成员,一切方便,因为默认合成的析构函数会自动处理所有的内存。但是如果一个类带了指针成员,那么需要我们自己来写 析构函数来管理内存。


对于含有指针成员的类的对象调用默认拷贝构造函数、拷贝赋值运算符时,指针成员进行是浅拷贝,两个对象的指针成员所指内存相同,这就导致指针被分配一次内存,但是程序结束时该内存却被析构了两次,第一次析构后,指针变为野指针 ,第二次析构导致错误。
 

浅拷贝与深拷贝:
(1)浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝;
(2)深拷贝是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝;

野指针与空指针:
(1)野指针:不是NULL指针,是指向"垃圾"内存(不可用内存)的指针,野指针是非常危险的。指针变量没有被初始化,它缺省值是随机的,它会乱指一气;指针p被free或者delete之后,只是把指针所指的内存释放掉了,没有改变指针的值,此时,p沦落为野指针。
(2)空指针:没有存储任何内存地址的指针就称为空指针(NULL指针)

总结:
(1)如果一个类带了指针成员,它也需要自定义析构函数。
(2)如果一个类需要自定义析构函数,几乎可以肯定它也需要自定义拷贝赋值运算符和拷贝构造函数。
(3)如果一个类需要一个拷贝构造函数,几乎可以肯定它也需要一个拷贝赋值运算符。反之亦然,如果一个类需要一个拷贝赋值运算符,几乎可以肯定它也需要一个拷贝构造函数。
 

demo:

#include "iostream"

using namespace std;

class Human
{
public:
	Human()
	{
		name = new char[4];
		string a = "123";
		strcpy_s(name, 4, a.c_str());

		cout << "Human Construct be called Successful!" << endl;
	}

#if 1
	Human(Human &hm)
	{
	   if (NULL != hm.name)
	   {
			name = new char[4];
			strcpy_s(name, 4, hm.name);
	   }

		cout << "Human copy Construct be called Successful!" << endl;
	}

	Human& operator=(const Human& hm)
	{
		if (this != &hm)
		{
			// 避免内存泄露
			if (name != NULL)
			{
				delete name;
				name = NULL;
			}

			if (NULL != hm.name)
			{
				name = new char[4];
				strcpy_s(name, 4, hm.name);
			}
		}

		cout << "Human operator be called Successful!" << endl;

		return *this;
	}
#endif

	~Human()
	{
		delete[] name;  //不需要判断是否为空
		cout << "Human Deconstrute be called Successful!" << endl;
	}

	int init()
	{
		return 0;
	}

	int age;
	char *name;
};


int main()
{
	{
		Human  hm1, hm3;  //调用构造函数

		Human hm2 = hm1;  //调用拷贝构造函数
		hm3 = hm1;        //调用拷贝赋值运算符
	}

	system("pause");
	return 0;
}

参考:

https://blog.csdn.net/caoshangpa/article/details/79226270
https://blog.csdn.net/fanx021/article/details/80207692
https://blog.csdn.net/liitdar/article/details/80656156
https://www.cnblogs.com/zpcdbky/p/5027481.html
https://www.cnblogs.com/codingmengmeng/p/9110608.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章