右值引用(Rvalue)
可以大幅改善容器的性能
当对象内部含有指针时,可以使用右值来窃取对象
原理
当右边的对象是一个右值时,左侧的对象可以偷取右侧对象的资源
1 2 3 4
   |  int x=foo() int* p=&foo() foo()=7;
 
  | 
 
右值引用(Rvalue)
可以大幅改善容器的性能
原理
当右边的对象是一个右值时,左侧的对象可以偷取右侧对象的资源
1 2 3 4
   |  int x=foo() int* p=&foo() foo()=7;
 
  | 
 
cpp 11后我们认为右值的对象时可以被窃取资源的
为此我们需要:
- 必须有语法让我们在调用端诉编译器,这是个Rvalue
 
- 必须有语法放我们在被调用段写出一个专门处理Rvalue的所谓move assignment函数
 
code
1 2 3 4 5 6 7 8 9 10 11 12 13
   | class MyString{     private:         char* _data;     public:          MyString(const Mystring& str):initialization list{
      }          Mystring(MyString&& str)noexcept:initialization list{         ...     } }
  | 
 
G2.9
1 2 3 4 5 6 7 8 9 10 11
   | iterator insert(iterator posistion,const T&x){     size_type n=posistion-begin();     if(finish !=end_of_storge && position ==end()){         construct(finish,x);         ++finish;     }else{         insert_aux(position,x);     }     return begin()+n; }
 
  | 
 
G4.9
1 2 3 4 5 6 7
   | iterator insert(const_iterator __position,const value_type& __x);
  iterator instert(const_iterator __position,value_type&& __x){     return emplace(__position,std::move(__x)) }
   | 
 
旧版问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | void process(int& i){     cout<<"process(int &i):"<<i<<endl; }
  void process(int&& i){     cout<<"process(int&&):"<<i<<endl; }
  void forward(int&& i){     out<<"forward(int&&):"<<i<<endl;     process(i);     } int a=0; forward(2); forward(move(a));
 
  | 
 
改进版本
标准库提供的完美的传递过去
1 2 3 4 5 6
   |  template <typename T1,typename T2> void functionA(T1&& t1,T2&& t2){     funtionB(std::forward<T1>(t1),              std::forward<T2>(t2)) }
 
  | 
 
使用时要实现一下功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | private:     char* _data; public:
  MyString(const Mystring& str):initialization list{
  }
  Mystring(MyString&& str)noexcept:initialization list{     ... }
  MyString& operator=(const MyString& str){
      return *this; }
 
  Mystring& operator=(MyString&& str){     noexcpt{         return *this;     } }
   | 
 
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
   | class MyString{     public:              static size_t DCtor;         static size_t Ctor;         static size_t CCtor;         static size_t CAsgn;         static size_t MCtor;         static size_t MAsgn;         static size_t Dtor;     private:         char* _data;         size_t _len;         void _init_data(const char*s){             _data = new char[_len+1];             memcpy(_data,s,_len);             _data[_len]='\0';         }     public:                  MyString():_data(NULL),_len(0){++DCtor;}                  MyString(const char* p):_len(strlen(p)){             ++Ctor;             _init_data(p);         }
                   MyString(const Mystring& str):_len(str._len){             ++CCtor;             _init_data(str._data);         }                  MyString(Mystring& str)noexcept:_data(str._data),_len(str._len){             ++MCtor;             str._len=0;             str._data=NULL;         }
                   MyString& operator=(const MyString& str){             ++CAsgn;             if(this != &str){                 if(_data) delete _data;                  _len=str._len;                 _init_data(str._data);             }else{
              }         return *this;         }
                   MyString& operator=(MyString&& str) noexcept{             if(this !=& str){                 if(_data) delete _data;                 _len = str._len;                 _data=str._data;                 str._len=0;                 str._data=NULL             }         }                           virtual ~MyString(){             ++Dtor;             if(_data){                 delete _data;             }         }
                   bool         operator<(const MyString& rhs)const {             return string(this._data)<string(rhs._data);                      }
          bool         operator=(const MyString& rhs)const{             return string(this._data)=string(rhs._data);                      }
          char* get()const{return _data;} };
  | 
 
对于性能的影响
- vector
- 插入元素,影响巨大,是否实现移动构造
 
- 容器拷贝,影响巨大,需要使用std::move()
 
- 容器交换,影响巨大,需要使用std::move()
 
 
- deque 
- 插入元素,影响不大 (不一定,和元素的位置相关)
 
- 容器拷贝,影响巨大,需要使用std::move()
 
- 容器交换,影响巨大,需要使用std::move()
 
 
- list 链表
- 插入元素,影响不大
 
- 容器拷贝,影响巨大,需要使用std::move()
 
- 容器交换,影响巨大,需要使用std::move()
 
 
- multiset(红黑树)
- 插入元素,影响不大
 
- 容器拷贝,影响巨大,需要使用std::move()
 
- 容器交换,影响巨大,需要使用std::move()
 
 
- unordered_multiset(hash_table)
- 插入元素, 差别不大
 
- 容器拷贝,影响巨大,需要使用std::move()
 
- 容器交换,影响巨大,需要使用std::move()
 
 
原理
- 容器拷贝
- 如果使用拷贝构造,会进行内存的分配,并且拷贝每一个内容
 
- 如果使用移动构造,只更改对应的容器的指针。//常量的时间