STL之string类的模拟实现

一、四个默认成员函数

构造函数和析构函数

	class string
	{
	public:
		string(const char* str = "")
			:_str(new char[strlen(str)+1])
		{
			strcpy(_str, str);
		}
		~string()
		{
			delete[] _str;
			_str = nullptr; 
		}

拷贝构造和运算符重载

传统写法:

string(const string& s)
			:_str(new char[strlen(s._str)+1])
		{
			strcpy(_str, s._str);
		}
		const char* c_str()
		{
			return _str;
		}
		string& operator=(const string& s)
		{
			if (this != &s)
			{
				delete[] _str;
				_str = new char[strlen(s._str) + 1];
				strcpy(_str, s._str);
			}
			return *this;

现代写法:

	string(const string& s)
			:_str(nullptr)
		{
			string tmp(s._str);
			swap(_str, s._str);
		}
		string& operator=(string s)
		{
			swap(_str, s._str);
			return *this;
		}

二、string类的增删查改

在之前的代码下要添加内存和容量

	class string
	{
	public:
		string(const char* str = "")
		{
			_str = (new char[strlen(str) + 1]);
			_size = strlen(str);
			_capacity = _size;
			strcpy(_str, str);
		}
		~string()
		{
			delete[] _str;
			_str = nullptr; 
			_size = 0;
			_capacity = 0; 
		}
		string(const string& s) 
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			string tmp(s._str);
			swap(_str, tmp._str);
			swap(_size, tmp._size);
			swap(_capacity, tmp._capacity);
		}
		string& operator=(string s)
		{
			swap(_str, s._str);
			swap(_size, s._size);
			swap(_capacity, s._size);
			return *this;
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	};

关于const的描述

我们定义的类的成员函数中,常常有一些成员函数不改变类的数据成员,也就是说,这些函数是"只读"函数,而有一些函数要修改类数据成员的值。如果把不改变数据成员的函数都加上const关键字进行标识,显然,可提高程序的可读性。其实,它还能提高程序的可靠性,已定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理, const成员函数和const对象 实际上,const成员函数还有另外一项作用,即常量对象相关。对于内置的数据类型,我们可以定义它们的常量,用户自定义的类也一样,可以定义它们的常量对象。

1、非静态成员函数后面加const(加到非成员函数或静态成员后面会产生编译错误)

2、表示成员函数隐含传入的this指针为const指针,决定了在该成员函数中, 任意修改它所在的类的成员的操作都是不允许的(因为隐含了对this指针的const引用)

3、唯一的例外是对于mutable修饰的成员。加了const的成员函数可以被非const对象和const对象调用,但不加const的成员函数只能被非const对象调用。
前面使用const 表示返回值为const
后面加 const表示函数不可以修改class的成员

遍历

我们这里的第一种遍历需要const的帮助

[]+for

		//读
	const char& operator[](size_t i) const
	{
		return _str[i];
	}
		//可读可写
	char& operator[](size_t i)
	{
		return _str[i];
	} 	
	size_t size() const
	{
		return _size;
	}
void f(const string& s)
{
	for (size_t i = 0; i < s.size(); ++i)
	{
		cout << s[i] << endl;
	}
}

const对象不能调用非const的成员函数,所以size要加const。
如果是返回引用,成员函数就要提供两个,一个const一个是非const对象,保证可读可写。

迭代器

string的迭代器原理就是指针

		typedef char* iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
void test_string3()
{   
	string s1("hello world");
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";
		++it;
	}
	return 0;
}

三、增删查改

增:

		string& insert(size_t pos, char* str)
		{
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				reserve(_size + len);
			}
			char* end = _str + _size;
			while (end >= _str + pos)
			{
				*(end + len) = *end;
				--end;
			}
			strncpy(_str + pos, str, len);
			_size += len;
			return *this;
		}
		void push_back(char ch)
		{
			if (_size == _capacity)
			{
				reserve(_capacity * 2);
			}
			_str[_size] = ch;
			_str[_size + 1] = '\0';
			++_size;
		}
		void append(const char* str)
		{
			size_t len = _size + strlen(str);
			if (len > _capacity)
			{
				reserve(len);
			}
			strcpy(_str + _size, str);
			_size = len;
		}

删:

		string& erase(size_t pos, size_t end)
		{
			size_t leftLen = _size - pos;
			//1、剩余字符长度小于要删的长度
			//2、剩余字符长度大于要删的长度
			if (len >= leftLen)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				const char* start = _str + pos+len;
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}
		}

查:

		查找字符:
		size_t find(char ch, size_t pos = 0)
		{
			for (size_t i = pos; i < _size; ++i)
			{
				if (_str[i] = ch)
				{
					return i;
				}
			}
			return npos;
		}
		查找字符串:
		size_t find(const char* str, size_t pos = 0)
		{
			const char* ret = strstr(_str, str);
			if (ret)
			{
				return ret - _str;
			}
			else
			{
				return npos;
			}
		}

总结

string类是一个管理字符数组的类,要求这个字符数组结尾用’\0’
1.拷贝构造和赋值重载实现深拷贝
2.增删查改的相关接口(跟顺序表类似)
3.重载了一些常见运算符

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值