【25】考虑写出一个不抛异常的swap函数
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函数的更多相关文章
- EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数
记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于cla ...
- Effective C++ Item 25 考虑写出一个不抛异常的swap函数
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛 ...
- Effective C++:条款25:考虑写出一个不抛异常的swap函数
(一) 缺省情况下swap动作可由标准程序库提供的swap算法完毕: namespace std { template<typename T> void swap(T& a, T& ...
- [Effective C++ --025]考虑写出一个不抛异常的swap函数
引言 在我的上一篇博客中,讲述了swap函数. 原本swap只是STL的一部分,而后成为异常安全性编程的脊柱,以及用来处理自我赋值可能性. 一.swap函数 标准库的swap函数如下: namespa ...
- 《Effective C++》item25:考虑写出一个不抛异常的swap函数
std::swap()是个很有用的函数,它可以用来交换两个变量的值,包括用户自定义的类型,只要类型支持copying操作,尤其是在STL中使用的很多,例如: int main(int argc, _T ...
- Effective C++ -----条款25:考虑写出一个不抛异常的swap函数
当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常. 如果你提供一个member swap,也该提供一个non-member swap用来调用前者.对于cla ...
- 考虑实现一个不抛异常的swap
Effective C++:参考自harttle land 类的swap实现与STL容器是一致的:提供swap成员函数, 并特化std::swap来调用那个成员函数. class Widget { p ...
- 不抛异常的swap函数
namespace AStuff{ template<typename T> class A { public: void swap(A *other) { using std::swap ...
- 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数
题目: 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数 首先,这道题肯定可以用动态规划来解, n为整数时,n的解为 n/2 的解加1 n为奇数时 ...
随机推荐
- 在运行时切换 WinForm 程序的界面语言 System.ComponentModel.ComponentResourceManager .ApplyResources
Download the code for this article: WinForm-Multilanguages-2.rar (11 KB). 方法二: 下面介绍一种只需对现有代码做较小改动的方法 ...
- Android开发之Service的写法以及与Activity的通信
Service的总结: 1.按运行地点分类: 类别 区别 优点 缺点 应用 本地服务(Local) 该服务依附在主进程上, 服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外 ...
- poj 3414 Pots ( bfs )
题目:http://poj.org/problem?id=3414 题意:给出了两个瓶子的容量A,B, 以及一个目标水量C, 对A.B可以有如下操作: FILL(i) fill the ...
- [C#] 我的log4net使用手册
1. log4net简介 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.Java平台下,它还 ...
- UVa 808 (建坐标系、找规律) Bee Breeding
题意: 如图,按照图中的规律给这些格子编号.给出两个格子的编号,求从一个格子到另一个格子的最少步数.(一步只能穿过有有公共边的格子) 分析: 根据高中数学知识,选任意两个不共线的向量,就能表示平面上所 ...
- 8.11-8.16:usaco
summary:57 bzoj1741:裸二分图最大匹配 #include<cstdio> #include<cstring> #include<iostream> ...
- xml 实现圆形图 和 椭圆形图
1. 效果图 2.圆形图 <ImageView android:layout_width="wrap_content" android:layout_height=" ...
- Android 隐藏RadoiButton左边按钮
声明方式 添加属性 android:button=“@null”? 代码方式 radioBtn.setButtonDrawable(new StateListDrawable());
- angularjs filter 详解
系统的学习了一下angularjs,发现angularjs的有些思想根php的模块smarty很像,例如数据绑定,filter.如果对smarty比较熟悉的话,学习angularjs会比较容易一点.这 ...
- vs2013 报错AccessViolationException 解决方案
最近 用vs2013 vs2010开发一个web 项目的时候 报AccessViolationException 异常 ,找不到原因 后边网上看了解决方法,试了一下 解决了,具体什么原因搞不清. 下 ...