用C++编写一个MyString类

 1.平台:vs2019

2.很多知识点写在了代码里

class MyString
{
private:
	char* str;
	MyString(char* p, int x)
	{
		str = p;
	}
public:
	MyString(const char* p = nullptr) :str(nullptr)
	{
		if (p != nullptr)
		{
			int len = strlen(p) + 1;
			str = new char[len];
			strcpy_s(str, len, p);
		}
		else
		{
			str = new char[1];
			str[0] = '\0';//空字符串
		}
	}
	MyString(const MyString& s) :str(nullptr)//拷贝构造
	{
		if (s.str != nullptr)
		{
			int len = strlen(s.str) + 1;
			str = new char[len];
			strcpy_s(str, len, s.str);
		}
	
	}
	MyString& operator=(const MyString& s)//赋值运算符重载有4中情况 0  0    0  1   1  0      1 1
	{
		if (this != &s)
		{
			delete[]str;
			int len = strlen(s.str) + 1;//strlen不能计算空字符串的长度
			str = new char[len];
			strcpy_s(str, len, s.str);
		}
		return *this;
	}
	~MyString()
	{
		delete[]str;
		str = nullptr;
	}
	MyString operator+(const MyString& s)const//这里不能以引用返回,引用返回相当于是地址,函数调用完成之后,地址消失
	{
		
		int len = strlen(str) + 1 +strlen(s.str);
		
		char*ps = new char[len];
		
		strcpy_s(ps, len, str);
		strcat_s(ps, len, s.str);//只用放一个\0。前面加了两次1 所以这里减1

		return MyString(ps,1);
	}
	MyString operator+(const char* s)const
	{
		//return *this + MyString(s);//  第一种
		int len = strlen(this->str) + 1 + strlen(s);
		char* ps = new char[len];
		strcpy_s(ps, len, this->str);
		strcat_s(ps, len,s);//只用放一个\0。前面加了两次1 所以这里减1

		return MyString(ps, 1);
	}
	MyString& operator+=(const MyString &s)
	{
		
		int len = strlen(this->str) + 1 + strlen(s.str);
		char* tmp = this->str;
		this->str = new char[len];
		strcpy_s(str, len, tmp);
		strcat_s(str, len, s.str);//只用放一个\0。前面加了两次1 所以这里减1
		delete[]tmp;
		return *this; //掉一个私有的构造函数,这个函数只是自己用
	}
	char* Get()
	{
		return str;
	}
	const char* Get()const
	{
		return str;
	}
	void Print()
	{
		cout << "str    " << str << endl;
		
	}
	size_t Size()const { return strlen(str); }
	char &operator[](const int pos)//普通方法 这里不能直接在后面加const的原因是前面以引用返回,我们可以修改它的值,这里加了const就不允许修改值了
	{
		assert(pos >= 0 && pos < Size());
		return str[pos];
	}
	const char& operator[](const int pos)const//常方法,本来就是传常对象那么就不可以更改它的值,所以返回值加const
	{
		assert(pos >= 0 && pos < Size());
		return str[pos];
	}
	friend MyString operator+(const char* s, const MyString& p);

	friend ostream& operator <<(ostream& out, const MyString& s);

	friend istream& operator>>(istream& in, MyString& s);
};
MyString operator+(const char* s, const MyString& p)
{
	//return MyString(s) + p;
	int len = strlen(p.str) + 1 + strlen(s);
	char* ps = new char[len];
	strcpy_s(ps, len,s);
	strcat_s(ps, len, p.str);//只用放一个\0。前面加了两次1 所以这里减1

	return MyString(ps, 1);
}
ostream& operator<<(ostream& out, const MyString& s)
{
	cout << s.str;
	return out;//实现空行
 }
istream& operator>>(istream& in, MyString& s)//这里存在设置大小的问题,还没有解决
{
	delete[]s.str;
	s.str = new char[256];//这里如果给大了,会产生浪费,给小了可能不够,思考解决这个问题
	int len = 256;
	in.getline(s.str, len);
	return in;
}
void main()
{
	MyString s1("yh");
	MyString s2("hello");
	MyString s3;

	//operator<<(cout,s2);
	cout << s2 << endl;
	cout << s1 << endl;
	//s3 = s1;
	//s3.Print();
	//s1.Print();
	//s3 = s1 + s2;
	//s3.Print();

	//s3 = "new" + s1;
	//s3.Print();


	//s3 = s2 + "new";
	//s3.Print();

	//s3 = s1 += s2;
	//s3.Print();

	char ch = s1[0];
	//cout << ch << endl;
	s1[0] = 'x';//引用返回创建了副本,返回别名就可以修改
	//s1.Print();
}

你可能感兴趣的:(C++,编程,c++,开发语言)