Effective C++条款23:宁以non-member、not-friend替换member函数

假如有一个以下的类,用来表示网页浏览器,其中有一些函数用来清除下载元素高速缓冲区、清楚访问过的URLs的历史记录、以及移除系统中的所有cookies:

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

许多用户想一次性执行所有这些动作,因此WebBroswer提供这样一个函数:

class WebBroswer
{
public:
	...
	void clearEverything();//调用clearCache,clearHistory,removeCookies
	...
};

当然,我们也可以提供一个非成员函数:

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

现在问题来了:哪一个比较好呢?是成员函数还是非成员函数?

面向对象守则要求数据一个尽可能被封装,成员函数提供clearEverything带来的封装性比非成员函数clearBrowser低。此外提供非成员函数可允许堆WebBrowse相关技能有较大的包裹弹性,因为这会导致相对较低的编译相依度,增加WebBrowser的可延伸性.

原因如下:
如果某些东西被封装,它就不可见,越多东西被封装,越少人可以看到它。而越少人看到它,我们就有越大的空间去变化它。因为我们的改变仅仅影响到那些看到改变的那些人和事物。也就是说,越多东西被封装,我们改变那些东西的能力越大,这就是我们推崇封装的原因。

考虑对象内的数据,越少代码可以看到数据,越多的数据被封装,我们就越能自由地改变对象数据。那如何判断一个数据的封装性呢
可以计算能够访问该数据的函数数量,作为一个粗糙的量测。越多函数可以访问它,数据的封装性就越低。

如果你在一个成员函数和一个非成员,非友元函数之间,两者提供相同的功能,那么导致较大封装性的是非成员非友元函数,因为它并不增加"能够访问类内私有成分"的函数数量。这就解释了为什么clearBrowseclearEverything更好的原因:它导致WebBrowse class有较大的封装性

注意:
因为封装性而让函数成为类的非成员函数并不意味着它不可用是另外一个类的成员。 比如我们可以让clearBrowser成为工具类的静态成员函数,只要它不是WebBrowse的一部分就不会影响WebBrowse的私有成员封装性.

在C++里面,比较自然的做法是让clearBrowser成为一个非成员函数并且位于和WebBrowse同一个命名空间内:

namespace WebBrowserStuff
{
	class WebBrowser{...};
	void clearBrowser(WebBrowser & wb);
}

总结:

宁可拿non-member non-friend函数替换member函数。这样可以增加封装性、包裹弹性和机能扩充性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值