cpp的赋值运算符重载

赋值运算符 的重载通常使用普通的成员函数来实现,为什么讲这个,因为我今天在写代码过程中发现一个bug,并且一开始没发现是这个问题(自赋值)。

1
C1 &operator=(const C1 &c);

我发现如果一旦当赋值操作涉及内存操作,如动态内存的开辟和释放,并且不小心使用了 A=A 这种操作时,就会引发严重的后果,例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
C1 &C1::operator=(const C1 &c){
    if(data) delete[] data;
    length = c.length;
    data = new char[c.length];
    for(int i{0};i < c.length; ++i){
        data[i] = c.data[i];
    }
    return *this;
}

v1 = v1 // 出现这种语句会引发严重后果

所以一般都需要自检(检查即将assign的这个值)是否已经是自己,本身。

1
2
3
 if (this == &c){
    return *this;
 }

在赋值重载的过程中,应该要有一个这样的检查,因为a=a赋值,本身最好的情况就是整个代码逻辑没有什么变化,行为也不会发生变换;最坏的情况就是程序直接崩溃,一旦我们读取已经释放的内存,就会引发非常严重的后果。

做一个这样检查是非常快,不会消耗什么资源的。

一般一个类写出来都会有复制构造,但是有时候往往我们不需要这种复制构造(可能引发严重的后果),有的类包含一些特殊的类似于锁等,必须由开发者专门编写深拷贝函数,我们可以通过手动显式申明来禁用他。

1
C1(const C1 &copy) = delete;

今天要说的就是这点的东西,以前在学习过程中忽略了很多东西,但是就是这些东西,往往会让我们踩坑,这种东西又急不来,只能写点文章记录一下,过程。

Last updated on Sep 05, 2023 08:48 UTC