条款25(一):考虑写出一个不抛异常的swap函数

127 篇文章 7 订阅
39 篇文章 3 订阅

条款25:考虑写出一个不抛异常的swap函数

Consider support for a non-throwing swap.
本章作为设计与声明最后一章,内容较长,分为三部分。

swap

swap是一个有趣的函数。
原本它只是STL的一部分,而后则成为异常安全性编程(exception-safe programming)的主体,以及后来用于处理自我赋值可能性(条款11)的一个常见机制。因此,swap的实现是非常重要的。

swap的缺省实现

所谓的swap(置换)两对象的值,指的就是将两对象的值彼此赋予对方。在默认的情况之下,swap动作可以由STL提供的swap算法来实现:

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

只要类型T支持copying(通过copy构造函数和copy assignment操作符来完成),缺省的swap实现代码就会自动置换类型为T的对象,我们并不需要额外的工作。

这种缺省的实现比较简单,涉及到了三个对象的复制:

  • a复制到temp
  • b复制到a
  • temp复制到b。

但是对于某些类型而言,这些复制动作并没有必要!

其中最主要的即“以指针指向一个对象,内含真正数据”的类型。
这种类型最常见的表现形式就是“pimpl手法”(pointer to implementation)
如果以这种手法设计Widget class:

class WidgetImpl {
public:
    ...
private:
    int a, b, c;      //可能有许多数据,意味着复制时间很长
    std::vector<double> v;
    ...
};

class Widget {          //该class使用pimpl手法
public:
    Widget(const Widget& rhs);     //复制Widget时,令它复制其WidgetImpl对象
    Widget& operator=(const Widget& rhs)   //operator=的实现见条款10~12
    {
        ...
        *pImpl = *(rhs.pImpl);
        ...
    }
    ...
private:
    WidgetImpl* pImpl;    //指针,所指的对象就是内含Widget数据
};

一旦我们需要置换两个Widget对象的值,我们唯一需要做的就是置换其pImpl指针而已。
但是,缺省的swap并不知道这一点!它不仅会复制三个Widgets,还会复制三个WidgetImpl对象!效率一下子就变得很低了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值