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

考虑下面这种经常出现的使用方式:

class webBroswer{
public:
    ...
    void clearCache();
    void clearHistory();
    void removeCookies();
    ...
};

那么很自然的就会想到增加这么一种清理方式:

class WebBrowser{
public:
    ...
    void clearEverything();
};

或者是这么一种清理方式:

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

如果要在功能相同的一个member function和一个non-member, non-friend function之间选的话,那么具有较高的封装性的是non-member, non-friend function.

(注意这里的在意封装性,让一个function成为一个class的non-member),不影响其成为另一个class的member函数,例如上面的clearBrowser函数来说,其完全可以作为某个工具类的static member函数)

一般的好的做法是让,clearBrowser放置在与clss WebBrowser相同的一个namespace里面。像下面这样:

namespace WebBrowserStuff{
    class WebBrowser{...};
    void clearBrowser(WebBrowser & wb);//类似clearBrowser这类的便利函数可以在一个namespace里面声明多个。
};

而且由于namespace可以跨头文件存在,这样也方便这类的工具函数进行跨头文件的维护。

小结:

记住应该用non-member non-friend函数替换member函数,这样做可以增加封装性,包裹弹性以及机能扩充性质。

时间: 2024-10-22 15:36:54

条款23:宁以non-member, non-friend,替换member函数。的相关文章

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

(一) 有个class来表示网页浏览器: class WebBrowser { public: void clearChache(); void clearHistory(); void removeCookies(); }; 许多用户会想一整个执行所有这些动作,因此WebBrowser也提供这样一个函数:clearEverything class WebBrowser { public: void clearChache(); void clearHistory(); void removeC

《Effective C++》学习笔记——条款23

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 四.Designs and Declarations Rule 23:Prefer non-member non-friend fuctions to member functions 规则 23:宁以  non-member . non-friend 替换 m

effective c++ 条款23 perfer nonmember nonfreind function to member function

主要的理由还是封装.nonmember nonfreind function 不能访问类private 成员变量. 这个场景是有一个类提供了一些基本功能,比如 class WebBrowser { public: void clearCache(); void clearHistory(); void removeCookies(); }; 有时候我们需要执行上述三个函数.我们的做法是 void clearBrowser(WebBrowerser &wb) { wb.clearCache();

Effective C++ (笔记) : 条款18 -- 条款23

条款18:让接口容易被正确使用,不易被误用 在(参数)类型上客户不知道怎么使用的时候,可以导入简单的"外覆"类型来区别参数.也就是,自定义数据类型,使客户明确调用相关的类型,防止误用. 尽量让自定义类型的行为和内置类型的行为相同,因为客户会想当然的和使用内置类型一样使用自定义类型,这也就是上面说的让接口容易被正确的使用.STL容器的接口十分一致,这也是他们非常容易使用的一个原因. 任何接口如果要求客户必须记得做某些事情,那么就有着"不正确的使用"的倾向,因为客户可能

条款23: 必须返回一个对象时不要试图返回一个引用

class rational { public: rational(int numerator = 0, int denominator = 1); ... private: int n, d; // 分子和分母 friend const rational // 参见条款21:为什么 operator*(const rational& lhs, // 返回值是const const rational& rhs) }; inline const rational operator*(cons

《Effective C 》资源管理:条款25--考虑写出一个不抛出异常的swap函数

条款25考虑写出一个不抛出异常的swap函数 条款25:考虑写出一个不抛出异常的swap函数 swap是STL中的标准函数,用于交换两个对象的数值.后来swap成为异常安全编程(exception-safe programming,条款29)的脊柱,也是实现自我赋值(条款11)的一个常见机制.swap的实现如下: namespace std{ template<typename T> void swap(T& a, T& b) { T temp(a); a=b; b=temp;

Effective C++ 条款25 考虑写出一个不抛出异常的swap函数

1. swap是STL的一部分,后来成为异常安全性编程(exception-safe programming)(见条款29)的一个重要脊柱,标准库的swap函数模板定义类似以下: namespace std{ template<typename T> swap(T& lhs,T& rhs){ T temp(lhs); lhs=rhs; rhs=temp; } } 只要T类型支持拷贝构造以及拷贝赋值,标准库swap函数就会调用T的拷贝构造函数和拷贝构造操作符完成值的转换,但对于某

Effetive C++_笔记_条款06_若不想使用编译器自动生成的函数,就该明确拒绝

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 通常如果你不希望class支持某一特定机能,只要不声明对应函数就是了.但这个策略对copy构造函数和copy assignment操作符却不起作用,你如果不声明它们,而某些人尝试调用它,编译器会为你声明它们. 这把你逼到了一个困境.如果你不声明copy构造函数和copy assignment操作符,编译器可能为你产出一份,于是你的clas支持copying.如果

Effective C++:条款36:绝不重新定义继承而来的non-virtual函数

(一)首先有下面的继承体系: class B { public: void mf(); ... }; class D : public B {...}; D x; 以下行为: B* pB = &x; pB->mf(); 异于以下行为: D* pD = &x; pD->mf(); 上面两种行为产生的结果不一定相同.看下面这种情况: mf是个non-virtual函数而D定义有自己的mf版本: class D : public B { public: void mf(); ...