我非常支持让编译器为你做尽可能多的工作。当编写一个简单的类时,编译器可以为你提供以下“免费”:
默认(空)构造函数
复制构造函数
一个析构函数
赋值运算符(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
{ }
这有什么好的理由吗?为什么执行逐个成员的比较是一个问题?显然,如果类分配内存,那么你要小心,但对于一个简单的类,编译器肯定可以为你做这个?
如果编译器可以提供默认的复制构造函数,它就应该能够提供类似的默认操作符==(),这在一定程度上是有意义的。我认为决定不为该操作符提供编译器生成的默认构造函数的原因可以从Stroustrup在“c++的设计和发展”(第11.4.1节-复制的控制)中关于默认复制构造函数的描述中猜到:
我个人认为这很不幸
定义的复制操作
默认和我禁止复制
我的许多类的对象。
然而,c++继承了它的默认值
赋值和复制构造函数
C,它们经常被使用。
因此,问题不应该是“为什么c++没有默认的操作符==()?”,而应该是“为什么c++有默认的赋值和复制构造函数?”,答案是Stroustrup为了向后兼容C而不情愿地包含了这些项(可能是c++的大部分缺点的原因,但也可能是c++流行的主要原因)。
出于我自己的目的,在我的IDE中,我用于新类的代码片段包含私有赋值操作符和复制构造函数的声明,因此当我生成一个新类时,我没有得到默认的赋值和复制操作——如果我想让编译器能够为我生成这些操作,我必须显式地从private:节中删除这些操作的声明。
在这个视频中,STL的创造者Alex Stepanov在13:00左右回答了这个问题。总结一下,在见证了c++的发展之后,他认为:
It's unfortunate that == and != are not implicitly declared (and Bjarne agrees with him). A correct language should have those things ready for you (he goes further on to suggest you should not be able to define a != that breaks the semantics of ==)
The reason this is the case has its roots (as many of C++ problems) in C. There, the assignment operator is implicitly defined with bit by bit assignment but that wouldn't work for ==. A more detailed explanation can be found in this article from Bjarne Stroustrup.
In the follow up question Why then wasn't a member by member comparison used he says an amazing thing : C was kind of a homegrown language and the guy implementing these stuff for Ritchie told him he found this to be hard to implement!
然后他说,在(遥远的)未来,==和!=将隐式生成。