繁体   English   中英

优先将非成员非朋友功能发送给成员函数

[英]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()是两个独立的公共方法,它可能是过度细粒度控制的一个例子,设计者应重新考虑给DriverCar.lightsOn()开关。

在浏览器示例中,我倾向于同意Scott Meyers的观点,即它不应该是成员函数。 但是,将它放在浏览器命名空间中也可能不合适。 也许最好让它成为控制Web浏览器的东西的成员,例如GUI事件处理程序的一部分。 MVC专家随时可以从这里接管。

我做了很多。 我总是把它们放在与其他类成员函数相同的.cpp中。 我不认为有任何二进制大小开销取决于你放置它们的位置。 (除非你把它放在标题中:P)

如果你想沿着这条路走下去, clearEverything clearEverything的clearEverything应该放在标题(声明)和类的实现中 - 因为它们是紧密耦合的,似乎是放置它们的最佳位置。

但是我倾向于将它们作为类的一部分 - 因为将来你可能有其他事情要清除,或者可能有更好或更快的实现来实现clearEverything例如删除数据库并重新创建表

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM