本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
经验:当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常
示例:namespace std{ template<typename T> void swap(T &a, T &b){ T temp(a); a = b; b = temp; } } //“pimpl手法”(pointer to implementation) --> 文件间的编译依存度 class WidgetImpl{ public: //... private: int a, b, c; std::vector<double> v; //... } class Widget{ public: Widget(const Widget &rhs); Widget &operator=(const Widget &rhs){ //返回的为什么是引用?--> 就应该是引用,参见Item10令operator=返回一个reference to *this。 //这里和Item28不一样,那里说的是不要返回handler指向对象 内部 成分。 //... *pImpl = *(rhs.pImpl); //... } //... private: WidgetImpl *pImpl; }
namespace std{ //这是std::swap针对“T是Widget”的特化版本。目前还不能通过编译 template<> void swap<Widget>(Widget &a, Widget &b){ swap(a.pImpl, b.pImpl); } }
namespace WidgetStuff{ class Widget{ //能正常编译,且与STL容器有一致性。因为所有STL容器也都提供有public swap成员函数和std::swap特化版本 public: //... void swap(Widget &other){ //调用swap时应针对std::swap使用using声明式,然后调用swap并且不带任何“命名空间资格修饰” using std::swap; swap(pImpl, other.pImpl); } //... }; void swap(Widget &a, Widget &b){ //non-member swap 函数;这里并不属于std命名空间 a.swap(b); } } namespace std{ template<> void swap<Widget>(Widget &a, Widget &b){ a.swap(b); } }
template<typename T> class WidgetImpl{ //... } template<typename T> class Widget{ //... } namespace std{ //错误,不合法 --> function template只能全特化,不能偏特化 template<typename T> void swap<Widget<T> >(Widget<T> &a, Widget<T> &b){ a.swap(b); } } namespace std{ template<typename T> //std::swap的一个重载版本,不合法 --> std不允许添加新的的templates void swap(Widget<T> &a, Widget<T> &b){ a.swap(b); } }