问题的引入
如果有的应用场景必须返回的是定义过的对象,也必须按赋值的方式来接收函数调用,那优化的后两条规则就用不成了 解决办法:
- 给该类添加一个右值引用拷贝构造函数,函数内部不做资源的分配,而是资源的转移,每当有通过右值(临时对象)来构建对象的时候,就调用右值引用拷贝构造函数
右值引用
左值:有名字或有内存
右值:没名字(临时量)或没内存
int main()
{
int a=10;
int &b=a;
int &c=10;
const int &c =10;
int && d=10;
}
记住两句话:
通过右值引用提高效率
CMyString类增添右值引用参数的拷贝构造
我直接指向你的资源,再把你的指针置为空,你的资源相当于移动给我了
下图中tmpStr匹到的就是右值引用的拷贝构造,因为函数返回值属于右值
CMyString的重载加号运算符函数
给容器里拷贝构造对象(笔试题)
vector提供了左值引用与右值引用的拷贝构造函数,传的是左值就调用左值引用的拷贝构造函数,传的是右值,就调用右值引用的拷贝构造函数
move移动语义
move:移动语义,将val的类型强转右值引用类型继而可以通过右值引用使用该值,以用于移动语义。
std::move源码:_Ty是未定的引用类型,remove_reference_t用于移除_Ty的引用类型
std::move实现,首先,通过右值引用传递模板实现,利用引用折叠原理将右值经过T&&传递类型保持不变还是右值,而左值经过T&&变为普通的左值引用,以保证模板可以传递任意实参,且保持类型不变。然后我们通过static_cast<>进行强制类型转换返回T&&右值引用,而static_cast之所以能使用类型转换,是通过remove_refrence::type模板移除T&&,T&的引用,获取具体类型T。
使用示例:T && val是右值引用,但是val本身类型是左值,std::move(val);就可以将val的类型强转成右值引用类型
forward完美转发
forward:类型完美转发,能够识别左值和右值类型
完美转发的引入
如下代码中,有函数模板和&&,Ty就是一个未定的引用类型,但是不管它最终通过引用折叠,推演为左值引用还是右值引用,val本身类型都是左值,要想知道val最后是通过左值引用绑定的还是右值引用绑定的,就要用到完美转发:std::forward,forward解释为类型的完美转发 std::forward<Ty>(val);forward可以返回val到底是通过左值引用绑定的,还是右值引用绑定的 进而可以知道到底调用左值引用提供的construct,还是右值引用提供的construct
construct代码:
引用折叠
|