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


    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie


    经验:当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常

    演示样例:
    stl里的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; }


    解析:一旦要转换两个Widget对象值,我们唯一须要做的就是转换其pImpl指针。但缺省的swap算法不知道这一点。它不仅仅复制三个Widgets,还复制三个WidgetImpl对象。

    纠正:将std::swap针对Widget特化
    通常我们不被同意改变std命名空间的不论什么东西。但能够为标准template制造特化版本号
    namespace std{ //这是std::swap针对“T是Widget”的特化版本号。

    眼下还不能通过编译 template<> void swap<Widget>(Widget &a, Widget &b){ swap(a.pImpl, b.pImpl); } }


    经验:假设你提供一个member swap。也该提供一个non-member swap用来调用前者。对于 classes(而非templates)。也请特化std::swap

    演示样例:
    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); } }


    经验:为“用户定义类型”进行std templates全特化是好的。但千万不要尝试在std内增加某些对std而言全新的东西
    演示样例:
    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);
    	}
    }
    

  • 相关阅读:
    Java的几种常用设计模式
    面向切面编程AOP
    面向过程编程、面向对象编程
    Java基础之集合与泛型
    Spring mvc中自定义拦截器
    Hibernate框架hibernate.cfg.xml配置文件,配置自动生成表结构策略。
    Notepad++打开xml文件显示crlf的问题
    java框架
    潜龙博客地址
    联通
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7264353.html
Copyright © 2020-2023  润新知