EffictiveC++

2 篇文章 0 订阅
1 篇文章 0 订阅

Effictive C++

条款24

  • 宁以non-member,no-friend,替换member函数

想象有个class用来表示网页浏览器,这样的class可能提供的众多函数中,一些用来清除下载元素的高速缓冲区,历史记录以及cookies

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

若采用成员函数方案,我们可能会考虑提供这样一个函数:

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

同时也可以由非成员函数提供

void clearBrowser(WebBrowser& wb)
{
        wb.clearCache();
        wb.clearHistory();
        wb.removeCookies();
}
  • 孰优孰劣?
  • 从面对对象守则要求来看,数据以及操作数据的那些函数应该被捆绑在一块,这意味它建议的member函数是较好的选择。不幸的是这是一个误解。面对对象守则要求数据应该尽可能的被封装,然而与直观相反的,member函数带来的封装性比 no-member函数低。此外提供member函数可允许对WebBrowser相关技能有较大的包裹弹性,导致较低的编译相依度,曽家WebBrowser的可延伸性,因此在许多方面no-member比member函数做法更好。why?

  • 从封装谈起,如果某些东西被封装,它就不再可见,愈多东西被封装,愈少人可以看到他,而愈少的人看到意味着我们有更大的弹性去变化它,因为我们的变化仅仅影响看到改变的那些人事物。因此越多东西被封装,我们改变那些东西的能力就越大,这就是首先我们推崇封装:改变事物而只影响有限客户。

  • 现在考虑对象内的数据:越少的代码可以看到数据,越多的数据可被封装。现在我们也就能越自由的改变对象数据,例如改变成员变量的数量,类型等。那么 如何测量“多少代码可以看到某一块数据呢”?做一种粗糙的测量:愈多函数可访问封装性就越低

  • 接下来就是抉择:member函数:不知可以访问class内的private数据,也可以取用private函数,enums,typedefs等等。 no-member函数:无法访问上述任何。且两者提供相同性能,那么导致较大封装性的是non-member,non-friend函数。因为它并不增加“能访问class内private成分”的函数数量。这就解释了为什么一个clearBrowser 会比 clearEverything更受欢迎的原因:clearBrowser具有较大的封装性。

  • 第二件值得注意的事情。只因在意封装性而让函数“成为class的non-member”并不意味着它“不可以是另一个函数的member”,例如我们可以令clearBrowser成为某工具类的一个static member函数。
    在C++中比较自然的方法:让clearBrowser成为一个non-member函数并位于WebBrowswer同一个namespace中:

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

}

这不仅是看起来自然而已,若我们需要添加更多non-member函数到此命名空间内,我们只需在WebBrowserStuff命名空间内建立一个头文件内含那些函数声明即可,这允许客户只对他们所用的那一小部分系统形成编译相依。这是class所无法提供的另一个特质。

请记住

  • 宁可拿non-member,non-friend函数代替member函数,这样做可以增加封装性,包裹弹性以及机能扩充性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值