学习C++11之引用
来源:互联网 发布:2016淘宝客微信教程 编辑:程序博客网 时间:2024/05/22 10:50
1、左值引用
左值引用只能绑定左值,不能绑定右值.
如下:
int x = 1;int &y = x; //绑定左值,正确int &z = 2; //绑定右值2,编译错误但是可以将右值绑定到一个const左值引用(这是一个例外)
如:
//右值绑定到const左值引用int const &i = 28; //正确在右值引用诞生之前,为了传递临时对象到函数中以引用,这将允许实参隐式转换到形参类型,如下:
void print(std::string cosnt& s) {}print("hello"); //“hello”字符串是临时字符串对象,也是右值
右值引用只能绑定右值,不能绑定左值.使用两个&&表示右值引用.
如:
int&& i = 8; int j = 18; int&& k = j; //编译错误通过使用函数重载来决定函数参数是左值/右值,重载函数参数设置为左值引用和右值引用.
void fun_reference(int& a){ std::cout << "左值引用:" << a << std::endl;}void fun_reference(int&& a){ std::cout << "右值引用:" << a << std::endl;}int main(){ int x = 8; fun_reference(x); //输出左值引用:8 fun_reference(18); //输出右值引用:18 return 0;}
3、move语义
(1)move的作用是避免复制,提高效率.考虑一个函数以std::vector<int>作为参数,函数作用是在不改变实参的情况下,在vector中添加元素,旧方法使用常量左值引用作为参数,在内部先拷贝,再添加。如下所示:
void process_copy(std::vector<int> const& vec_){ std::vector<int> vec(vec_); vec.push_back(42);}上面函数能够传递左值和右值,但在内部都强制拷贝。假如使用右值引用重载上面函数,可以避免传递右值时强制使用拷贝。如下:
void process_copy(std::vector<int> && vec){ vec.push_back(42);}
(2)move构造函数
class X{private: int* data;public: X(): data(new int[1000000]) {} ~X() { delete [] data; } X(const X& other): data(new int[1000000]) { std::copy(other.data,other.data+1000 000,data); } X(X&& other): data(other.data) { other.data=nullptr; }};move构造函数允许拥有者的指针在对象之间传递,允许unique_ptr<>(拥有move构造函数)作为一个函数的返回值,函数返回值属于临时对象,可以作为右值传递给右值引用,避免了拷贝。
(3)std::move()
对于有名字的对象,可以使用std::move()函数和static_cast<>强制转换为右值,在赋值时,将调用效率更高的move赋值运算符,避免了拷贝
X x1;X x2=std::move(x1); //调用move赋值运算符X x3=static_cast<X&&>(x2); //同上
(4)注意,尽管右值引用能够绑定右值,但在函数体中,右值引用将会被函数”定义“为左值。如下:
void do_stuff(X&& x_){ X a(x_); //调用拷贝构造函数 X b(std::move(x_)); }do_stuff(X()); //传递右值,但在函数体中第一行代码将会调用拷贝构造函数X x;do_stuff(x); //这个调用就错误,左值不能被右值引用绑定
(5)右值引用和函数模板
当右值引用作为函数模板参数,会有差异。如果函数参数是一个模板参数的右值引用,模板推演参数类型将分两种:
template<typename T>void foo(T&& t){}
1)若是使用左值作为参数调用,模板将参数类型推演为左值引用。
int i=42;foo(i); //函数将被推演为:foo<int&>(i)2)若是使用右值作为参数调用,模板将参数类型推演为值的类型
foo(42); //推演为foo<int>(42)foo(3.14159); //推演为foo<float>(3.14159)foo(std::string()); //推演为foo<std::string>(std::string())
0 0
- 学习C++11之引用
- 【C++】 引用学习
- C++Primer 学习笔记之指针和引用
- Ndk学习之JNI全局引用和局部引用(java->c->java)
- C++学习之引用
- C++学习之引用
- C++学习之引用
- C++Primer读书笔记之引用
- c之引用作为参数
- C/C++学习笔记11:指针与引用的区别
- 引用 如何学习c#(如何学习程序语言)
- 引用 如何学习c#(如何学习程序语言)
- 【学习C++】学习C++ -> 引用( References )
- Javascript 学习笔记之引用
- c++ primer学习之-------引用
- perl学习总结之引用
- JavaScript学习之 引用类型
- C++每日学习之引用
- 0-1背包
- 负数在计算机中的表示
- 【暑假测试3】C HDU 5327 Olympiad
- UI 03 关于UITextField键盘遮挡问题
- 字典序排列的算法
- 学习C++11之引用
- HTTP中POST与GET 区别介绍
- Android基础之Activity四种启动模式
- Contiki例(三)使用etimer定时器激活被阻塞的任务
- ROS学习--(十三)编写简单的订阅器(subscriber),编译,测试
- AngularJs学习笔记__3、AngularJs模板
- centos 6实现ssh无密码登录的简便方法
- UITableView Cell
- 【C++】sizeof