第四部分 设计与声明(2)(条款23:宁以non-member、non-friend替代member函数)

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

思考下面的问题:

一个网页浏览器类

class WebBrowser{

  public:

    ...

   void clearCache();//清除Cache

   void clearHistory();//清除History

   void removeCookies();//清除Cookies

  ...

};

现在用户可能还希望清除所有(以上三种),因此WebBrowser提供了这样一个函数:

class WebBrowser{

   ...

   void clearEverything();

  ...

};

当然我们也可以这么做:

void clearBrowser(WebBrowser& wb)

{

  wb.clearCache();

  wb.clearHistory();

  wb.clearCoockies();

}

现在的问题是哪个好?为什么?

    首先我们讨论封装。如果某些东西被封装,他就不再可见。越多的东西被封装,越少人可以看到它,我们就有越大的弹性去改变它,因为我们的改变只会影响到那些可以直接看到改变的人。这就是我们首先推崇封装的原因:它使我们能够改变事物而只影响有限客户。

   现在考虑对象里的数据。愈少的代码可以看到数据,愈多的数据被封装,而我们也就愈能自由的改变对象数据。数据被愈多的函数访问,数据的封装性就越低。

   As we know,成员变量应该为private,因为如果它不是,就有无限的函数去访问它,那么它就毫无封装性。能够访问private成员只有class的member函数和friend函数。那么现在我们已经知道了,clearBrowser函数比clearEverything函数更受到欢迎,因为它具有更大的封装性。

   这里有值得注意的地方,只因在意封装性而让函数“成为class的non-member”,并不意味着“不可以是另外一个class的member”。for example,我们可以让clearBrowser函数成为某个工具类的static member函数。只要它不是WebBrowser的一部分(或成为其friend),就不会影响WebBrowser的private成员的封装性。

    在C++中,我们可以这样做

   namespace WebBrowserStuff{

   class WebBrowser{...};

   void clearBrowser(WebBrowser& wb);

   ...

}

对于namespace,它与class不同,前者可以跨越多个头文件,为了方便我们可以定义多个头文件:

//头文件 "webbrowser.h" -----这个针对class WebBrowser本身及WebBrowser的核心机能。

namespace WebBrowserStuff{

  class WebBrowser{...};

  ...

}

//头文件 "webbrowserbookmarks.h"

namespace WebBrowserStuff{

  ...

}

//头文件 "webbrowsercookies.h"

namespace WebBrowserStuff{

  ...

}

...

将便利函数放在多个头文件内但是属于同一个名字空间,意味着客户可以轻松扩展这组便利函数。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值