在(另有)优秀的书籍C++编码标准,第44项,标题为"首选写非成员非朋友函数"中,Sutter和Alexandrescu建议只有真正需要访问类成员的函数才能成为该类成员.所有其他只能使用成员函数编写的操作不应该是该类的一部分.他们应该是非成员和非成员.争论是:
它促进了封装,因为需要访问类的内部的代码较少.
它使编写函数模板变得更容易,因为您不必每次都猜测某个函数是否是成员.
它使类保持较小,从而使测试和维护更容易.
虽然我看到了这些论点的价值,但我发现了一个很大的缺点:我的IDE无法帮助我找到这些功能!每当我有某种对象时,我想看看它上面有哪些操作,我不能只输入" pMysteriousObject->
"并获得成员函数列表.
保持干净的设计最终会让您的编程生活更轻松.但这实际上会让我更难.
所以我想知道它是否真的值得这么麻烦.你怎么处理那件事呢?
Scott Meyers对Sutter有类似的看法,请看这里.
他还明确指出以下内容:
"基于他对各种类似字符串的类的工作,Jack Reeves观察到一些函数在成为非成员时不会"感觉"正确,即使他们可能是非朋友的非成员."最佳"界面对于一个班级来说,只能通过平衡许多相互竞争的问题来找到,其中封装的程度只有一个."
如果一个函数是"只是有意义"成为成员函数的东西,那就把它作为一个函数.同样,如果它不是主界面的一部分,并且"只是有意义"成为非成员,那就这样做吧.
需要注意的是,对于例如operator ==()的重载版本,语法保持不变.所以在这种情况下你没有理由不把它作为一个非成员的非朋友浮动函数声明在与该类相同的地方,除非它真的需要访问私有成员(根据我的经验,它很少会).即使这样,你也可以定义operator!=()一个非成员,并且在operator ==()方面.
我认为,在他们之间,Sutter,Alexandrescu和Meyers在C++的质量方面做得比其他任何人都要多,这并不是错的.
他们问的一个简单问题是:
如果效用函数有两个独立的类作为参数,哪个类应该"拥有"成员函数?
另一个问题是,您只能在您所控制的类中添加成员函数.您为std :: string编写的任何辅助函数都必须是非成员,因为您无法重新打开类定义.
对于这两个示例,您的IDE将提供不完整的信息,您将不得不使用"旧时尚方式".
鉴于世界上最有影响力的C++专家认为带有类参数的非成员函数是类接口的一部分,这对于IDE来说更是一个问题,而不是编码风格.
您的IDE可能会在一两个版本中更改,您甚至可以让它们添加此功能.如果你改变你的编码风格以适应今天的IDE,你可能会发现你将来会遇到更大的问题,而且代码是不可扩展的/不可维护的.