条款23:宁以non-member、non-friend替换member函数

/**********************************************************************
//对下类提供一个清理全部的函数
class WebBrowser
{
public:
void cleanCache();
void cleanHistory();
void cleanCookies();
//1. 提供一个member函数,调用前面三个函数
void cleanEverything();
};


//2. 提供一个non-member函数
void cleanBrowser(WebBrowser& wb)
{
wb.cleanCache();
wb.cleanHistory();
wb.cleanCache();
}


//1和2哪一个函数好
//面向对象守则要求,数据以及操作数据的那些函数应该捆绑在一起,这意味着它建议member函数是较好的选择
//不幸的是这个建议不正确,这是基于对面向对象真实意义的一个误解

//面向对象守则要求数据应该尽可能被封装,而1的封装比2的封装性低,越多东西被封装,越少人可以看到它,而越少人看到它,我们有越大的弹性去改变它,因此提供2(non-member)函数可允许对WebBrowser相关机能有较大的包裹弹性,而最终导致较低的编译相依度,增加了可延伸性。

//考虑对象内的数据。越少代码可以看到数据(也就是访问它)越多的数据可被封装,而我们也就越能自由地改变对象数据。量测“有多少代码可以看到某一块数据”,可以计算能够访问该数据的函数数量作为粗糙的量测标准。

//这个论述只适用于non-member non-friend函数。

//我们也可以令cleanBrowser成为某个工具类(utility class)的static member函数
//但在C++中比较自然的方法是让cleanBrowser成为一个non-member函数,并且位于WebBrowser所在的同一个namespace内如
namespace WebBrowserStuff
{
class WebBrowser{};
void cleanBrowser(WebBrowser& wb);
...
}
//这不只是看起来自然而已,namespace和class不同,前者可跨跃多个源文件,而后者不能
//这很重要,像cleanBrowser这样的函数是一个“提供便利的函数”,如果他既不是members也不是friends,就没有对WebBrowser的特殊访问权利,也就不能提供“WebBrowser客户无法以其它方式取得”的机能。


文件组织示例


//头文件WebBrowser.h针对class WebBrowser自身及核心功能
namespace WebBrowserStuff
{
class WebBrowser{};
... //核心功能,例如几乎所有客户都需要的,non-member函数
}


//头文件WebBrowserBookMarks.h
namespace WebBrowserStuff
{
... //与书签相关的便利函数
}


//头文件WebBrowserCookies.h
namespace WebBrowserStuff
{
... //与cookie相关的便利函数
}


这正是C++标准程序库的组织方式,这允许客户只对他们所用的那一小部分系统形成编译相依。
以此种方式切割机能并不适用于class成员函数,因为一个class必须整体定义,不能被分割为片片段段
**********************************************************************/


//我们首推封装的原因:它使我们能够改变事物而只影响有限客户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值