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

版权声明:仅供参考与学习交流 https://blog.csdn.net/lym940928/article/details/81951767

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

Prefer non-member non-friend functions to member.
本章分为两个部分。
假设有一个class用来表示网页浏览器。这样的class可能提供的众多函数中:

  • 有一些用来清除下载元素高速缓存区(cache of downloaded elements)
  • 清除访问过的URLs的历史记录(history of visited URLs)
  • 清除系统中的所有cookies
class WebBrowser {
public:
    ...
    void clearCache();
    void clearHistory();
    void removeCookies();
    ...
};

因此,用户可能会觉得使用一个操作来执行这些任务,因此WebBrowser也提供这样一个函数:
- member函数

class WebBrowser {
public:
    ...
    void clearEverything();  //调用上述的三个函数
};

同时,这个机能也可以通过一个non-memebr函数调用适当的member函数而提供:
- non-member函数

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

那么,对于上面两个办法,哪一种较好呢?
首先,对于面向对象守则的要求,数据及操作数据的那些函数应该被捆绑在一起。这就意味着使用member函数可能是一个比较好的选择。然而事实上并非如此!

  • 面向对象守则要求数据应该尽可能地被封装,而与直观相反的是,member函数clearEverything所带来的封装性比non-member函数clearBrowser要低。

此外,提供non-member函数可允许对WebBrowser相关机能有较大的包裹弹性(packaging flexibility),而那最终导致较低的编译相依度,增加WebBrowser的可延伸性

  • 因此,许多方面non-member做法比member做法好。

首先,从封装开始讨论。

  • 如果某些东西被封装,它就不再可见。越多的东西被封装,就越少的人可以看见。而越少的人可以看到它,我们就有越大的弹性去改变它,因为我们的改变仅仅直接影响看到改变的那些人事物。因此,越多的东西被封装,我们改变这些东西的能力就越大。简而言之,封装使得我们能够改变事物而只影响有限的用户。

然后,考虑对象内的数据

  • 越少的代码可以看到数据(即访问到它),越多的数据就可以封装,而我们就越能自由地改变对象数据,例如改变成员变量的数量、类型等。简而言之,越多的函数可以访问这个数据,它的封装性就越低。

在上一个条款22中可以得知,成员变量应该是private,因为如果它们不是private,就会有无限量的函数可以访问到它们,它们也就毫无封装性。

  • 能够访问private成员变量的函数只有class的member函数加上friend函数

对于member函数,它可以访问class内的:

  • private数据
  • private函数
  • enums
  • typedefs
  • 等等

而对于non-member函数,它无法访问上述的任何一个。
如果我们需要在member函数和non-member函数中选择,而且两者提供相同的机能,则:

  • 导致较大封装性的是non-member non-friend函数,因为它并不会增加“能够访问class内的private”的函数数量。

因此,这也就解释了为什么clearBrowser(non-member non-friend函数)比clearEverything(member函数)更受欢迎:
它导致WebBrowser class有有较大的封装性。

扫描二维码关注公众号,回复: 3055541 查看本文章

猜你喜欢

转载自blog.csdn.net/lym940928/article/details/81951767