C++ 右值引用

http://www.cnblogs.com/soaliap/archive/2012/11/19/2777131.html

主要是两个问题

返回优化

vector<SpecialClass>&& func()
{              …

                return std::move(vect); //move,取得一个左值的右值
}

复制省略

在类里实现转移构造函数


一:第一个具有const引用的函数,可以接受任意的参数,不管是左值还是右值,不管这个左值或者右值易变或者不易变(if mutable);但是对于第二个函数,除了mutable rvalue-references类型,其他的类型都可以。

二:先从例子入手

printReference (constString& str)
{
        cout << str;
}
 
printReference (String&& str)
{
        cout << str;
}

第一个具有const引用的函数,可以接受任意的参数,不管是左值还是右值,不管这个左值或者右值易变或者不易变(if mutable);但是对于第二个函数,除了mutable rvalue-references类型,其他的类型都可以


move构造和move赋值操作符
右值引用的一个用处是可以用来创建move构造函数和move赋值操作符,move构造和move赋值可以避免内存重新分配,因为我们已经有了一个临时变量了。
把一个对象中的一个字段移动到另一个对象是什么意思?如果是一个原生类型,比如int,我们赋值就可以了,但是对于指针类型的处理比较有趣。我们不需要再分配和初始化一段内存,我们只需要把临时对象中的指针偷过来,然后让原始指针指向null即可,因为临时对象不再需要了,所以我们可以把它的指针拿过来用:
来看拷贝构造:
  1. class ArrayWrapper  
  2. {  
  3.     public:  
  4.         ArrayWrapper (int n)  
  5.             : _p_vals( new int[ n ] )  
  6.             , _size( n )  
  7.         {}  
  8.         // copy constructor  
  9.         ArrayWrapper (const ArrayWrapper& other)  
  10.             : _p_vals( new int[ other._size  ] )  
  11.             , _size( other._size )  
  12.         {  
  13.             for ( int i = 0; i < _size; ++i )  
  14.             {  
  15.                 _p_vals[ i ] = other._p_vals[ i ];  
  16.             }  
  17.         }  
  18.         ~ArrayWrapper ()  
  19.         {  
  20.             delete [] _p_vals;  
  21.         }  
  22.     private:  
  23.     int *_p_vals;  
  24.     int _size;  
  25. };  
来看move构造:
  1. class ArrayWrapper  
  2. {  
  3. public:  
  4.     // default constructor produces a moderately sized array  
  5.     ArrayWrapper ()  
  6.         : _p_vals( new int[ 64 ] )  
  7.         , _size( 64 )  
  8.     {}  
  9.    
  10.     ArrayWrapper (int n)  
  11.         : _p_vals( new int[ n ] )  
  12.         , _size( n )  
  13.     {}  
  14.    
  15.     // move constructor  
  16.     ArrayWrapper (ArrayWrapper&& other)  
  17.         : _p_vals( other._p_vals  )  
  18.         , _size( other._size )  
  19.     {  
  20.         other._p_vals = NULL;  
  21.     }  
  22.    
  23.     // copy constructor  
  24.     ArrayWrapper (const ArrayWrapper& other)  
  25.         : _p_vals( new int[ other._size  ] )  
  26.         , _size( other._size )  
  27.     {  
  28.         for ( int i = 0; i < _size; ++i )  
  29.         {  
  30.             _p_vals[ i ] = other._p_vals[ i ];  
  31.         }  
  32.     }  
  33.     ~ArrayWrapper ()  
  34.     {  
  35.         delete [] _p_vals;  
  36.     }  
  37.    
  38. private:  
  39.     int *_p_vals;  
  40.     int _size;  
  41. };  

可以看出,move构造和copy构造相互重载了,那么调用的时候如何判断调用哪个构造呢?
很简单,上边不是已经有了方法吗,
如果是临时对象就会自动调用move构造,如果不是,就会调用copy构造
。那么为什么move构造中要把原始指针置为null呢?
因为如果不置为null,那么临时变量消失时,会析构,释放自己的指针,
还资源给os,那么新对象中的指针也就随之会被delete掉。
所以需要把原始指针置为null,这 样临时变量在析构时就找不到给自
己分配的那块内存了,那块内存也就可以被新对象正常使用了。
注意:这里的重载规则要求如果要调用move构造,那么一定要传一个
临时变量,并且一定要是一个可以修改的临时变量,
如果不能修改,那么临对象内的指针就不能置为null了,如果一
个函数返回的是const类型,那么就不能调用move构造了

==================================================================================

简介


C++0X是新一代C++标准的非官方名称。它将代替C++03成为C++最新的标准。C++0X对C++的核心语言以及标准库经进行了部分更新。C++0X完全兼容目前的C++标准。


在C++0X之中,语言本身添加了对于多线程的支持。一些细节得到了改进,例如支持统一初始化方式。对泛型编程的支持方面有了更边界的,同时对功能进行了改进。


核心语言功能
右值引用


在C++03中,临时变量(右值,出现在等号右侧的变量。另一种解释是引用值,没有实际地址的值)和const & type没有实际的差别。而在C++0X标准中添加了一种新的引用类型。叫做右值引用。它的定义类似于typename &&。另外右值引用提供了一种转移语义。


动机


右值引用的出现使得一些基础概念或者effective C++中表述的一些条目需要重新编写。那么来看看右值引用出现的动机是什么。


来看一个例子


std::vector实际上内部就是一个C类型数组,并且提供了一些内存和性能优化管理的机制。那么在现行的C++03标准中,当一个vector临时变量或者函数返回一个vector类型对象的时候。这里无可避免、毫无疑问的将会产生一个新的vector变量,并且将所有右值中的成员变量拷贝到这个临时变量中。(当然有些编译器具有NRV的优化功能,但是这种优化功能的执行情况和在复杂函数中的优化效果值得商榷)并且在拷贝结束后这个临时变量将被销毁,完成它短暂而又神圣的使命。


vector<SpecialClass> func()


{


              …


                return vect; 


}


使用右值引用,在以上场景中std::vector的转移构造函数会被调用。转移的过程是把右值vector中指向C类型数组的指针直接拷贝到新的vector对象中。然后把右值中的数组指针置空。这样就省去了数组拷贝过程,并且删除一个空的临时变量不会产生大量的内存操作。


那么我们需要将返回值声明为std::vector<>&&,将会大幅简化内存操作。


vector<SpecialClass>&& func()


{


              …


                return std::move(vect); 


}


 


右值引用不能引用一个左值对象,为了可以对指定的左值对象进行右值引用操作。标准库提供了std::move()函数。通过该函数可以获得指定对象的左值。


为自己的类定制右值引用构造函数


SpecialClass(SpecialClass&& rhs)


{





return *this;


}


当调用右值引用的类并没有定义右值引用构造函数时,默认的拷贝构造函数会被调用,并且参数会以const &的形式传入。


为了便于在模板中进行参数推到,标准库提供了std::forward()函数通过此函数可以保证传入参数的左右值性质不变


template <class T, class A1>


inline


shared_ptr<T>


factory(A1&& a1)


{


    // If a1 is bound to an lvalue, it is forwarded as an lvalue


    // If a1 is bound to an rvalue, it is forwarded as an rvalue


    return shared_ptr<T>(new T(forward<A1>(a1)));


}


 


struct A


{


    ...


    A(const A&);  // lvalues are copied from


    A(A&&);       // rvalues are moved from


};


 


int main()


{


    A a;


    shared_ptr<A> sp1 = factory<A, A>(a);        // "a" copied from


    shared_ptr<A> sp2 = factory<A, A>(move(a));  // "a" moved from


}

weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值