原始版本:

  1. template<typename T>
  2. void swap(T& a, T& b)
  3. {
  4. T tmp(a);
  5. a = b;
  6. b = tmp;
  7. }

此版本不重视效率,当交换的两个对象比较大时,需要更高效的交换,因此应该提供1)public swap成员函数,让它高效的置换两个对象,并提供nono-member swap,调用之

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // FileName : swap_item25.h
  4. // Version : 0.10
  5. // Author : Ryan Han
  6. // Date : 2013/07/26 13:13:55
  7. // 2013/10/30 08:27:50
  8. // Comment :
  9. // ½«WidgetÉùÃ÷Ò»¸öswapµÄpublicº¯Êý×öÕæÕýµÄÖû»¹¤×÷£¬È»ºó½«std::swapÌØ»¯
  10. ///////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifndef _SWAP_ITEM25_H_
  13. #define _SWAP_ITEM25_H_
  14.  
  15. #include <iostream>
  16. using namespace std;
  17.  
  18. class WidgetImpl {
  19. public:
  20. WidgetImpl(int a = , int b = , int c = );
  21. /*WidgetImpl(int a = 1, int b = 2, int c = 3) : x(a), y(b), z(c){
  22. cout << "WidgetImpl constructor called." << endl;
  23. }*/
  24.  
  25. ~WidgetImpl(){
  26. cout << "WidgetImpl de-constructor called." << endl;
  27. }
  28.  
  29. void WidgetPrint(){
  30. cout << "x = " << x << " y = " << y << " z = "<< z << endl;
  31. }
  32. private:
  33. int x, y, z;
  34. };
  35.  
  36. class Widget {
  37. public:
  38. Widget(int a = , int b = , int c = ) : pImpl(new WidgetImpl(a, b, c)){
  39. cout << "Widget constructor called." << endl;
  40. ;
  41. }
  42.  
  43. ~Widget(){
  44. cout << "Widget de-constructor called." << endl;
  45. delete pImpl;
  46. }
  47.  
  48. Widget(const Widget& rhs) {
  49. pImpl = new WidgetImpl(*(rhs.pImpl));
  50. }
  51.  
  52. Widget& operator=(const Widget& rhs){
  53. *pImpl = *(rhs.pImpl);
  54. }
  55.  
  56. void WidgetPrint(){
  57. pImpl->WidgetPrint();
  58. //non friend class can't access private data
  59. //cout << (*pImpl).x << endl;
  60. }
  61.  
  62. //has to use because only member function could access private member pImpl
  63. void swap(Widget& other){
  64. using std::swap;
  65. swap(pImpl, other.pImpl);
  66. }
  67. private:
  68. WidgetImpl* pImpl;
  69. };
  70.  
  71. //inline to avoid duplicate definition
  72. //http://www.cnblogs.com/dracohan/p/3401660.html
  73. namespace std {
  74. template <>
  75. inline void swap<Widget>(Widget& a, Widget& b){
  76. cout << "specialized swap was called" << endl;
  77. a.swap(b);
  78. }
  79. }
  80.  
  81. #endif
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // FileName : swap_item25.cpp
  4. // Version : 0.10
  5. // Author : Ryan Han
  6. // Date : 2013/07/26 13:13:55
  7. // 2013/10/30 08:27:50
  8. // Comment :
  9. //
  10. ///////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "swap_item25.h"
  13. #include <iostream>
  14. using namespace std;
  15.  
  16. WidgetImpl::
  17. WidgetImpl(int a, int b, int c) : x(a), y(b), z(c){
  18. cout << "WidgetImpl constructor called." << endl;
  19. }
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // FileName : swap_item25.cpp
  4. // Version : 0.10
  5. // Author : Ryan Han
  6. // Date : 2013/07/26 13:13:55
  7. // 2013/10/30 08:27:50
  8. // Comment :
  9. //
  10. ///////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "swap_item25.h"
  13. #include <iostream>
  14. using namespace std;
  15.  
  16. int main()
  17. {
  18. Widget a;
  19. Widget b(,,);
  20.  
  21. a.WidgetPrint();
  22. b.WidgetPrint();
  23.  
  24. swap(a, b);
  25.  
  26. a.WidgetPrint();
  27. b.WidgetPrint();
  28.  
  29. int* pinta = new int();
  30. int* pintb = pinta;
  31.  
  32. cout << "*pinta is: " << *pinta << endl;
  33. cout << "*pintb is: " << *pintb << endl;
  34.  
  35. return ;
  36. }

