为什么C ++编译器不定义operator ==和operator!=?

我非常乐于让编译器为您完成尽可能多的工作。编写简单的类时,编译器可以为您提供以下“免费”功能:


默认(空)构造函数

复制构造函数

析构函数

赋值运算符(operator=)

但是它似乎无法为您提供任何比较运算符-例如operator==或operator!=。例如:


class foo

{

public:

    std::string str_;

    int n_;

};


foo f1;        // Works

foo f2(f1);    // Works

foo f3;

f3 = f2;       // Works


if (f3 == f2)  // Fails

{ }


if (f3 != f2)  // Fails

{ }

是否有充分的理由呢?为什么进行逐成员比较会是一个问题?显然,如果该类分配了内存,那么您要格外小心,但是对于一个简单的类,编译器肯定可以为您执行此操作吗?



红颜莎娜
浏览 367回答 3
3回答

胡说叔叔

编译器不会知道您要进行指针比较还是深度(内部)比较。只执行而不让程序员自己做是比较安全的。然后他们可以做出所有喜欢的假设。

跃然一笑

如果编译器可以提供默认的副本构造函数,那么它应该能够提供类似的默认值的说法operator==()具有一定意义。我认为,决定不提供该运算符生成的编译器默认值的原因可以由Stroustrup在“ C ++的设计和演变”(第11.4.1节-复制控制)中对默认副本构造函数的说明中得出。 :我个人认为很遗憾,默认情况下定义了复制操作,并且禁止复制许多类的对象。但是,C ++从C继承了其默认赋值和复制构造函数,并且它们经常使用。因此operator==(),问题应该是“为什么C ++具有默认的赋值和复制构造函数?”,而不是“为什么C ++没有默认的?”,答案是Stroustrup勉强地包含了这些项,以实现与C的向后兼容性。 (可能是大多数C ++疣的原因,但也可能是C ++普及的主要原因)。出于我自己的目的,在我的IDE中,我用于新类的代码段包含一个私有赋值运算符和复制构造函数的声明,因此,当我生成一个新类时,我没有默认的赋值和复制操作-我必须显式删除该声明private:如果我希望编译器能够为我生成这些操作,请参阅本节中的这些操作。

牧羊人nacy

即使在C ++ 20中,编译器仍然不会operator==为您隐式生成struct foo{&nbsp; &nbsp; std::string str;&nbsp; &nbsp; int n;};assert(foo{"Anton", 1} == foo{"Anton", 1}); // ill-formed但是您将拥有显式默认的功能==:struct foo{&nbsp; &nbsp; std::string str;&nbsp; &nbsp; int n;&nbsp; &nbsp; // either member form&nbsp; &nbsp; bool operator==(foo const&) const = default;&nbsp; &nbsp; // ... or friend form&nbsp; &nbsp; friend bool operator==(foo const&, foo const&) = default;};默认值==是按成员进行的==(与默认副本构造函数按成员进行复制的方式相同)。新规则还提供==和之间的预期关系!=。例如,使用上面的声明,我可以同时编写:assert(foo{"Anton", 1} == foo{"Anton", 1}); // ok!assert(foo{"Anton", 1} != foo{"Anton", 2}); // ok!这种特殊的功能(默认operator==和之间的对称==和!=)来自一个建议,这是更广泛的语言特点,那就是的一部分operator<=>。
打开App,查看更多内容
随时随地看视频慕课网APP