c++ String类及深浅拷贝(传统写法与现代写法)code

#####主要内容:模拟实现String类的默认成员函数,增删查改,及各类运算符重载等。

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<assert.h>

using namespace std;


class String
{
public:
	String(const char* str = "")//构造函数
		:_str(new char[strlen(str) + 1])//开辟一块和str等长的空间,用于存放对象的_str,需要算上'\0'
		, _size(strlen(str))//字符串长度,这里的_size和_capacity都不记'\0'
		, _capacity(_size)//开辟的最大空间,后面扩容需要判断
	{
		strcpy(_str, str);//拷贝即可
	}
	// s1.Swap(s2); 


	void show()//打印函数
	{
		cout << "_str:" << _str << endl;
		cout << "_size:" << _size << endl;
		cout << "_capcity" << _capacity << endl;

	}


	void Swap(String& s)//交换函数,另两个对象交换所有成员变量
	{
		if (s._str != _str)//如果两个字符串相同就没有拷贝必要了
		{
			//swap是库函数,可以直接用于交换
			swap(_str, s._str);
			swap(_size, s._size);
			swap(_capacity, s._capacity);
		}
	}


	//String s2(s1) 
	String(const String& s)//拷贝构造函数
		/*:_str(new char[strlen(s._str) + 1])
		,_size(s._size)
		,_capacity(s._capacity)*/
	{
		/*strcpy(_str, s._str);*/      //传统写法


		//现代写法
		String s1(s._str);   //创建一个临时对象,直接用于交换,临时对象出作用域自动析构
		Swap(s1);

	}


	// s1 = s2 
	String& operator=(const String &s)
	{

		if (_str != s._str)//避免出现自己给自己赋值的情况
		{
			//传统写法,自己释放,自己开空间
			//	delete[] _str;
			//	_str = new char[strlen(s._str) + 1];
			//	strcpy(_str, s._str);
			//	_size = s._size;
			//	_capacity = s._capacity;


			//现代写法,创建临时对象
			String tmp(s._str);
			Swap(tmp);

		}

		return *this;   //返回*this,适用于连等情况
	}


	~String()//析构函数,释放_str空间
	{
		delete[] _str;
		_str = NULL;

	}

	const char* c_str()//提取字符串,因为_str是私有成员,只能用这种方法返回
	{
		return _str;
	}


	void Expand(size_t n)//扩容,扩容到_size+n字节
	{
		_capacity += n;
		char *tmp = new char[_capacity + 1];
		strcpy(tmp, _str);
		swap(tmp, _str);
		delete[] tmp;
	}


	void PushBack(char ch)//在_str尾上插入字符ch
	{
		Insert(_size, ch);
	}


	//void PushBack(const char* str)

	void PopBack()//删除_str最后一个字符
	{
		Erase(_size - 1, 1);
	}


	void Insert(size_t pos, char ch)//在pos处插入字符ch
	{
		assert(pos <= _size);

		if (_size + 1 >= _capacity)//扩容
		{
			Expand(5);
		}



		memmove(_str + pos + 1, _str + pos, _size - pos + 1);
		_str[pos] = ch;
		_size++;
	}


	void Insert(size_t pos, const char* str)//在任意处插入一个字符串str
	{
		assert(pos <= _size);
		if (_size + strlen(str) >= _capacity)//扩容
		{
			Expand(strlen(str));
		}

		memmove(_str + pos + strlen(str), _str + pos, _size - pos + 1);
		strncpy(_str + pos, str, strlen(str));

		_size += strlen(str);

	}


	void Erase(size_t pos, size_t n = 1)//删除从pos处向后的n个字符,默认删除1个字符
	{
		assert(pos < _size);
		assert(n <= _size);
		if (_size == 0)//为空不能删除
		{
			cout << "the string is empty!!" << endl;
			return;
		}

		memmove(_str + pos, _str + pos + n, _size - n + 1);
		_size -= n;
	}


	size_t Find(char ch)//在_str中查找字符ch是否存在,若存在则返回第一次出现时的下标,不存在返回-1
	{
		char *tmp = strchr(_str, ch);//strchr:查找字符ch第一次出现的位置,存在返回指针,不存在返回NULL
		if (tmp == NULL)
		{
			printf("'ch' is not in this string!!\n");
			return -1;
		}
		return tmp - _str;
	}


	size_t Find(const char* str)//在_str中查找子串str,若存在返回第一次出现的下标,不存在则返回-1
	{
		assert(str);
		char *tmp = strstr(_str, str);

		if (tmp)
		{
			return tmp - _str;
		}
		return -1;
	}

	// s1 + 'a' 
	String operator+(char ch)
	{
		String s1(_str);
		s1.PushBack(ch);
		return s1;
	}


	String& operator+=(char ch)
	{
		PushBack(ch);
		return *this;
	}


	String operator+(const char* str)
	{
		String s1(_str);
		s1.Insert(strlen(_str), str);
		return s1;
	}


	String& operator+=(const char* str)
	{
		Insert(strlen(_str), str);
		return *this;
	}

	bool operator>(const String& s)
	{
		if (strcmp(_str, s._str) > 0)
		{
			return true;
		}
		return false;
	}


	bool operator>=(const String& s)
	{
		return (*this > s) | (*this == s);
	}

	bool operator<(const String& s)
	{
		return !(*this >= s);
	}
	
	
	bool operator<=(const String& s)
	{
		return !(*this > s);
	}
	
	
	bool operator==(const String& s)
	{
		if (strcmp(_str, s._str) == 0)
		{
			return true;
		}
		return false;
	}


	bool operator!=(const String& s)
	{
		return !(*this == s);
	}

private:
	char* _str;
	size_t _size;
	size_t _capacity;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值