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

1. 面向对象的真实意义并非是数据以及操作数据的函数应该被捆绑在一起,而是要求数据应该尽可能地被封装.封装意味着数据的不可见,越多的东西被封装,用户对其直接的接触就越少,用户代码和被封装内容的编译相关度就越低,"包裹弹性"就越高,也就是说,封装性越好,对代码的更改所造成的影响就越低.

2. non-member-non-friend函数实际上比public-member和friend函数要高,因为前者无法访问类的private对象,而后者可以访问类的任何对象,这显然降低了数据的封装性(当然,出于封装性的考虑让函数成为类的non-member并不意味着它不可以是其他类的member).

3. 如果non-member函数之间并没有编译相依关系,那么可以通过把它们声明在同一命名空间不同头文件的方式把它们分离开来.将函数放在多个头文件但隶属于同一命名空间可以使客户轻松地扩展这一组函数,只需要添加更多non-member-non-friend到同一命名空间即可.但member函数却不可以,因为类必须整体定义而不能分割为片片段段,因此就"机能扩充性而言",non-member-non-friend函数同样由于member函数.

时间: 2024-12-10 09:38:11

Effective C++ 条款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 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++ 条款六 若不想使用编译器自动生成的函数,就该明确拒绝

class HomeForSale //防止别人拷贝方法一:将相应的成员函数声明为private并且不予实现 { public: private: HomeForSale(const HomeForSale&); HomeForSale& operator = (const HomeForSale&);//只有申明,此函数很少被使用   };   //方法二,设计一个专门用来阻止copying动作的基类,然后让其他类继承这个类即可   class Uncopyable { prot

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的拷贝构造函数和拷贝构造操作符完成值的转换,但对于某

Effective C++ 条款23

宁non-member.non-friend顶替member性能 本节介绍笔者为什么时间来实现某些功能.择非成员函数而且是非友元函数.这样做总结一句话,就是最大限度的实现类的封装性. 封装意味着不可见. 愈多东西被封装.欲少人能够看到它,我们就有愈大的弹性去改变它.愈少代码能够看到数据(訪问数据),愈多数据可被封装,我们就更有自由来改变对象数据.愈多函数能够訪问它,数据的封装性就愈低. 我们知道在上一节声明private数据成员也是为了实现类的封装.可见封装对于一个健壮的类来说的重要性. 以上就

More Effective C++ 条款23 考虑使用其他程序库

1. "理想的程序库应该小,快速,威力强大,富有弹性,有扩展性,直观,可广泛运用,有良好支持,使用时没有束缚,而且没有'臭虫'".但实际上这种程序库是不可能实现的:要针对速度和大小做优化,往往要牺牲移植性;要有丰富的机能,结果可能不够直观......一个程序库往往要权衡各方面得失,采取折中的方法来实现. 2. 不同的程序库侧重点可能不一样,即使两个程序库机能类似,也可能有不同的性能表现. 考虑iostream和stdio程序库,stdio提供的I/O操作速度通常比iostream快,可

Effective C++ 条款50 了解new和delete的合理替换时机

1. 替换标准库提供的operator new或operator delete通常基于以下三个理由: 1). 用来检测运行上的错误.将"new 所得内存"delete掉却不幸失败会导致内存泄露,多次对同一块"new所得内存"施行delete会导致未定义行为,如果让operator new持有一串动态分配所得地址,而operator delete将地址从中移走,就可以很容易检测出上述错误;各式各样的变成错误会导致数据"overruns"(写入点在分

Effective C++ 条款46 需要类型转换时请为模板定义非成员函数

1. 条款24举出一个Rational的例子,来说明为什么只有non-member函数才有能力"在所有实参身上实施隐式类型转换".Rational的定义如下: class Rational{ public: Rational(int numerator=0,int denominator=1); int numerator()const; int denominator()const; private: int numerator; int denominator; }; operat

Effective C++ 条款6 若不想使用编译器自动生成的函数,就该明确拒绝

1. 某些类的含义决定了它们不具备某些功能,也就是说某些函数不能被创造出来以防被错误的使用(例如定义一个Book类,它含有一个表示ISBN的变量,这种情况下拷贝构造函数以及赋值操作符显然是没有意义的,因为任何两种书的ISBN都不同),但是编译器在类的创建者没有声明默认构造函数,拷贝构造函数,赋值操作符和析构函数的情况下会产生这些函数,为了避免这种情况,可以将这些函数声明为private并且不提供它们的定义来阻止它们的使用,但是如果这些函数经由其他成员函数或者友元函数调用,错误将会在链接期才能被发