#include <iostream>
#include <string.h>
using namespace std;
class MyString
{
public:
MyString(const char *str = NULL);
MyString(const MyString& str);
MyString& operator=(const MyString& str);
MyString(MyString&& str);
MyString& operator=(MyString&& str);
~MyString() {
delete[] pData;
}
char* getStr() { return pData; }
private:
char* pData;
};
//注意参数为常量字符串指针
//当创建一个字符串对象时,此时不是将pData直接指向外部字符串的地址,
//而是在MyString内部重新创建一个新的字符串,并将pData指向这个新的字符串的地址,
//所以MyString不会修改外部传入的字符串的内容,这点要注意
//例如调用MyString("abcdef"), 虽然已经为字符串“abcd”分配了内存,
//但是在MyString 内部会重新创建一个新的“abcd”
MyString::MyString(const char *str) {
cout << "Constructor: MyString is created!"<< endl;
if (str == NULL) {
pData = new char[1];
pData[0] = '\0';
}
else
{
int len = strlen(str) + 1;
pData = new char[len];
strcpy_s(pData, len, str);
}
}
MyString::MyString(const MyString& str) {
cout << "Copy Constructor: MyString is created!" << endl;
int len = strlen(str.pData); //strlen 碰到'\0'结束,返回的长度长度不包含'\0'
pData = new char[len + 1];
strcpy_s(pData, len + 1, str.pData);
}
//赋值函数中,上来比较 this == &other 是很必要的,因为防止自复制,这是很危险的,
//因为下面有delete []m_data,如果提前把m_data给释放了,指针已成野指针,再赋值就错了。
//返回值必须为引用类型MyString&,否则会调用一次拷贝构造函数
MyString& MyString::operator=(const MyString& str) {
cout << "operator= Constructor is Called!" << endl;
if (this == &str) {
return *this;
}
delete[] pData;
int len = strlen(str.pData);
pData = new char[len + 1];
strcpy_s(pData, len + 1, str.pData);
return *this;
}
MyString::MyString(MyString&& other) : pData(other.pData) {
cout << "Move Copy Constructor: MyString is created!" << endl;
other.pData = nullptr;
}
MyString& MyString::operator=(MyString&& other) {
cout << "Move operator= Constructor is Called!" << endl;
if (this == &other)
return *this;
delete[] pData;
pData = other.pData;
other.pData = nullptr;
}
ostream& operator<<(ostream &output, MyString str) {
return cout << str.getStr();
}
MyString getStr() {
MyString str("Hello");
return str;
}
void main() {
MyString str1("hello"); //调用普通构造函数
MyString str2("world"); //调用普通构造函数
MyString str3(str1); //调用拷贝构造函数
str3 = str2; //调用赋值函数
MyString str4 = getStr();
MyString str5;
str5 = getStr();
getchar();
}
运行结果如下:
Constructor: MyString is created!
Constructor: MyString is created!
Copy Constructor: MyString is created!
operator= Constructor is Called!
Constructor: MyString is created!
Move Copy Constructor: MyString is created!
Constructor: MyString is created!
Constructor: MyString is created!
Move Copy Constructor: MyString is created!
Move operator= Constructor is Called!
这里的细节可以参考一下陈硕的
C++面试中string类的一种正确简明的写法
https://www.cnblogs.com/Solstice/p/3362913.html
https://github.com/chenshuo/recipes/blob/master/string/StringTrivial.h