class WebBrowser
{
public:
...
void clearCache();
void clearHistory();
void removeCookies();
...
};
如果想执行类里面所有的动作,有点用户可能会提供这样的一个函数
class WebBrowser
{
public :
...
void clearEverything(); //调用clearCache,ClearHistory,和removeCookies
...
};
当然,这一操作也可以由一个非成员函数调用适当的成员函数而提供出来:
void clearBrowser( WebBrowser& wb)
{
wb,clearCache();
wb.clearHistory();
wb.removeCookies();
}
那么哪一个比较好呢,是成员函数,还是非成员函数呢?
让我们从封装开始讨论,如果某些东西被封装,它就不可再见。愈多东西被封装,愈少人看到它,而愈少人看到它,我们就有愈大的弹性去改变它,因为我们改变的只是直接影响看到改变的那些人事物。因此愈多东西被封装,我们改变那些东西的能力就愈大。这就是我们首先推崇封装的原因:它使我们改变事物而只影响有限客户。
对数据而言,愈多的数据可被封装,而我们也就愈能地自由地改变对象数据。不让访问,愈多的函数可以访问它,数据的封装性就愈低。
所以导致较大的封装性的是非成员函数和非友元函数,因为它并不增加“能够访问class内的private成员“这就解析了为什么。
第二件值得注意的事情是,只因在封装性而让函数成为class的非成员函数并不意味着它不可以是另一个class的成员函数,
namespace WebBrowserStuff
{
class WebBrowserStuff{ ...};
void clearBrowser( WebBrowser& wb);
....
}
然而这并不是为了好看而已,要知道,命名空间和类不同,前者可以跨越多个源码文件而后者不能。这很重要。
如果clearBrowser不存在,类对象只能自行调用clearCache,clearHistory和removeCookies.
但是通常大多数客户只对其中某些含兴趣。
//头文件“webbrowser.h"
namespace WebBrowserStuff
{
class WebBrowser{....};
... //核心机能,例如几乎所有客户需要的非成员函数。
}
//头文件“webbrowserbookmarks.h"
namespace WebBrowserStuff
{
... //与书签相关的便利函数
}
//头文件” webbrowsercookies.h"
namesapce WebBrowserStuff
{
... //与cookie相关的便利函数
}
将所有便利函数放在多个头文件内当隶属同一个命名空间,意味着客户可以轻松扩张这一组便利函数,他们需要做的是就是添加更多的非成员函数和非友元函数到此命名空间。这是class无法提供的另一个性质,因为class定义无法对客户不能扩展的。