C++箴言:用非成员非友元函数取代成员函数

C++箴言:用非成员非友元函数取代成员函数,第1张

C++箴言:用非成员非友元函数取代成员函数,第2张

想象一个象征网络浏览器的类。在大量的函数中,这样的类可以提供一个缓存,用于清除空下载的组件。清除空访问过的URL的历史,以及从系统中删除所有cookies的功能:

class WebBrowser {
public:
...
void clear cache();
void clear history();
void remove cookies();
...
};

许多用户希望一起执行所有这些操作,因此WebBrowser可能也提供了这样的功能:

class WebBrowser {
public:
...
void clear everything();//调用clearCache、clearHistory、
//和removeCookies
...
};

当然,这个函数也可以由调用适当成员函数的非成员函数提供:

void clear browser(WebBrowser & WB)
{
WB . clear cache();
WB . clear history();
WB . remove cookies();
}

那么成员函数clearEverything和非成员函数clearBrowser哪个更好呢?

face object的原理指出,数据和对它们进行操作的函数应该绑定在一起,并建议成员函数是更好的选择。不幸的是,这个建议是不正确的。它来自于对什么是面向对象的误解。面向对象原则指出数据要尽可能封装。与直觉相反,成员函数clearEverything实际上会导致比非成员函数clearBrowser更差的封装。此外,非成员功能的提供允许WebBrowser相关功能的更大打包灵活性。此外,它还可以获得更少的编译依赖,提高WebBrowser的可扩展性。因此,非成员方法在许多方面都优于成员函数。了解其原因非常重要。

我们将从封装开始。如果某个东西被封装,它就隐藏起来了。封装的东西越多,能看到的东西就越少。越是看不到的东西,我们越是灵活的去改变它,因为我们的改变只直接影响那些能看到我们改变了什么的东西。一个东西的封装性越强,我们改变它的能力就越强。这就是为什么包装的价值是第一位的原因:它为我们提供了改变事物的灵活性,但只影响有限数量的客户。

考虑与对象相关的数据。代码能看到的数据(即访问数据)越少,数据封装就越强,我们改变对象数据特征的自由度就越大,比如数据成员的数量、类型等等。作为对一段数据有多少代码可以看到的粗略衡量,我们可以统计一下可以访问这段数据的函数的数量:可以访问的函数越多,数据的封装性就越弱。

成员应该是私有的,因为如果它们不是私有的,就有无限的函数可以访问它们。它们根本没有被封装。对于私有数据成员,可以访问它们的函数数是类的成员函数数加上友元函数数,因为只有成员和友元才能访问私有成员。假设在成员函数(不仅可以访问类的私有数据,还可以访问私有函数、枚举、typedefs等)之间有一个选择。)和一个提供相同功能的非成员非友函数(不能访问上面的东西)。可以得到更强封装的选择是非成员非友函数,因为它不会增加可以访问类私有部分的函数的数量。这就解释了为什么clearBrowser(非成员非友函数)比clearEverything(成员函数)更可取:它可以为WebBrowser获得更强的封装性。

在这一点上,有两件事值得注意。首先,这个论点只适用于非成员非友函数。友元可以像成员函数一样访问类的私有成员,所以它们也会影响封装。从封装的角度来看,选择不是在成员和非成员函数之间,而是在成员函数和非成员非友元函数之间。(当然,封装不是唯一的观点。如果观点来自隐式类型转换,那么选择是在成员函数和非成员函数之间。)

第二件要注意的事情是,仅仅关注封装,可以指出的是,仅仅因为一个函数是一个类的非成员,并不意味着它不能是另一个类的成员。对于习惯于所有函数都必须属于类的语言(例如,Eiffel、Java、C#等)的程序员来说,这是一种适度的安慰。).比如我们可以让clearBrowser成为utility类的静态成员函数。只要不是WebBrowser的一部分(或者朋友),就不会影响WebBrowser私有成员的封装。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C++箴言:用非成员非友元函数取代成员函数

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情