C++ swap函数(effective C++ 条款25)
来源:互联网 发布:双色球红球246算法 编辑:程序博客网 时间:2024/06/05 01:13
标准库swap函数
我们首先看一下标准库的swap函数是如何实现的,它是一个定义在std命名空间的函数模板:
namespace std { template<typename T> void swap(T &a,T &b) { T temp(a); a = b; b = temp; }}
可以看到,标准库的swap实现调用了拷贝构造函数(对于非内置类型),并且有两次的赋值运算,这在很多情况下是不满足我们的效率需求的(大型对象的拷贝是毫无必要的操作,我们仅需要交换指针,若存在容器类型,调用容器类的swap明显是更加正确的操作)。在C++11中,我们有如下的优化:
template<typename T>void swap(T& a,T&b) { T temp(std::move(a)); a = std::move(b); b = std::move(temp);}
移动方式的本质就是移交临时对象对资源的控制权,通常就是指针的替换,因此上述操作对存在移动构造和移动赋值运算的类来讲,已经可以基本满足要求,但是,对于未定义上述操作的类来讲,改进版本的swap操作并未有任何效率上的提升,因此,有必要定义类类型的swap。
copy and swap中的 swap操作
前一篇文章中关于copy and swap操作中提到了swap操作,作为成员函数的swap交换了两者指针:
class A {private:int *a;public:void swap(A& rhs) { using std::swap; swap(this->a,rhs.a);// 我们简单地交换了指针}};
我们稍后将解释关于using std::swap为何是必要的。
上述操作并没有解决问题,我们希望能够像调用普通swap函数操作一样调用swap(A &a,A&b),因此,我们下一步的操作就是在std命名空间内特化swap版本:
namespace std { template<> void swap<A>(A&a,A&b) { a.swap(b); }}
在std空间内的特化版本满足C++标准的规定,这种扩充操作使得我们的特化版本对包含了std空间的文件都处于可见状态,因此,我们可以像以前一样使用swap进行交换:
using std::swap;A a,b;swap(a,b);
我们知道,C++允许对类模板全特化,但是对函数模板不允许全特化:
template<typename T>// 以下定义不允许!void swap<A<T>> (A<T>& a,A<T>& b) { a.swap(b); }
同样的,std内对swap的重载也不符合规定,我们的解决方案就是,在自定义的命名空间内定义swap函数:
namespace Astuff { template<typename T> class A { ... ... }; template<typename T> void swap(A<T>&a,A<T> &b) { a.swap(b); }};
这样,我们在当前的命名空间内就拥有了swap的完整定义,那么为什么在使用时要加using std::swap呢?这句声明会使std命名空间的swap暴露出来,编译器会自动在当前命名空间和std空间内寻找最符合当前函数调用的swap版本,因此,以下的写法完全错误:
A a,b;std::swap(a,b);
这种写法直接调用了std空间内的swap函数,因此并不符合大多数情况下的需求,using版本才是最准确的版本:
using std::swap;swap(a,b);
- 《Effective C++》学习笔记条款25 考虑写出一个不抛异常的swap函数
- Effective C++——》条款25:考虑写一个不抛出异常的swap函数
- Effective C++:条款25:考虑写出一个不抛异常的swap函数
- Effective c++(第三版) 条款25:考虑写出一个不抛出异常的swap函数
- 《Effective C ++ 》资源管理:条款25--考虑写出一个不抛出异常的swap函数
- 读书笔记《Effective C++》条款25:考虑写出一个不抛异常的swap函数
- 《Effective C++》条款25:考虑写出一个不抛异常的swap函数
- C++ swap函数(effective C++ 条款25)
- Effective C++(条款18-25)
- [Effective C++]条款14: 确定基类有虚析构函数
- effective C++ 条款25 swap
- 《Effective C++》构造/析构/赋值 函数:条款5-条款9
- 《Effective C++》构造/析构/赋值 函数:条款10-条款12
- Effective C++:条款01
- Effective C++:条款02
- Effective C++:条款03
- Effective C++:条款04
- Effective C++:条款05
- 测试人员掌握代码的重要性
- 抓取搜狗微信百度新闻网易新闻
- EF Core DBFirst
- request.getParameter()和request.getInputStream()与request.getReader()
- POJ2758 斐波那契数列 0ms
- C++ swap函数(effective C++ 条款25)
- Oracle 11g Data Guard Redo应用服务
- andriod入门学习(一)--新建项目及简单控件拖拽生成
- 占楼
- 使用swiper做的小案例
- 转义序列和反转义(&#x)
- 快速排序
- DEEP LEARNING第五章
- Servlet(cookie的生存时间与请求路径)