一、主要观点:
- 在某些情况下,使用
non-member
、non-friend
函数来替换member
函数可以增强封装性和可扩展性,提供更好的软件设计。
二、详细解释:
-
封装性:
- 类成员函数的封装性考量:成员函数可以访问类的
private
成员,这在一定程度上破坏了封装性。因为它拥有比实际所需更多的对类内部的访问权限。例如,对于一个类Widget
的成员函数,它可以访问类的所有private
数据成员和函数,即使某些数据或函数并不需要被该成员函数操作。 - non-member、non-friend 函数的优势:
non-member
、non-friend
函数只能通过类的public
接口来访问类,这意味着它们不能直接访问类的private
成员。这种方式可以将类的内部实现细节更好地隐藏起来,增强封装性。例如,对于一个处理Widget
类对象的non-member
、non-friend
函数,它只能通过Widget
类的public
接口进行操作,不能访问Widget
类内部的private
成员,这样类的内部实现可以更加自由地修改而不影响这个外部函数。
- 类成员函数的封装性考量:成员函数可以访问类的
-
可扩展性:
- 对类功能的扩展更灵活:使用
non-member
、non-friend
函数可以将不同的功能分布在不同的函数中,而不是将所有功能都集中在类的成员函数里。这样,当需要对类的功能进行扩展时,可以方便地添加新的non-member
、non-friend
函数,而不需要修改类的内部实现。 - 命名空间的使用:可以将相关的
non-member
、non-friend
函数放在一个命名空间中,形成一个功能集合。这样可以更好地组织代码,并且可以根据不同的功能模块将函数分类到不同的命名空间中,方便代码的管理和维护。例如:
namespace WidgetStuff {class Widget {... };void doSomething(Widget& w);void doAnotherThing(Widget& w); }
这里,
doSomething
和doAnotherThing
是non-member
、non-friend
函数,它们通过Widget
的public
接口操作Widget
类,当需要添加新的操作Widget
的函数时,只需在WidgetStuff
命名空间中添加即可,而不用修改Widget
类。 - 对类功能的扩展更灵活:使用
-
编译依赖关系:
- 减少依赖:
member
函数的修改通常会导致类的重新编译,因为它是类定义的一部分。而non-member
、non-friend
函数的修改通常只需要重新编译该函数本身,减少了对类的依赖。这在大型项目中可以提高编译速度。 - 降低耦合:
non-member
、non-friend
函数与类的耦合度相对较低,使得类的接口更加稳定,避免因修改函数而影响类的内部实现和其他使用该类的代码。
- 减少依赖:
-
示例说明:
- 考虑一个表示网页浏览器的类
WebBrowser
,可能有清除缓存、清除历史记录、清除 Cookies 等操作。可以有两种实现方式:
class WebBrowser { public:void clearCache();void clearHistory();void clearCookies();void clearEverything() { // member functionclearCache();clearHistory();clearCookies();} };
或者使用
non-member
、non-friend
函数:class WebBrowser { public:void clearCache();void clearHistory();void clearCookies(); };void clearEverything(WebBrowser& wb) { // non-member, non-friend functionwb.clearCache();wb.clearHistory();wb.clearCookies(); }
在这个例子中,使用
non-member
、non-friend
函数clearEverything
可以将清除操作的功能与WebBrowser
类分离,避免WebBrowser
类变得臃肿,同时也不会增加WebBrowser
类的封装性负担,因为clearEverything
函数无法访问WebBrowser
类的private
成员。 - 考虑一个表示网页浏览器的类
三、总结:
- 为了实现更好的封装性、可扩展性、降低编译依赖和降低耦合度,在某些情况下,应该优先考虑使用
non-member
、non-friend
函数而不是member
函数。这有助于将类的功能分离,提高代码的可维护性和组织性,同时使类的内部实现更加独立和灵活。