C++11新特性应用--让你的程序更高效(右值引用避免深拷贝)
2016-01-07 21:38
162 查看
这里的内容注意参考书籍《深入应用C++11代码优化与工程级应用》
今天,重温一下右值。
使用右值,使得我们的C++程序更加高效。
我们可以简单把右值理解为一个临时变量。之前,我们谁也不会在意这个临时变量,但要付出了效率的代价。
而右值引用就是对右值进行的引用类型,与我们通常所说的引用一样,一定要记得初始化。
左右值区分:
再看看这个:
之前在初始化列表的博客中提到过,使用初始化列表进行初始化,比在构造函数中初始化效率更高,道理是一样的。
这结论一定是正确的,当你用VS编译器试图写代码进行验证的时候,你也许就会骂娘了,这他妈输出结果不是一样的吗。
我只能呵呵了,因为编译器对程序进行了优化,你是看不到的。如果非要搞明白,就试图一步一步看看反汇编吧,包你满意。
下面就说说使用右值如何避免深拷贝。
此时,你可能又要犯嘀咕了?
深拷贝不是好事儿吗,使我们自己写的赋值构造函数实现深拷贝吗,是为了避免两个指针指向同一个东西,也避免删除同一个东西两次。
但,凡是都是在不停的发展的。因为C++11引入了右值概念,所以这就使得之前我们所写的赋值构造函数并不是那么完美了。主要还是效率的问题了。
下面就是用到了移动构造函数~之前也有提到过啊:
有了右值引用和移动语义,在设计和实现类时,对于需要动态申请大量资源的类,应该设计右值引用的拷贝构造函数和赋值函数,以提高应用程序的效率。需要注意的是,我们一般在提供右值引用的构造函数的同时,也会提供常量左值引用的拷贝构造函数,以保证移动不成还可以使用拷贝构造。
今天,重温一下右值。
使用右值,使得我们的C++程序更加高效。
我们可以简单把右值理解为一个临时变量。之前,我们谁也不会在意这个临时变量,但要付出了效率的代价。
而右值引用就是对右值进行的引用类型,与我们通常所说的引用一样,一定要记得初始化。
左右值区分:
void func(X& x); // 左值引用 重载 void func(X&& x); // 右值引用 重载 X x; X foobar(); func(x); // 参数为左值,调用func(X& x); func(foobar()); // 参数为右值,调用func(X&& x);
再看看这个:
// lvalues: // int i = 42; i = 43; // ok, i is an lvalue int* p = &i; // ok, i is an lvalue int& foo(); foo() = 42; // ok, foo() is an lvalue int* p1 = &foo(); // ok, foo() is an lvalue // rvalues: // int foobar(); int j = 0; j = foobar(); // ok, foobar() is an rvalue int* p2 = &foobar(); // error, cannot take the address of an rvalue j = 42; // ok, 42 is an rvalue
之前在初始化列表的博客中提到过,使用初始化列表进行初始化,比在构造函数中初始化效率更高,道理是一样的。
这结论一定是正确的,当你用VS编译器试图写代码进行验证的时候,你也许就会骂娘了,这他妈输出结果不是一样的吗。
我只能呵呵了,因为编译器对程序进行了优化,你是看不到的。如果非要搞明白,就试图一步一步看看反汇编吧,包你满意。
下面就说说使用右值如何避免深拷贝。
此时,你可能又要犯嘀咕了?
深拷贝不是好事儿吗,使我们自己写的赋值构造函数实现深拷贝吗,是为了避免两个指针指向同一个东西,也避免删除同一个东西两次。
但,凡是都是在不停的发展的。因为C++11引入了右值概念,所以这就使得之前我们所写的赋值构造函数并不是那么完美了。主要还是效率的问题了。
下面就是用到了移动构造函数~之前也有提到过啊:
MyString(MyString&& str) { std::cout <<"Move Constructor is called! source: "<< str._data << std::endl; _len = str._len; _data = str._data; // 避免了不必要的拷贝 str._len = 0; str._data = NULL; } MyString&operator=(MyString&& str) { std::cout <<"Move Assignment is called! source: "<< str._data << std::endl; if (this != &str) { _len = str._len; _data = str._data; // 避免了不必要的拷贝 str._len = 0; str._data = NULL; } return *this; }
有了右值引用和移动语义,在设计和实现类时,对于需要动态申请大量资源的类,应该设计右值引用的拷贝构造函数和赋值函数,以提高应用程序的效率。需要注意的是,我们一般在提供右值引用的构造函数的同时,也会提供常量左值引用的拷贝构造函数,以保证移动不成还可以使用拷贝构造。
相关文章推荐
- C++11新特性应用--让你的程序更高效(右值引用避免深拷贝)
- c++使用mpich库编写并行程序
- 10个经典的C语言小程序
- C++11新特性应用--占位符(std::placeholders std::is_placeholder std::is_bind_expression)
- 总结C语言在嵌入式开发中应用的知识点(文件数据的加密与解密)
- 总结C语言在嵌入式开发中应用的知识点(文件数据的加密与解密)
- map——映射(message.cpp)
- C++ operator关键字(重载操作符)
- C++学习笔记(一)
- C++模版总结(2/2)
- c++实现gray code(格雷码)
- FileTool.exe 替换 Visual C++ 中的打开和添加到项目功能
- 《C++Primer 5e》学习笔记(6):类
- c++ 优秀文章
- 【C++11新特性】 nullptr关键字
- C和C++内存管理详解
- 欢迎使用CSDN-markdown编辑器
- explicit C++关键字
- C++错误调试集锦
- ubuntu 安装 GCC 和 G++ C++ 开发环境