【C++】右值引用的拷贝构造函数和赋值函数
右值引用后右值仍在函数栈上
右值引用是将哪些函数返回拷贝倒上级函数栈的匿名对象或者传参时的临时对象,这种右值直接利用;
相当于区分了深浅拷贝,使效率提高
右值是函数栈上的临时空间,右值引用相当于将其地址记录了
注意,右值引用避免绑定局部对象,局部函数弹出后,对象也被释放。
右值引用只是将临时对象的行作用域提升到当前右值引用的花括号作用域下。
#include <cstring>
#include <iostream>
#include <ostream>
using namespace std;
class CMyString {
public:
CMyString(const char *str = nullptr) {
cout << "CMyString(const char*)" << endl;
if (str != nullptr) {
mptr = new char[strlen(str) + 1];
strcpy(mptr, str);
} else {
mptr = new char[1];
*mptr = '\0';
}
}
~CMyString() {
cout << "~CMyString" << endl;
delete[] mptr;
mptr = nullptr;
}
// 左值引用参数的拷贝构造
CMyString(const CMyString &str) {
cout << "CMyString(const CMyString &str)" << endl;
mptr = new char[strlen(str.mptr) + 1];
strcpy(mptr, str.mptr);
}
// 右值引用参数的拷贝构造
CMyString(CMyString&& str){ // str引用的是上级函数传入的实参临时对象
cout << "CMyString(CMyString&& str)" << endl;
mptr = str.mptr;
str.mptr = nullptr;
}
CMyString& operator=(const CMyString &str) { // 4. 赋值构造
cout << "CMyString& operator=(const CMyString &str)" << endl;
if (this == &str)
return *this;
delete[] mptr;
mptr = new char[strlen(str.mptr) + 1];
strcpy(mptr, str.mptr);
return *this;
}
// 右值引用的赋值拷贝
CMyString& operator=(CMyString &&str) { // 4. 赋值构造
cout << "CMyString& operator=(const CMyString &str)" << endl;
if (this == &str)
return *this;
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);
return tmpStr;
}
CMyString operator+(const CMyString &lhs,const CMyString &rhs){
CMyString tmpStr; // 3. 默认构造
strcpy(tmpStr.mptr, lhs.mptr);
strcat(tmpStr.mptr,rhs.mptr);
return std::move(tmpStr); // 显示指定为移动构造
}
ostream& operator<<(ostream &out,const CMyString &str){
out << str.mptr;
return out;
}
int main() {
int a = 10;
int &b = a; // 左值:有内存,有名字
/*
int tmp = 20;
const int &c = tmp;
*/
const int &c = 20;
/*
int tmp = 20;
int &&c = tmp; // 汇编代码与const int &c = 20;相同
*/
int &&d = 20;
const CMyString &e = CMyString("aaa");
// int &&f = d; 一个右值引用变量,本身是一个左值
}

浙公网安备 33010602011771号