【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为奇数时 ...
随机推荐
- XmlDocument类
XmlDocument类是.NET框架的DOC解析器.XmlDocument将XML视为树状结构,它装载XML文档,并在内存中构建该文档的树状结构.下面来看下XmlDocument提供了哪些功能. 一 ...
- 254 shades of grey
254 shades of grey Description: Why would we want to stop to only 50 shades of grey? Let's see to ho ...
- cisco vpn client for win10 x64 setup package
win10 x64安装cisco vpn client报错,解决方法如下: 1.卸载以前安装的所有cisco vpn client,并重启电脑. 2.运行winfix.exe 3.安装Global V ...
- uva11082 Matrix Decompressing
网络流 首先算出每行每列的数的和. 每行的值减去c,每列的值减去R 然后每行和每列之间连边,容量为19. 这样一来,(i,j)的流量相当于(i,j)的值-1. 这样就避免了流量为0不对应答案的尴尬情况 ...
- 如何从Linux源码获知版本信息
/*************************************************************************** * 如何从Linux源码获知版本信息 * 声明 ...
- Java [leetcode 19]Remove Nth Node From End of List
题目描述: Given a linked list, remove the nth node from the end of list and return its head. For example ...
- 设计模式:Observer(观察者)—— Guava EventBus
本文分为三个部分: Observer(观察者) Guava EventBus详解 Guava EventBus使用示例 1. Observer(观察者) 1.1 背景 我们设计系统时, ...
- Ext入门学习系列(五)表格控件(3)
上节学习了Ext中如何绑定服务器端传递的数据.分别用asp.net和asp.net MVC.PHP.XML为例.本节主要介绍绑定之后的分页功能. 一.Ext的表格控件如何绑定? 分页是Ext自带的一个 ...
- error MSB3027: Could not copy "xxx.dll" to "xxx.dll". Exceeded retry count of 10. Failed.
错误提示内容: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3363,5): error MSB302 ...
- 自动脚本工具新版 v2.0
自动脚本工具 下载 下载工具后,解压,直接双击 "execute.bat" 文件后(前提已配置好 jdk 1.7 的环境),会生成文件夹 "output",该文 ...