namespace std { template<class T> void swap(T&a,T&b) { T temp(a); a=b; b=temp; } } //T支持copying函数即可。 //pimpl手法:以指针指向一个对象,内含真正数据。 //在namespace std中只能全特化,不能偏特化, //如 namspace std { template<> void swap<A>(A&a,A&b) { ..... } } 接口:用户和代码的互动。
客户端错误可以导入新类型而防止用户错误。
接下来是Date的实例,面对导入新类型。
对于数据范围,我们做了进一步的编程。更改如下:
尽量让自定义类型的行为与内置类型一致。
勤快的使用shared_ptr,因为他能防止客户犯下资源泄漏的错误。
但是shared_ptr是原始指针的两倍大,但是额外成本不显著。
下面讲一下设计class的设计规范:
1.注意对象的创建和销毁过程。
2.搞清对象初始化和赋值的区别。
3.class 的pass-by-value的意义(调用copy函数)
4.注意此类是否是基类或不是。
5.需要什么类型转换。
6.谁该取用新type成员。
7.构造函数的explicit。
8.看看是否一般化。
在类中成员函数的参数传递时,多用pass-by-reference-const而不用pass-by-value
因为1.速度快。2.能够类型转换(继承)
适合pass-by-value的类型:1.内置。2.STL迭代器和函数对象。
对于返回对象的非成员函数,不能乱用reference。
成员变量设为private。
改变共有成员变量会破坏客户代码。
用non-member和non-friend替换member,因为更好的封装。
愈多函数可访问他,数据封装性就愈低。
用namespace将类与便利函数封装,可以更好的布局。而且namespace可以随时添加函数。
若所有参数需要转换类型,采用non-member。
swap()
一般来说要用swap可以在class里声明一个swap成员函数,这样可以在swap成员函数中调用stl中的swap函数。
然后再到std中写下特化版本。
C++只能对class偏特化,而不能对function偏特化。
如果想调用std中swap,可以用using std::swap,意思是先看特化版本,再看一般模板版本。
本来的swap不能满足要求的原因是因为class中的pimpl手法:
解决步骤:
1.先public swap成员函数。
2.在class所在的namespace中提供一个non-member swap
3.当你调用swap时确定包含using声明式。