初级C++:string类的实现


底层还是对字符串数组的操作
在这里插入图片描述


构造函数 、深拷贝、swap、析构

  • 模拟实现加上时命名空间。

构造函数


namespace MyString
{
	class string
	{	
	private:
		char* _a;
		_size;
		_cap;
	public:
		...
	}
};

string(const char* s)
	:_size(strlen(s))	//防止是无参空串 ,先测长度
	, _cap(_size)
{
	_a = new char[_cap + 1];
	strcpy(_a, s); 		//字符串拷贝到实例化的新对象这里
}

Swap


void swap(string& s)
{
//标准库里的swap
	::swap(_a, s._a);
	::swap(_size, s._size);
	::swap(_cap, s._cap);
}

/*template<class T>  //标准库里面的swap函数模板
void swap(T &a, T &b)   
{
    T temp = a;
    a = b;
    b = temp;
}*/

深度拷贝构造

string(const string& s)
	:_a(nullptr)
{
	string tmp(s._a);      //临时tmp出了这个域自动析构
	// ===  this->swap(tmp)
	swap(tmp);
}

析构

~string()
{
    delete[] _a;
    _str = nullptr;
    _size = 0;
    _capacity = 0;
}

resize 、 reserve

  • resize开空间,并初始化;
  • rserve只对cap扩容负责

resize

void resize(size_t n, char ch='0')
{
	/小于直接腰斩
	if (n<=_size)
	{
		_size = n;
		_a[_size] = '\0';  /不传默认用 0 
	}
	else
	{
		if (n>_cap)
		{
			reserve(n);     /开n个就好了
		}
		for (size_t i = _size; i < n; i++)
		{
			_a[_size] = ch;   /新开的初始化
		}
		_size = n;
		_a[_size] = '\0';
	}
}

reserve


void  reserve(size_t n)
{
	/开辟一块儿新的空间,拷贝源空间,销毁原空间
	if (n>_cap)
	{
		char* tmp = new char[n + 1];
		strcpy(tmp, _a);
		delete[] _a;
		_a = tmp;
		/size  没变 容量变化了
		_cap = n;
	}
}

重载 [ ] 访问、 赋值重载 =

字符串数组访问,返回字符

重载 [ ]

char& operator[](size_t pos)
{
	assert(pos < _size);
	return _a[pos];//*(a+pos)
}

//只读的
const char& operator[](size_t pos)const
{
	assert(pos < _size);
	return*(_a + pos); /_a[pos];
}

赋值重载 =

string& operator=(const string& s)
	{
		if (this != &s)
			{
			string tmp(s._str);
			swap(_str, tmp._str);
			}

			return *this;
	}

+= 重载、 c_str

//字符 
string& operator+=(char ch)
{
	string::push_back(ch);
	return *this;
}
//字符串
string& operator+=(const char* s)
{
	string::append(s);
	return *this;
}
void append(const char* s)
{
	//追加的字符串的长度
	size_t len = strlen(s);
	if (_size+len>=_cap)          //大于容量,扩容
	{
		reserve(_size + len);
	}
	//原字符长度尾部开始复制
	strcpy(_a + _size, s);
	_size += len;
}

//字符串对象
string&  operator+=(const string& s)
{
	*this += s._a;
	return *this;
}


---//C_str
//c_str,返回对象的字符串
		const char* c_str()
		{
			return _str;
		}


getinline

从输入流输入数据,存到对象里,遇到’\n’结束输入

//输入流的类型
istream& getline(istream& in, string& s)
	{
		s.clear();
		char ch = in.get();
		while (ch != '\n')
		{
			s += ch;
			ch = in.get();
		}
		return in;
	}

	void test_string6()
	{
		string s1;
		getline(cin, s1);
		cout << s1 << endl;
	}

输入输出操作符重载:<< 、>>

输入

	istream& operator>>(istream& in, string& s)
	{
		s.clear();
		char ch;
		ch = in.get();/每次获取一个字符
		while (ch != ' ' && ch != '\n')
		{
			s += ch;
			ch = in.get();
		}

		return in;
	}

输出


	ostream& operator<<(ostream& out, const string& s)
	{
		// 不管字符数组中的内容是啥,size是多少,就要输出多少个有效字符
		for (size_t i = 0; i < s.size(); ++i)
		{
			out << s[i];
		}

		return out;
	}

G

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值