C++右值引用完美展示与原理介绍
2016-08-23 18:38
405 查看
直接上代码,以自定义类MyString来演示创建多个对象却不用开辟新内存,也不用拷贝内存:
下面的getString函数内部,创建了三个对象,但是它们的资源却在像接力棒一样的传给下一个。从而不用开辟新内存,也不用拷贝内容。
最后一个对象用于真正的打印工作。
std::move用于返回对象的右值引用
而MyString的构造函数接受一个右值引用对象
MyString的构造函数在得到右值引用对象后交换资源,从而实现了偷梁换柱。避免了内存的重新开辟、拷贝、释放的过程。
传引用:T& 常用于修改对象
传应用:const T& 常用于只读对象
传值: T 常用于小型对象非频繁传值
传右值引用: T&& 常用于临时对象的资源交换,复杂对象避免拷贝
下面的getString函数内部,创建了三个对象,但是它们的资源却在像接力棒一样的传给下一个。从而不用开辟新内存,也不用拷贝内容。
最后一个对象用于真正的打印工作。
原理:
T&& std::move(const T& t)std::move用于返回对象的右值引用
而MyString的构造函数接受一个右值引用对象
MyString的构造函数在得到右值引用对象后交换资源,从而实现了偷梁换柱。避免了内存的重新开辟、拷贝、释放的过程。
总结:
从本例代码来看,右值引用相当于在参数传递的方式上增加了一种传参的形式。原有的传参形式:
传地址:T* C语言用法传引用:T& 常用于修改对象
传应用:const T& 常用于只读对象
传值: T 常用于小型对象非频繁传值
传右值引用: T&& 常用于临时对象的资源交换,复杂对象避免拷贝
//// move example #include <utility> // std::move #include <iostream> // std::cout #include <vector> // std::vector #include <string> // std::string using namespace std; class MyString { friend ostream& operator<<(ostream& os, const MyString& str) { return os<<str.m_pData; } public: MyString(void) :m_pData(nullptr),m_length(0),m_id(++s_i) { cout<<"MyString("<<m_id<<")"<<endl; } ~MyString() { cout<<"~MyString("<<m_id<<")"<<endl; Clear(); } MyString(const char* _pData, int _length) :m_pData(nullptr),m_length(0),m_id(++s_i) { cout<<"MyString(const char*,int,"<<m_id<<")"<<endl; Copy(_pData, _length); } MyString(const MyString& _strFrom) :m_pData(nullptr),m_length(0),m_id(++s_i) { cout<<"MyString("<<m_id<<", const MyString& "<<_strFrom.m_id<<" )"<<endl; if (_strFrom.m_pData == m_pData) { //do nothing } else { Copy(_strFrom.m_pData, _strFrom.m_length); } } //使用右值引用来创建对象时,使用资源交换来避免内存拷贝和重新创建 MyString(MyString&& _strFrom) :m_pData(nullptr),m_length(0),m_id(++s_i) { cout<<"MyString("<<m_id<<", MyString&& "<<_strFrom.m_id<<" )"<<endl; if (_strFrom.m_pData == m_pData) { //do nothing } else { swap(m_pData,_strFrom.m_pData); swap(m_length,_strFrom.m_length); } } protected: void Clear(void) { if (nullptr != m_pData) { delete[] m_pData; m_pData = nullptr; m_length = 0; } } void Copy(const char* _pData, int _length) { Clear(); m_pData = new char[_length]; for (size_t i = 0; i< _length; ++i) { m_pData[i] = _pData[i]; } m_length = _length; } private: char* m_pData; int m_length; int m_id; static int s_i; }; int MyString::s_i = 0; MyString getMyString(void) { //下面的代码创建了三个MyString对象,只发生了1次开辟内存,0次内存拷贝 MyString s("12345",6);//id == 1 MyString s1(move(s));//id == 2 return move(s1);//id == 3 这个被函数返回 //~MyString(2) //~MyString(1) } int main () { cout<<getMyString()<<endl;//打印的是函数返回的id == 3的那个对象 return 0; }
相关文章推荐
- [C++] 右值引用:移动语义与完美转发(C++是一种扼杀生命的语言)
- C++ 11: 右值引用,转移语义与完美转发
- C++标准之(ravalue reference) 右值引用介绍
- c++ 11 右值引用原理
- [C++] 右值引用:移动语义与完美转发
- 《C++0x漫谈》系列之:右值引用(或“move语意与完美转发”)(上)
- c++中的引用的使用原理和使用实例 (2)
- 《C++0x漫谈》系列之:右值引用(或“move语意与完美转发”)(上)
- 《C++0x漫谈》系列之:右值引用(或“move语意与完美转发”)(下)
- 《C++0x漫谈》系列之:右值引用(或“move语意与完美转发”)(上)
- C++中引用与指针的区别(详细介绍)
- 《C++0x漫谈》系列之:右值引用(或“move语意与完美转发”)(上)
- 《C++0x漫谈》系列之:右值引用(或“move语意与完美转发”)(下)
- C++ 11 右值引用的理解
- VC2010中C++的右值引用新特性
- C++之引用介绍
- c++中的引用的使用原理和使用实例 (3)
- 《C++0x漫谈》系列之:右值引用(或“move语意与完美转发”)(下)
- 《C++0x漫谈》系列之:右值引用或“move语意与完美转发”(上)
- C++右值引用