C++11中的右值引用、移动语句和完美转换

C++11引入右值引用和移动语句,可以避免无谓的复制,提高程序的性能,右值引用记为T&&。

辨别左右值的便捷方法:看能不能对表达式取地址,若果能,则为左值,否则为右值。


左值引用, 使用 T&, 只能绑定左值;
右值引用, 使用 T&&, 只能绑定右值
常量左值, 使用 const T&, 既可以绑定左值又可以绑定右值;
已命名的右值引用,编译器会认为是个左值;
编译器有返回值优化,但不要过于依赖

要实现移动语义就必须增加两个函数:移动构造函数和移动赋值构造函数。

将左值转化为右值,使用T std::move(T)。就是将原来的T类型有变量名的数据转化为没有变量名的数据,而原来的变量值变成空值。

通过std::is_same即可判断两个类型是否一样,特别在模板里面,在不清楚模板的参数时,此功能可以对一些特定的参数类型进行特殊的处理,在模板里是利器!

在C++11中,拷贝构造/赋值和移动构造/赋值函数必须同时提供或同时不提供,程序员才能保证类同时具有拷贝和移动语义。只声明其中一种的话,类都仅能实现一种语义。其实,只实现一种语义,在类的编写中也是非常常见的。

只有移动语义的类型非常有趣,因为只有移动语义表示该类型的变量所拥有的资源只能被移动,而不能被拷贝。那么这样的自由必须是唯一的。因此,只有移动语义构造的类型往往都是“资源型”的类型。比如说智能指针,文件流,都可以视为“资源型”的类型。

在标准库中仅可移动的模板类:unique_ptr。vs2011,把ifstream这样的类型实现为仅可移动的。

在<type_traits>里,可通过一些辅助模板类来判断一个类型是否可以移动的,比如:

is_move_constructible, is_trivially_move_constructible, is_nothrow_move_constructible,使用方法仍然是使用其成员value。比如:

cout << is_move_constructible<UnknownType>::value;

就可打印出Unknown是否可以移动,这在一些情况下还是非常有用的。

有了移动语义,可以实现高性能的置换(swap)函数。只是置换指针,没有资源的释放与申请。

参考:

https://www.jianshu.com/p/d19fc8447eaa (作者写得好)

https://en.cppreference.com/w/cpp/utility/move

原文地址:https://www.cnblogs.com/gwzz/p/14025532.html