1、swap交换对象值,std提供了实现方法模版的实现,它的实现是交换对象值。

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

2、考虑下面的情况下,资源管理类Widget,内部只有一个指针WidgetImpl,该指针指向一个对象,这个对象中包含真正数据。对这种资源管理类执行swap,如果调用std中的swap,有哪些动作?对于Widget,copy构造一次,copy赋值两次,同时对于WidgetImpl,copy构造一次,copy赋值两次。我们知道,对于这种情况,只需要交换WidgetImpl就可以了。因此,std中的swap不能满足需求。

3、怎么解决呢?

  std中的swap是个模版方法,不能满足需求,因此我们要全特化一个方法。在方法中,交换WidgetImpl。因为,WidgetImpl是private,不能在外部访问。我们可以在Widget中访问,让Widget暴露一个成员方法,让全特化的swap调用成员方法。

 class Widget
{
public:
void swap(Widget& rhs)
{
using namespace std::swap;
swap(this->_widgetImpl,rhs._widgetImpl);
}
}; namespace WidgetStuff
{
template<>
void swap<Widget>(Widget& a,Widget& b)
{
a.swap(b);
}
}

注意:可以全特化std中的东西,但是不要在std中添加东西,因此全特化的方法,放在WidgetStuff命名空间内。

4、全特化方法是模版方法的一个特例,从范围角度看,模版方法>全特化方法,那么问题来,对于Widget的交换方法swap,模版方法和全特化方法都满足,那么是调用全特化方法,还是使用模版方法实例化一个呢?

  对于C++的名称查找法则,可以这样认为,先在小范围里找,小范围里没有,再到大范围找。

5、目前C++只允许对类模版偏特化(指定部分模版形参),不允许对方法模版偏特化,但是可以重载。

6、假如在模版方法中调用swap呢?

  根据上面的查找规则,先在小范围里找,小范围里找不到,再到大范围里找,但是这里要暴露大范围里的swap,使用using std::swap;

7、为了异常安全性,成员方法swap绝不抛出异常。非成员方法swap允许抛出异常,因为copy构造和copy赋值都可能导致异常。

【25】考虑写出一个不抛异常的swap函数的更多相关文章

  1. EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数

    记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于cla ...

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

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛 ...

  3. Effective C++:条款25:考虑写出一个不抛异常的swap函数

    (一) 缺省情况下swap动作可由标准程序库提供的swap算法完毕: namespace std { template<typename T> void swap(T& a, T& ...

  4. [Effective C++ --025]考虑写出一个不抛异常的swap函数

    引言 在我的上一篇博客中,讲述了swap函数. 原本swap只是STL的一部分,而后成为异常安全性编程的脊柱,以及用来处理自我赋值可能性. 一.swap函数 标准库的swap函数如下: namespa ...

  5. 《Effective C++》item25:考虑写出一个不抛异常的swap函数

    std::swap()是个很有用的函数,它可以用来交换两个变量的值,包括用户自定义的类型,只要类型支持copying操作,尤其是在STL中使用的很多,例如: int main(int argc, _T ...

  6. Effective C++ -----条款25:考虑写出一个不抛异常的swap函数

    当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常. 如果你提供一个member swap,也该提供一个non-member swap用来调用前者.对于cla ...

  7. 考虑实现一个不抛异常的swap

    Effective C++:参考自harttle land 类的swap实现与STL容器是一致的:提供swap成员函数, 并特化std::swap来调用那个成员函数. class Widget { p ...

  8. 不抛异常的swap函数

    namespace AStuff{ template<typename T> class A { public: void swap(A *other) { using std::swap ...

  9. 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数

    题目: 输入一个数字n  如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数  写出一个函数 首先,这道题肯定可以用动态规划来解, n为整数时,n的解为 n/2 的解加1 n为奇数时 ...

随机推荐

  1. virtualbox怎么装系统OVA虚拟包大全一键安装

    1 第一步,下载ova虚拟包 http://pan.baidu.com/s/1hqxWkUo . 里面有win7.ubuntu.kali,你自己挑一个需要的 全都可以自动缩放屏幕,有VirtualBo ...

  2. css揭秘之按钮的实现技巧

    <html> <title>css</title> <style> button{ padding: .3em .8em; border: 1px so ...

  3. poj 3087 Shuffle'm Up ( map 模拟 )

    题目:http://poj.org/problem?id=3087 题意:已知两堆牌s1和s2的初始状态, 其牌数均为c,按给定规则能将他们相互交叉组合成一堆牌s12,再将s12的最底下的c块牌归为s ...

  4. poj 2251 Dungeon Master( bfs )

    题目:http://poj.org/problem?id=2251 简单三维 bfs不解释, 1A,     上代码 #include <iostream> #include<cst ...

  5. poj1823,3667

    又来练线段树了…… poj1823题意很简单(明显的数据结构题),区间修改和统计最长连续空区间: 有了poj3468的基础,区间修改不是什么问题了,重点是求最长连续空区间:(弱弱的我纠结了好久) 在每 ...

  6. 使用Unity3d的Physics.Raycast()的用法做子弹射击

    Class Functions 1)static function Raycast (origin : Vector3, direction : Vector3, distance : float = ...

  7. Sharepoint网站创建自定义导航全记录

    转:http://tech.it168.com/a2009/1207/820/000000820524_all.shtml [IT168 技术文档]在一个Sharepoint网站中可以创建子网站,页面 ...

  8. 实体框架Entity Framework 4.1快速入门

    介 绍 在旧的Entity 框架中,开发者可以从已存在的数据库中产生业务实体的模型,这种开发方法被称为数据库驱动的开发方法.而在4.1的Entity Framework中,支开发者先创建实体业务类,然 ...

  9. JSP文件上传代码

    一.首先建立一个上传的界面,取名为a.jsp,代码如下 <%@ page contentType="text/html; charset=utf-8" language=&q ...

  10. Java Web程序工作原理

    Web开发的最重要的基本功能是HTTP:Java Web开发的最重要的基本功是Servlet Specification.HTTP和Servlet Specitication对于Web Server和 ...