/*
CMyString(const char*)
CMyString(const char*)
CMyString(const char*)
CMyString(const CMyString&) => tmpStr拷贝构造main函数栈帧上的临时对象
~CMyString
operator=(const CMyString&) => main函数栈帧上的临时对象给t2赋值
~CMyString
aaaaaaaaaaaaaaaaaaaa
~CMyString
~CMyString
*/
改进:
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;//delete一个nullptr的指针不会发生报错
mptr = nullptr;
}
// 带左值引用参数的拷贝构造
CMyString(const CMyString &str)
{
cout << "CMyString(const CMyString&)" << endl;
mptr = new char[strlen(str.mptr) + 1];
strcpy(mptr, str.mptr);
}
// 带右值引用参数的拷贝构造
CMyString(CMyString &&str) // str引用的就是一个临时对象
{
cout << "CMyString(CMyString&&)" << endl;
mptr = str.mptr;
str.mptr = nullptr;
}
// 带左值引用参数的赋值重载函数
CMyString& operator=(const CMyString &str)
{
cout << "operator=(const CMyString&)" << 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) // 临时对象
{
cout << "operator=(CMyString&&)" << 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 operator+(const CMyString &lhs,
const CMyString &rhs)
{
//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);
//delete []ptmp;
return tmpStr; //
//return CMyString(ptmp);
}
ostream& operator<<(ostream &out, const CMyString &str)
{
out << str.mptr;
return out;
}
用模板代替写两个push_back函数!
forward完美转发:识别出Ty是左值引用还是右值引用,那么匹配不同的construct函数!
move:移动语义,得到右值引用类型(左值转换成右值引用)
为什么用forword?因为右值引用变量本身是一个左值!