关于赋值运算符“=”的重载问题

赋值运算符的重载,应该使用这种方式:

Boy& operator=(const Boy &boy);

注意:参数要使用引用!

正确的完整代码为:
Boy类(所在文件:“Boy.h”):

#include <string>

using namespace std;

class Boy{
    
    
public:
	Boy(const char *name = NULL);
	~Boy();
	Boy& operator=(const Boy& boy);

	string getName();
private:
	char *name;
};

Boy类的实现(所在文件:Boy.cpp):

#include "Boy.h"

Boy::Boy(const char *name) {
    
    
	//判断传递的是否为空指针,是空指针就是没有命名
	if(!name) {
    
    
		name = "未命名";
	}
	this->name = new char[strlen(name) + 1];
	strcpy_s(this->name, strlen(name) + 1, name);
}

Boy& Boy::operator=(const Boy& boy) {
    
    
	if(name) delete name;
	this->name = new char[strlen(boy.name) + 1];
	strcpy_s(this->name, strlen(name) + 1, boy.name);
	return *this;
}

string Boy::getName() {
    
    
	return name;
}

Boy::~Boy() {
    
    
	if(name) delete[] name;
}

主函数入口点:

#include <iostream>
#include "Boy.h"

int main(void) {
    
    
	Boy boy1("大鱼");
	Boy boy2, boy3;
	
	boy3 = boy2 = boy1;
	cout << boy1.getName() << endl;
	cout << boy2.getName() << endl;
	cout << boy3.getName() << endl;

	return 0;
}

正确编译结果:
在这里插入图片描述
错误一:
如果定义成:

Boy& operator=(const Boy *boy);

这样定义,该函数不起作用,编译器不会识别为赋值运算符的重载,也就是:boy2 = boy1时不会调用这个函数。
这时调用的是编译器自动生成的赋值构造函数,但程序结束时会崩掉!
原因是,编译器自动生成的赋值构造函数是进行浅拷贝的,将指针name的值拷贝了,没有重新给name分配空间,导致三个对象中的数据name都使用同一个空间,析构函数调用了三次,同一个数据name被释放了三次,程序崩掉!!!

错误二:
如果定义:

Boy& operator=(const Boy boy);

有效果,但是在调用时,会执行参数的传递:
就是说,执行boy2 = boy1;时,就会执行: boy2.operator=(boy);
然而,执行 boy2.operator=(boy);时,就会执行: const Boy boy = boy1;
执行 const Boy boy = boy1;,就会执行Boy类的拷贝构造函数!
但是,并没有定义拷贝构造函数。那么,编译器会自动生成拷贝构造函数,进行浅拷贝!

浅拷贝就是直接把boy1.name这个指针变量的值直接拷贝到指针boy.name,导致这两个指针指向同一个地址,这就很危险!由于boy这个变量是临时变量,在这个函数执行完之后,就会消亡!消亡就会调用析构函数释放掉内存,这时,boy1.name与boy.name指向的值就是随机的,乱七八糟的数据,如下:
在这里插入图片描述
这样定义赋值构造函数:Boy& operator=(const Boy boy),有两个影响:
1)浪费性能
2)如果没有自定义的拷贝构造函数,而且这个类又有指针成员时,就会调用自动生成的拷贝构造函数,导致浅拷贝
如果析构函数中,对这个指针指向的内存做了释放,那就导致数据损坏或程序崩溃!

小结:
1)赋值运算符的重载,一定要使用引用参数
2)如果一个类有指针成员,而且使用了动态内存分配,那么一定要定义自己的拷贝构造函数【要使用深拷贝】,避免调用自动生成的拷贝构造函数
因为自动生成的拷贝构造函数,是浅拷贝!

猜你喜欢

转载自blog.csdn.net/weixin_46060711/article/details/124358415