创建复制构造函数时如何正确重载运算符=

How do I properly overload a operator= when creating a copy constructor

提问人:Xenon The Friend 提问时间:11/12/2020 更新时间:11/12/2020 访问量:301

问:

我正在我的大学里做一个C++的讲座,我无法真正理解运算符=应该做什么以及如何正确地重载它。在我能找到的几乎所有讲座示例中,复制和移动构造函数的代码部分如下所示:

class MyClass {
MyClass(const MyClass& s) {
copy(s); // the function is supposed to do the copying.
}
MyClass& operator=(const MyClass& s){
if(this != &s){ remove(); copy(s);} // the remove function is defined later on in the code, and it 
           return *this;}                            deletes a given pointer.   

现在我的问题是,为什么有一个 if 语句 her 以及它的作用,是否有另一种方法可以正确重载 operator=,为什么我们在运算符重载中返回类引用?如果我们按值而不是按引用返回它会是错误的吗?另外,什么时候复制东西是个坏主意,因为我读过很多关于复制如何导致内存泄漏的信息,但我从未见过这样的事件,所以我不知道该怎么做。任何帮助将不胜感激!

C++ 运算符重载 copy-constructor

评论

0赞 Pete Becker 11/12/2020
该测试使写作无害。a = a;

答:

2赞 Sam Varshavchik 11/12/2020 #1

这与复制构造函数无关。

这是在将对象分配给自身时检查边缘情况:

MyClass c;

// Some code

c=c;

c=c是完全有效的C++。您可以将对象分配给自身。据推测,您期望这不会做任何事情。此对象不会更改。

当赋值运算符本身在调用复制构造函数进行自赋值时,赋值运算符本身会严重中断时,就会完成与赋值运算符的比较。在本例中,如果与 是相同的对象。thissthis

没有法律规定赋值运算符必须进行这种比较。许多赋值运算符重载可以正常工作,即使在将对象赋值给自己时也是如此。

但是,无论这个赋值运算符做什么,如果赋值来自自身,它都不会起作用。你没有展示这个赋值运算符是做什么的,但它调用一个叫做的东西的事实是一个很大的线索。它从对象中删除了某些内容,因此如果没有此检查,将此对象分配给自身将使其完全“空”。这将是一件相当粗鲁的事情,你不同意吗?remove

评论

0赞 Xenon The Friend 11/12/2020
非常感谢您的回复,并为我澄清了问题。我一直在想,每次定义复制构造函数时都必须重载 = 运算符。这个检查是应该做的事情吗,没有它程序会正常工作吗?再次感谢!
0赞 Sam Varshavchik 11/12/2020
通常,当图片中有复制构造函数时,还需要赋值运算符,但只是出于相同的基础原因,而不一定是实现复制构造函数。没有法律规定,当存在复制构造函数时,必须实现赋值运算符。但是,根据赋值运算符实现复制构造函数是一种相当常见的方法。我在我的回答中解释了进行此检查的原因。同样,没有法律规定必须在每个赋值运算符中完成。但必须在其中一些人身上完成。
0赞 Red.Wave 11/12/2020 #2

曾经有一个过时的成语,叫做三巨头的规则。 该规则的推荐实现是另一个过时的 Copy+Swap 惯用语。这些习语为初学者 C++ 程序员提供了很好的起点。稍后,您可能会发现针对特殊情况的更好的权衡和优化的替代方案。就目前而言,坚持使用旧的习语 - 至少 - 可以提高对代码的功能和正确性的保证。

干杯 调频。