[英]Preferring non-member non-friend functions to member functions
这个题目标题取自Scott Meyers的Effective C ++ 3rd Edition中第23项的标题。 他使用以下代码:
class WebBrowser {
public:
void clearCache();
void clearHistory();
void removeCookies();
//This is the function in question.
void clearEverything();
};
//Alternative non-member implementation of clearEverything() member function.
void clearBrowser(WebBrowser& wb) {
wb.clearCache();
wb.clearHistory();
wb.removeCookies();
};
虽然声明下面的替代非成员非友元函数比成员函数clearEverything()更适合封装。 我想部分想法是,如果提供访问的成员函数较少,则访问WebBrowser的内部成员数据的方法较少。
如果你接受这个并使这种外部非朋友功能的功能,你会把它们放在哪里? 函数仍然与类紧密耦合,但它们将不再是类的一部分。 将它们放在类的相同CPP文件中,在库中的另一个文件中,或者什么?
我主要是来自C#背景,而且我从来没有对所有成为课堂成员的渴望摆脱那种渴望,所以这让我感到有些困惑(虽然听起来可能很傻)。
通常,您可以将它们放在关联的命名空间中。 这(在某种程度上)与C#中的扩展方法有相同的功能。
问题是在C#中,如果你想制作一些静态函数,它们必须在一个类中,这是荒谬的,因为根本没有OO - 例如,Math类。 在C ++中,您可以使用正确的工具来完成这项工作 - 命名空间。
所以, clearEverything
都是一种非常必要的便利方法。 但是由你来决定它是否合适。
这里的哲学是类定义应尽可能保持最小,并且只提供一种方法来完成某些事情。 这降低了单元测试的复杂性,交换替代实现的整个类所涉及的难度,以及可能需要被子类覆盖的函数数量。
通常,您不应该只使用一系列其他公共成员函数的公共成员函数。 如果你这样做,它可能意味着:1)你的公共接口太详细/细粒度或其他不合适,被调用的函数应该是私有的,或者2)该函数应该真正在类外部。
汽车类比:喇叭通常与踩刹车一起使用,但添加一个新的踏板/按钮同时做两件事是愚蠢的。 Car.brake()
和Car.honk()
是由Driver
执行的功能。 然而,如果Car.leftHeadLampOn()
和Car.rightHeadLampOn()
是两个独立的公共方法,它可能是过度细粒度控制的一个例子,设计者应重新考虑给Driver
单Car.lightsOn()
开关。
在浏览器示例中,我倾向于同意Scott Meyers的观点,即它不应该是成员函数。 但是,将它放在浏览器命名空间中也可能不合适。 也许最好让它成为控制Web浏览器的东西的成员,例如GUI事件处理程序的一部分。 MVC专家随时可以从这里接管。
我做了很多。 我总是把它们放在与其他类成员函数相同的.cpp中。 我不认为有任何二进制大小开销取决于你放置它们的位置。 (除非你把它放在标题中:P)
如果你想沿着这条路走下去, clearEverything
clearEverything的clearEverything
应该放在标题(声明)和类的实现中 - 因为它们是紧密耦合的,似乎是放置它们的最佳位置。
但是我倾向于将它们作为类的一部分 - 因为将来你可能有其他事情要清除,或者可能有更好或更快的实现来实现clearEverything
例如删除数据库并重新创建表
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.