优雅的处理自我赋值

之前写过一个简单的vector,Clang-tidy警告:

Operator=() does not handle self-assignment properly

为什么要警惕自我赋值呢?一个经典的例子是当你赋值的时候需要先删除原来的值时,不做处理的自我赋值就会造成错误。
例如如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class T {
int* p;

public:
// rhs 即 Right Hand Side 。
T(const T& rhs){
if(rhs.p) p = new int(*rhs.p);
else p = nullptr;
}
~T() { delete p; }

// ...

T& operator=(const T& rhs) {
delete p;
p = new int(*rhs.p);
return *this;
}
};

这时如果有一个T类型的变量a, 并且执行a = a的话,就会出现错误。

一种显然的解决办法是,先判断是否为自己,如果是,则不做处理。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class T {
int* p;

public:
// rhs 即 Right Hand Side 。
T(const T& rhs){
if(rhs.p) p = new int(*rhs.p);
else p = nullptr;
}
~T() { delete p; }

// ...

T& operator=(const T& rhs) {
if (this == &rhs) return *this;
delete p;
p = new int(*rhs.p);
return *this;
}
};

这样的代码就完美了吗,并没有,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class T {
int* p;

public:
// rhs 即 Right Hand Side 。
T(const T& rhs) {
if (rhs.p)
p = new int(*rhs.p);
else
p = nullptr;
}
~T() { delete p; }

// ...

T& operator=(const T& rhs) {
if (this == &rhs) return *this;

delete p;
try {
p = new int(*rhs.p);
} catch (std::bad_alloc&) {
p = nullptr;
throw;
}
return *this;
}
};

未完待续。。。

作者

YunShu

发布于

2022-06-23

更新于

2022-06-23

许可协议

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×