Effective C++ Item 25 考虑写出一个不抛异常的swap函数
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
经验:当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常
演示样例:
stl里的swap算法
namespace std{
template<typename T>
void swap(T &a, T &b){
T temp(a);
a = b;
b = temp;
}
} //“pimpl手法”(pointer to implementation) --> 文件间的编译依存度
class WidgetImpl{
public:
//...
private:
int a, b, c;
std::vector<double> v;
//...
} class Widget{
public:
Widget(const Widget &rhs);
Widget &operator=(const Widget &rhs){ //返回的为什么是引用?--> 就应该是引用,參见Item10令operator=返回一个reference to *this。
//这里和Item28不一样,那里说的是不要返回handler指向对象 内部 成分。 //...
*pImpl = *(rhs.pImpl);
//...
}
//...
private:
WidgetImpl *pImpl;
}
解析:一旦要转换两个Widget对象值,我们唯一须要做的就是转换其pImpl指针。但缺省的swap算法不知道这一点。它不仅仅复制三个Widgets,还复制三个WidgetImpl对象。
纠正:将std::swap针对Widget特化
通常我们不被同意改变std命名空间的不论什么东西。但能够为标准template制造特化版本号
namespace std{ //这是std::swap针对“T是Widget”的特化版本号。 眼下还不能通过编译
template<>
void swap<Widget>(Widget &a, Widget &b){
swap(a.pImpl, b.pImpl);
}
}
经验:假设你提供一个member swap。也该提供一个non-member swap用来调用前者。对于 classes(而非templates)。也请特化std::swap
演示样例:
namespace WidgetStuff{
class Widget{ //能正常编译,且与STL容器有一致性。 由于全部STL容器也都提供有public swap成员函数和std::swap特化版本号
public:
//...
void swap(Widget &other){ //调用swap时应针对std::swap使用using声明式。然后调用swap而且不带不论什么“命名空间资格修饰”
using std::swap;
swap(pImpl, other.pImpl);
} //...
};
void swap(Widget &a, Widget &b){ //non-member swap 函数。这里并不属于std命名空间
a.swap(b);
}
}
namespace std{
template<>
void swap<Widget>(Widget &a, Widget &b){
a.swap(b);
}
}
经验:为“用户定义类型”进行std templates全特化是好的。但千万不要尝试在std内增加某些对std而言全新的东西
演示样例:
template<typename T>
class WidgetImpl{
//...
}
template<typename T>
class Widget{
//...
} namespace std{ //错误,不合法 --> function template仅仅能全特化。不能偏特化
template<typename T>
void swap<Widget<T> >(Widget<T> &a, Widget<T> &b){
a.swap(b);
}
} namespace std{
template<typename T> //std::swap的一个重载版本号,不合法 --> std不同意加入新的的templates
void swap(Widget<T> &a, Widget<T> &b){
a.swap(b);
}
}
Effective C++ Item 25 考虑写出一个不抛异常的swap函数的更多相关文章
- EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数
记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于cla ...
- 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 ...
- 【25】考虑写出一个不抛异常的swap函数
1.swap交换对象值,std提供了实现方法模版的实现,它的实现是交换对象值. namespace std { template<typename T> void swap(T& ...
- 考虑实现一个不抛异常的swap
Effective C++:参考自harttle land 类的swap实现与STL容器是一致的:提供swap成员函数, 并特化std::swap来调用那个成员函数. class Widget { p ...
- 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数
题目: 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数 首先,这道题肯定可以用动态规划来解, n为整数时,n的解为 n/2 的解加1 n为奇数时 ...
- java————数组 简单写出一个管理系统
数组的特点 1, 数组是一块连续的空间,下标描述空间的位置. 2, 下标从0开始,最大下标为数组长度—1.(*.length-1) 3, 数组元素都是变量.(就是每个下标对应的内容).变量的类型 ...
随机推荐
- c#操作SQL的例子
>> 数据表复制 当表目标表存在时: insert into 目的数据库..表 select * from 源数据库..表 当目标表不存在时: select * into 目的数据库..表 ...
- $.getJSON无法对外部变量进行赋值的问题
如下,即可将d中的值赋给外部变量 //把ajax的异步设置成同步,防止$.getJSON无法对外部变量进行赋值,必须在$.getJson前面 $.ajaxSetup({async:false}); $ ...
- python中函数和生成器的运行原理
#!/usr/bin/env python # -*- coding:utf-8 -*- # author:love_cat # python的函数是如何工作的 # 比方说我们定义了两个函数 def ...
- windows下修改Mysql5.7.11初始密码的图文教程
参考:http://www.jb51.net/article/98481.htm [摘要:1.my-default.ini 更名my.ini 正在解压的目次上面复造my-default.ini一份更名 ...
- 【原创】SSIS-WMI 数据读取器任务:监控物理磁盘空间
1.背景 随着时间的推移,我们的DW会越来越大,也就意味着磁盘空间会越来越小,那如果哪一天留意不当,就会造成磁盘空间的不足而导致ETL失败,最终影响我们的系统的数据正确性和使用,更严重的有可能导致物理 ...
- Laravel 项目使用 Carbon 人性化显示文章发表时间
比如说有这样一个需求:一篇文章的发表时间: **距离现在时间** **显示格式** < 1小时 xx分钟前 1小时-24小时 xx小时前 1天-10天 xx天前 >10天 直接显示日期 针 ...
- 异步 JavaScript 之理解 macrotask 和 microtask(转)
这个知识点... https://blog.keifergu.me/2017/03/23/difference-between-javascript-macrotask-and-microtask/? ...
- java标识符与命名规则
标识符就是给变量.类或方法起的名字.可以用字母.下划线或美元符号开头,区分大小写,没有最大长度限制.(关键字除外) 关键字 访问控制 private protected public ...
- Python的程序结构[1] -> 方法/Method[1] -> 静态方法、类方法和属性方法
静态方法.类方法和属性方法 在 Python 中有三种常用的方法装饰器,可以使普通的类实例方法变成带有特殊功能的方法,分别是静态方法.类方法和属性方法. 静态方法 / Static Method 在 ...
- Web/JAVA 简单题目汇总
[Java标识符,变量.常量] 一.Java合法标识符命名规则 (1)区分字母大小写,标识符长度不限 (2) 英文,Unicode码双字节文字字符(日文,韩文,中文),数字,下划线,$(美元符号)均 ...