Item 23 多考虑“非成员、非友元”函数

class WebBrowser { public: ... void clearCache(); void clearHistory(); void removeCookies(); ... };

 

为了提供一站式服务,定义一个“清除一切”的函数。下面是两种方案:

1> 成员函数

class WebBrowser { public: ... void clearEverything(); ... };

 

2> 非成员、非友元函数

void clearBrowser(WebBrowser& wb) { wb.clearCache(); wb.clearHistory(); wb.removeCookies(); }

 

这两种方式哪种更好?这要从面向对象的根本谈起。
所谓面向对象,并不是把操作和数据搞到类里越多,才是好的封装。封装,是针对数据来说的。
上面的成员函数,其实对数据的封装不算好。那个非成员非友元的“双非”函数,才是封装的较好的。不仅如此,它还为WebBrowser提供了更好的扩展性,减少了编译依赖。

先说封装。封装的越多,客户看见的就越少,从而程序员就有更多的空间去修改。
再说对象内部的数据。某个数据被访问的越少,被封装的就越完全,程序员也就有越多的修改权。
若数据声明为公有或protected,则有无穷多的函数访问它,就是无封装。
私有的成员,只有成员函数、友元函数可以访问。
第一种方法定义为成员函数,增加了访问次数,相当于减弱了封装。反之,双非函数是好封装。不过,可以把clearBrowser放到别的类里。那样做不算破坏WebBrowser的封装。

另外,像WebBrowser这样的类可能有很多“便利函数”,比如为书签、打印等工作提供快捷调用的函数。常见的作法是:

// file: webbrowser.h // 提供WebBrowser的核心功能 namespace WebBrowserStuff { class WebBrowser { ... }; ... } // file: webbrowserbookmarks.h // 书签相关的便利函数 namespace WebBrowserStuff { void addBookmark(WebBrowser& wb, const URL& url); ... } // file: webbrowsercookies.h // Cookie相关的便利函数 namespace WebBrowserStuff { void removeCookie(WebBrowser& wb); ... } ...

 

所有的便利函数,都在WebBrowserStuff这个名字空间里。
STL就是这样组织的。

你可能感兴趣的:(Effective,C++)