C++-高效的swap的更多相关文章

  1. 【原创】C++之自定义高效的swap(1)

    1 问题背景     当交换两个包含了指针成员的类,我们最想看到的是直接交换其指针.但是当我们调用std::swap标准库这个模板函数时,通常它都会复制3个指针指向的对象作为交换所用,缺乏效率.如下: ...

  2. c++下为使用pimpl方法的类编写高效的swap函数

    swap函数是c++中一个常用的函数,用于交换两对象的值,此外还用于在重载赋值运算符中处理自赋值情况和进行异常安全性编程(见下篇),标准模板库中swap的典型实现如下: namespace stl { ...

  3. 读书笔记 effective c++ Item 25 实现一个不抛出异常的swap

    1. swap如此重要 Swap是一个非常有趣的函数,最初作为STL的一部分来介绍,它已然变成了异常安全编程的中流砥柱(Item 29),也是在拷贝中应对自我赋值的一种普通机制(Item 11).Sw ...

  4. 条款25:考虑写出一个不抛出异常的swap函数

    首先说下标准库的swap算法: namespace std{ template<typename T> void swap(T & a, T & b) { T tmp = ...

  5. swap() 函数实现的方法

    swap()函数总结: 一.利用临时变量 1.引用(交换任意类型) template <typename T> void swap(T& x,T& y) { T tmp; ...

  6. linux kernel 如何处理大小端

    暂时在用MPC8309,不太清楚大小端内核是什么时候给转的. 今天看了关于readl和writel具体实现的文章 今天就主要来分析下readl/writel如何实现高效的数据swap和寄存器读写.我们 ...

  7. linux kernel如何处理大端小端字节序

    (转)http://blog.csdn.net/skyflying2012/article/details/43771179 最近在做将kernel由小端处理器(arm)向大端处理器(ppc)的移植的 ...

  8. C++编码优化之减少冗余拷贝或赋值

    临时变量 目前遇到的一些产生临时变量的情况:函数实参.函数返回值.隐式类型转换.多余的拷贝 1. 函数实参 这点应该比较容易理解,函数参数,如果是实参传递的话,函数体里的修改并不会影响调用时传入的参数 ...

  9. C++ 11的移动语义

    目录 可拷贝和可移动的概念 移动构造函数和移动赋值函数 小结移动构造和移动赋值 std::move() 使用 std::move 实现一个高效的 swap 函数 Move and swap 技巧 参考 ...

随机推荐

  1. Android入门:绑定本地服务

    一.绑定服务介绍   前面文章中讲过一般的通过startService开启的服务,当访问者关闭时,服务仍然存在: 但是如果存在这样一种情况:访问者需要与服务进行通信,则我们需要将访问者与服务进行绑定: ...

  2. 【Oracle 数据迁移】环境oracle 11gR2,exp无法导出空表的表结构【转载】

    今天做数据迁移,但是发现有些空表无法exp,后来找到问题所在. [原文]:http://www.cnblogs.com/wenlong/p/3684230.html 11GR2中有个新特性,当表无数据 ...

  3. hadoop 入门实例【转】

    原文链接:http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.html 1.数据去重  "数据去重"主要是为了掌握 ...

  4. 转:C++中Static作用和使用方法

    转自:http://blog.csdn.net/artechtor/article/details/2312766 1.什么是static?       static 是C++中很常用的修饰符,它被用 ...

  5. OpenGL的glTexCoord2f纹理坐标配置

    纹理坐标配置函数,先看定义: void glTexCoord2f (GLfloat s, GLfloat t); 1.glTexCoord2f()函数 有两个参数:GLfloat s, GLfloat ...

  6. 慢慢聊Linux AIO

    一.What:异步IO是什么? 1. 一句话总结 允许进程发起很多I/O操作,而不用阻塞或等待任何操作完成 2. 详细说说  一般来说,服务器端的I/O主要有两种情况:一是来自网络的I/O:二是对文件 ...

  7. Linux命令(2) - 查看目录和文件大小: du -sh

    [root@hadoop01 ~]# ll total 156 drwxr-xr-x. 18 root root 4096 Jan 5 05:05 apps -rw-r--r--. 1 root ro ...

  8. 项目开发中遇到的extjs常见问题

    事件触发机制 l 给某一个控件添加事件. obj.addEvents( {search : true }); l 给某一个事件添加处理函数 n 给一个对象或变量添加监听及对应得处理,可以在创建时,通过 ...

  9. C#实现文件下载

    1,Http 协议中有专门的指令来告知浏览器, 本次响应的是一个需要下载的文件. 格式如下:Content-Disposition: attachment;filename=filename.ext以 ...

  10. 如何在腾讯云上开发一款O2O书签?

    版权声明:本文由潘佳宇原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/187 来源:腾云阁 https://www.qclo ...