赋值运算符会出现和复制构造函数类似的问题。
cpp允许类对象赋值,这是通过自动为类重载赋值运算符实现的。这种运算符的原型如下:
Class_name & Class_name::operator=(const Class_name &);
-
赋值运算符的功能及何时使用它
将已有的对象赋给另一个对象时,将使用重载的赋值运算符:StringBad sb1("hahahah"); ... StringBad sb2; sb2 = sb1; // 初始化对象时,不一定会使用赋值运算符, // 可以理解为先使用复制构造函数创建了一个临时对象, // 然后通过赋值将临时对象的值复制到新对象中。 StringBad sb3 = sb1;
-
赋值运算符存在的问题
和复制构造函数相同,也是成员复制问题。由于浅拷贝,导致使用new初始化的指针成员数据受损。例如,当sb1调用析构函数时,其中的指针成员所指向的空间被释放,后面sb2调用析构函数时,则会出错。为解决该问题,应采用深拷贝自定义一个赋值运算符。其实现与复制构造函数相似,但也有一些差别。
① 由于目标对象可能引用了以前分配的数据,所以函数应使用delete[]来释放这些数据。
② 函数应当避免将对象赋给自身,否则给对象重新赋值前,释放内存操作可能删除对象的内容。
③ 函数返回一个指向调用对象的引用,以此实现连续赋值操作。以复制构造函数中的StringBad对象为例编写赋值运算符:
StringBad & StringBad::operator=(const StringBad & st) { if(this == $st) return *this; delete [] str; len = st.len; str = new char[len + 1]; std::strcpy(str, st.str); return *this; }
评论区