编写MyString类实现C++库中string类的一些基础功能

我们首先来看看C++库中的string类有什么功能。

string s1("hel");
string s2("lo");
string s3;
	
s3 = s1 + s2;
cout << s3 << endl;

我们就先看看上面这些例子,首先我们可以用一个字符串给s1对象初始化,我们可以用+号连接两个字符串,同时我们还可以用=号直接给s3对象赋值,最后还可以用cout直接输出这个对象中的字符串。

我们自己写个类来实现这些功能。

实现这些功能需要注意的

1、要注意字符串的拷贝,深拷贝。

2、注意内存的动态分配和释放。

3、运算符重载的使用。

现在我们就来看看怎么编写这些功能,看代码。

#include <iostream>
#pragma warning(disable:4996) //由于在vs2015使用strcpy会报错,所以加了这一句话

using namespace std;

class MyString
{
public:
	MyString(char *s);
	MyString(const MyString &s);  //拷贝构造函数
	MyString(); //不带参数的构造函数
	~MyString();              //析构函数
	MyString& operator=(const MyString &s); //=号运算符重载
	MyString operator+(const MyString &s);//+号运算符重载
	char operator[](int i);//[]运算符重载
	bool operator<(const MyString &s);//<运算符重载
	bool operator>(const MyString &s);//>运算符重载
	bool operator==(const MyString &s);//==运算符重载
	bool operator!=(const MyString &s);//!=运算符重载
private:
	char *str;
	//友元函数
	friend ostream& operator<<(ostream &out, MyString &s);//重载左移运算符
	friend istream& operator >> (istream &in, MyString &s); //重载右移运算符
};

//不带参数的构造函数
MyString::MyString()
{
	this->str = new char[1];
	str[0] = '\0';
}

//带一个参数的构造函数
MyString::MyString(char *s)
{
	str = new char[strlen(s) + 1];
	strcpy(this->str, s);
}

//拷贝构造函数
MyString::MyString(const MyString &s)
{
	str = new char[strlen(s.str) + 1];
	strcpy(this->str, s.str);
}

//析构函数
MyString::~MyString()
{
	if (this->str != NULL)
	{
		delete[] this->str;
	}
}

//+号运算符重载
MyString MyString::operator+(const MyString &s)
{
	MyString p;
	p.str = new char[strlen(this->str) + strlen(s.str) + 1];
	strcpy(p.str, this->str);
	strcat(p.str, s.str);
	return p;
}

//=号运算符重载
MyString& MyString::operator=(const MyString &s)
{
	if (this == &s)
	{
		return *this;
	}
	if (this->str != NULL)
	{
		delete[] this->str;
	}
	this->str = new char[strlen(s.str) + 1];
	strcpy(this->str, s.str);
	return *this;
}

//[]运算符重载
char MyString::operator[](int i)
{
	int len = strlen(this->str) - 1;
	if (i > len)
	{
		return ('\0');
	}
	else
	{
		return (this->str[i]);
	}
}

//<运算符重载
bool MyString::operator<(const MyString &s)
{
	int ret;
	ret = strcmp(this->str, s.str);
	if (ret < 0)
		return true;
	else
		return false;
}

//>运算符重载
bool MyString::operator>(const MyString &s)
{
	int ret;
	ret = strcmp(this->str, s.str);
	if (ret > 0)
		return true;
	else
		return false;
}

//==运算符重载
bool MyString::operator==(const MyString &s)
{
	int ret;
	ret = strcmp(this->str, s.str);
	if (ret == 0)
		return true;
	else
		return false;
}

//!=运算符重载
bool MyString::operator!=(const MyString &s)
{
	int ret;
	ret = strcmp(this->str, s.str);
	if (ret != 0)
		return true;
	else
		return false;
}

//左移运算符重载
ostream& operator<<(ostream &out, MyString &s)
{
	out << s.str;
	return out;
}

//右移运算符重载
istream& operator>>(istream &in, MyString &s)
{
	char p[50];
	in.getline(p, 50);
	s = p;
	return in;
}
int main()
{
	MyString m1("hello");
	MyString m2("world");
	MyString m3;

	m3 = m1 + " " + m2;
	cout << "m3 = " << m3 << endl;
	
	MyString m4(m3);
	cout << "m4 = " << m4 << endl;

	cout << "m1[1] = " << m1[1] << endl;

	cout << (m1 < m2) << endl;
	cout << (m1 > m2) << endl;
	cout << (m1 == m3) << endl;
	system("pause");
	return 0;
}

这里主要讲解的是拷贝构造函数、赋值运算符重载、+号运算符重载和[]运算符重载的写法。

拷贝构造函数

MyString::MyString(const MyString &s)
{
	str = new char[strlen(s.str) + 1];
	strcpy(this->str, s.str);
}

拷贝构造函数的第一个参数时这个类的一个引用,拷贝构造函数主要完成两个任务:①是给类中的str动态分配空间,用来容纳传入的s对象中的str字符串。②将s对象中的str拷贝到被初始化对象的str中。

赋值函数(=号运算符重载)

MyString& MyString::operator=(const MyString &s)
{
	if (this == &s)
	{
		return *this;
	}
	if (this->str != NULL)
	{
		delete[] this->str;
	}
	this->str = new char[strlen(s.str) + 1];
	strcpy(this->str, s.str);
	return *this;
}

首先要判断这两个对象是否相同,如果相同就返回这个对象本身,如果不同就得判断原本的对象中给str分配的空间有没有被释放,如果没有就得将其内存释放,然后重新分配一个能够容纳用于赋值的对象中str的空间。然后再将这个str拷贝到被赋值的str中。

[]运算符重载

char MyString::operator[](int i)
{
	int len = strlen(this->str) - 1;
	if (i > len)
	{
		return ('\0');
	}
	else
	{
		return (this->str[i]);
	}
}

在写[]运算符重载的时候我们要注意下标的越界问题,所以我们得先判断要取出的下标是否越界,如果越界我就让其返回一个空字符。否则我们就返回相应的元素。

+号运算符重载

MyString MyString::operator+(const MyString &s)
{
	MyString p;
	p.str = new char[strlen(this->str) + strlen(s.str) + 1];
	strcpy(p.str, this->str);
	strcat(p.str, s.str);
	return p;
}
我们定义一个局部对象,用来存放连接后的字符串,首先要给它分配一个能够容纳两个字符串的空间,然后用strcpy将第一个字符串复制到p中,再用strcat连接这两个字符串。

猜你喜欢

转载自blog.csdn.net/y____xiang/article/details/80272501