C++中string类的实现!

在实现自己的string类之前,我们先来了解一下标准库的string类型。

string类型支持长度可变的字符串,C++标准库将负责管理与存储字符相关的内存,以及提供各种有用的操作。标准库string类型的目的就是满足对字符串的一般应用。要使用string类型的对象,必须加上头文件:#include<string>

#include<iostream>
#include<string>
using namespace std;

//string类
class CString
{
public:
	//构造
	CString(char *p = NULL)
	{
		if(p != NULL)//传进来的字符串判空
		{
			_pstr = new char[strlen(p)+1];
			strcpy(_pstr,p);
		}
		else
		{
			_pstr = new char[1];//若为空则赋予其一个char类型字节的长度
			*_pstr = '\0';
		}
	}
	//析构
	~CString()
	{
		delete []_pstr;
		_pstr = NULL;
	}
	//拷贝构造
	CString(const CString &src)
	{
		_pstr = new char[strlen(src._pstr)+1];
		strcpy(_pstr,src._pstr);
	}
	//赋值构造
	CString &operator=(const CString &src)
	{
		if(&src == this)
		{
			return *this;
		}

		delete []_pstr;

		_pstr = new char[strlen(src._pstr)+1];
		strcpy(_pstr,src._pstr);
		return *this;
	}

	//如果两个string对象长度不同,且短的string对象与长的string对象的前面部分相匹配,则短的string对象小于
	//两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。

	//重载>
	bool operator>(const CString &src)const
	{
		return strcmp(_pstr,src._pstr) > 0;
		
	}
	//重载<
	bool operator<(const CString &src)const
	{
		return strcmp(_pstr,src._pstr) < 0;
	}
	//重载==
	bool operator==(const CString &src)const
	{
		return strcmp(_pstr,src._pstr) == 0;
	}
	//得到字符串长度
	int length()const
	{
		return strlen(_pstr);
	}
	//重载[]
	char operator[](int index)const
	{
		if(index < 0 || index >strlen((this->_pstr)))
			throw "下标越界!";
		return _pstr[index];
	}
	//实现c_str()
	const char* c_str()const
	{
		return _pstr;
	}
	//定义CString的迭代器类型
	class iterator
	{
	public:
		//构造
		iterator(char *p) :it_str(p){}
        //重载迭代器的!=
		bool operator!=(const iterator &it)
		{
			return it_str != it.it_str;
		}
        //重载迭代器前置++
		void operator++()
		{
			it_str++;
		}
        //重置迭代器解引用*
		char& operator*()
		{
			return *it_str;
		}

	private:
		char *it_str;//迭代器指针

	};
    //实现迭代器begin()函数
	iterator begin()//返回容器0号元素的迭代器
	{
		return iterator(_pstr);
	}
    //实现迭代器end()函数
	iterator end()//返回容器最后一个元素后继位置的迭代器
	{
		return iterator(_pstr + length());
	}
private:
	char *_pstr;
	friend ostream &operator<<(ostream &out, const CString &str);//声明<<重载函数为友元函数
	friend CString operator+(const CString &lhs, const CString &rhs);//声明+重载函数为友元函数
};

//重载+
CString operator+(const CString &lhs, const CString &rhs)
{
	char *p = new char[strlen(lhs._pstr)+strlen(rhs._pstr)+1];//为连接好的字符串开辟空间
	strcpy(p,lhs._pstr);//拷贝lhs的字符串
	strcat(p,rhs._pstr);//拷贝rhs的字符串
	CString tmp(p);//用p构造临时对象
	delete []p;//析构p
	return tmp;//返回连接后的字符串
}
//重载<<
ostream &operator<<(ostream &out, const CString &str)
{
	out << str._pstr ;
	return out;
}

实现过程中大部分知识来自于字符串基础知识,除此之外,还将一部分运算符进行了重载!那么运算符重载是什么?

C++ 运算符重载的目的:让对象的运算表现的和内置类型一样。什么是内置类型?内置类型就是int,char等计算机内部本身就存在的类型。在运算符重载函数中有一部分实现在类内,一部分实现在类外。编译器优先去类的成员方法里面查找运算符重载函数(对象在左边),如果没有,然后再到全局找合适的运算符重载函数(对象在右边)

可重载操作符(如图)

不可重载操作符:①::  ②.*  ③.  ④:?

重载操作符函数的定义:

重载操作符是具有特殊名称的函数:保留字operator后加需重载的操作符。重载操作符函数具有返回类型和形参列表。

这里要提到一个特殊的符号"++",因为前置++和后置++在形式上符号是无法区分的。所以规定在前置++的重载函数的形参列表中多了一个只有int类型名无参数名的列表。

CComplex operator++()//后置++
CComplex operator++(int) //前置++

还有另外一个运算符的重载"()"

有operator()运算符重载的对象,一般使用在泛型算法当中,改变泛型算法的行为,使其能够内联,节省函数的调用开销

猜你喜欢

转载自blog.csdn.net/Disremembrance/article/details/88719204
今日推荐