码迷,mamicode.com
首页 > 编程语言 > 详细

Effective C++ 条款25

时间:2015-06-27 21:30:09      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

考虑写出一个不抛出异常的swap函数

本节讲解如何自定义一个高效的swap函数

对于std名空间中的swap缺省函数如下所示

namespace std{
    template<typename T>
    void swap(T& a, T& b)
    {
        T temp(a);
        a=b;
        b=temp;
    }
}

class WidgetImpl{
public:
    ……
private:
    int a,b,c;              //数据很多,复制意味时间很长
    std::vector<double> b;
    ……
};

我们可以看到,当交换对象的数据很大时,以上swap的执行效率会很慢,为了改变这种状况,作者提出以下方法;

重新定义一个类

class Widget{
public:
    Widget(const Widget& rhs);
    Widget& operator=(const Widget& rhs
    {
        ……          //复制Widget时,复制WidgetImpl对象              
        *pImpl=*(ths.pImpl);
        ……
    }
    ……
private:
    WidgetImpl* pImpl;//指针,含有Widget的数据
};

如果置换两个Widget对象值,只需要置换其pImpl指针,那么效率就会很高。
那么怎样定义swap呢?
如下:

calss Widget{
public:
    ……
    void swap(Widget& other)
    {
        using std::swap;//这个声明有必要
        swap(pImpl, other.pImpl);
    }
    ……
};
namespace std{
    template<> //修订后的swap版本
    void swap<Widget>(Widget& a, Widget& b)
    {
        a.swap(b);  //调用其成员函数
    }
}

Widget w1,w2;

swap(w1,w2);//调用名空间的全特化Widget版本的swap.

从上面的代码我们可以看出完成了我们的目的,实现两个WidgetImpl对象交换,只交换他们的指针。当然这里需要构造出一个交换类Widget,需要全特化Widget 类型的swap,需要在函数体内定义member函数swap。

那么,读者就迷茫了,绕了一大圈,怎么不直接调用成员函数swap,这是因为当你用swap(a,b)语句时,它会拥有自动合适匹配的功能。更适合客户使用,实现接口的一致性和简易性。

下面我们来介绍当两个类都是template,如何解决上面的问题?
如下:

template<typename T>
class WidgetImpl{……};
template<typename T>
class Widget{……};

我们可以重新命名一个名空间如下:

namespace WidgetStuff{
   ……//模板化的WidgetImpl等
   template<typename T>//内含swap函数
   class Widget{……};
   ……
   template<typename T>
   void swap(Widget<T>& a,//non-member,不属于std命名空间
             Widget<T>& b)
   {
       a.swap(b);
   }
}

Widget<int> w1,w2;

swap(w1,w2);//调用名空间WidgetStuff的Widget<int>版本的swap.

版权声明:本文为博主原创文章,未经博主允许不得转载。

Effective C++ 条款25

标签:

原文地址:http://blog.csdn.net/u011058765/article/details/46663827

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!