45右值引用
右值引用
- 左值有内存有名字,是可寻址的变量,有持久性。
- 右值没内存没名字,一般是不可寻址的常量,或在表达式求值过程中创建的无名临时对象,短暂性的。C++中的临时量均作为右值。拷贝构造函数或运算符重载可以使用右值引用作为函数参数,以处理临时量。
左值引用和右值引用
- 一般左值引用只能绑定左值,右值引用只能绑定右值。
- 特殊情况
const char& = 'a'其中'a'是右值,但可以绑定至常左值引用上
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "cstring"
using namespace std;
class CMyString
{
public:
CMyString(const char* p = nullptr)
{
if (p != nullptr)
{
mptr = new char[strlen(p) + 1];
strcpy(mptr, p);
}
else
{
mptr = new char[1];
*mptr = '\0';
}
cout << "CMyString()" << endl;
}
~CMyString()
{
delete[] mptr;
mptr = nullptr;
cout << "~CMyString()" << endl;
}
//左值引用参数的拷贝构造
CMyString(const CMyString& str)
{
mptr = new char[strlen(str.mptr) + 1];
strcpy(mptr, str.mptr);
cout << "CMyString(const CMyString&)" << endl;
}
//右值引用参数的拷贝构造,临时对象会调用
CMyString(CMyString&& str)
{
mptr = str.mptr;
str.mptr = nullptr;
cout << "CMyString(CMyString&&)" << endl;
}
//右值引用参数的运算符重载
CMyString& operator=(CMyString&& str)
{
cout << "String& operator=(String&&)" << endl;
if (this == &str)
return *this;
delete[] mptr;
mptr = str.mptr;
str.mptr = nullptr;
return *this;
}
const char* c_str() const { return mptr; }
private:
char* mptr;
friend CMyString operator+(const CMyString& lhs,
const CMyString& rhs);
friend ostream& operator<<(ostream& out, const CMyString& str);
};
CMyString GetString(CMyString& str)
{
const char* pstr = str.c_str();
CMyString tmpStr(pstr);
cout << "--------------------" << endl;
return tmpStr; //本来这里会调用左值引用构造临时对象,但由于tmpStr是临时变量,现在会匹配到右值引用拷贝构造
}
//CMyString operator+(const CMyString& lhs,
// const CMyString& rhs)
//{
// cout << "--------------------" << endl;
// char* ptmp = new char[strlen(lhs.mptr) + strlen(rhs.mptr) + 1]; //存在内存泄露
// strcpy(ptmp, lhs.mptr);
// strcat(ptmp, rhs.mptr);
// return CMyString(ptmp);
//}
CMyString operator+(const CMyString& lhs,
const CMyString& rhs)
{
cout << "--------------------" << endl;
// char* ptmp = new char[strlen(lhs.mptr) + strlen(rhs.mptr) + 1];
CMyString tmpStr;
tmpStr.mptr = new char[strlen(lhs.mptr) + strlen(rhs.mptr) + 1];
strcpy(tmpStr.mptr, lhs.mptr);
strcat(tmpStr.mptr, rhs.mptr);
return tmpStr; //tmpStr是右值 调用右值引用的拷贝构造给main中的临时量
}
ostream& operator<<(ostream& out, const CMyString& str)
{
out << str.mptr;
return out;
}
int main()
{
CMyString str1 = "aaaaaaaaaaaaaaaaa";
CMyString str2 = "bbbbbbbbbbbbbb";
CMyString str3 = GetString(str1); //main中返回的临时量也属于右值,重载右值引用的等号运算符
CMyString str4 = str1 + str2; //重载右值引用的拷贝构造
cout << str3 << endl;
cout << "--------------------" << endl;
return 0;
}

浙公网安备 33010602011771号