1. 右值引用
个人认为右值引用的目的主要是为了是减少内存拷贝,优化性能。
比如下面的代码:
String Fun() { String str = "hello world"; return str; }
str为临时对象,然后调用Stringd的拷贝构造函数,将临时对象的值赋值给String,这种拷贝是完全没有必要的,如果堆内存很大,那么这个拷贝构造的代价会很大,带来了额外的性能损耗。
为了避免链式对象的拷贝构造,我们可以使用右值引用拷贝的方式来实现:
MyString& operator=(MyString&& other) { cout << "MyString& operator=(const MyString&& other)" << endl; if (this != &other) { m_nLen = other.m_nLen; m_pData = other.m_pData; other.m_pData = NULL; } return *this; }
上面的代码只是进行了指针权限的转移,而没有额外的性能消耗。
1.1 使用右值引用实现MyString类
#include "stdio.h" #include <string> #include <iostream> using namespace std; class MyString { public: MyString() :m_pData(NULL), m_nLen(0) { cout << "MyString()" << endl; } MyString(const char *pStr) // 允许隐式转换 { cout << "MyString(const char *pStr)" << endl; m_nLen = strlen(pStr); CopyData(pStr); } MyString(const MyString& other) { cout << "MyString(const MyString& other)" << endl; if (!other.m_pData) { m_nLen = other.m_nLen; DeleteData(); CopyData(other.m_pData); } } MyString& operator=(const MyString& other) { cout << "MyString& operator=(const MyString& other)" << endl; if (this != &other) { m_nLen = other.m_nLen; DeleteData(); CopyData(other.m_pData); } return *this; } MyString(MyString&& other) { cout << "MyString(MyString&& other)" << endl; m_nLen = other.m_nLen; m_pData = other.m_pData; other.m_pData = NULL; } MyString& operator=(MyString&& other) { cout << "MyString& operator=(const MyString&& other)" << endl; if (this != &other) { m_nLen = other.m_nLen; m_pData = other.m_pData; other.m_pData = NULL; } return *this; } ~MyString() { DeleteData(); } private: void CopyData(const char *pData) { if (pData) { m_pData = new char[m_nLen + 1]; memcpy(m_pData, pData, m_nLen); m_pData[m_nLen] = '