手撕一个string类(c++)

包含构造函数、拷贝构造函数、析构函数、拷贝赋值
扩展:重载+、重载+=、重载==、重载[]、重载<<。

设计:
首先有一个成员变量char *m_data;,使用char型指针变量存储字符串的首地址
正因为有指针成员,所以必须自定义拷贝构造函数,因为默认的是浅复制,会造成空悬指针。

class myString
{
public:
	myString(const char *str = 0);					//构造
	myString(const myString& str);					//拷贝构造
	myString& operator=(const myString& str);		//重载=
	myString operator+(const myString& str) const;	//重载+
	myString& operator+=(const myString& str) ;		//重载+=
	bool operator==(const myString& str) const;		//重载==
	char& operator[](int index);					//重载[]
	~myString();									//析构

private:
	char *m_data;
};

构造函数:比如string s, string s(“aaaa”) 。所以构造函数要处理空和非空参数两种情况。

myString::myString(const char* pstr)
{
	if (pstr)
	{
		m_data = new char[strlen(pstr) + 1]; 动态申请长度+1的字符空间,因为末尾有个/0结束符
		strcpy(m_data, pstr);  把参数r指针指向的字符串拷贝到m_data指向的字符串
		// memset(m_data, pstr, m_length ); 用这句也可以
	}
	else
	{
		m_data = new char[1]; 参数为空,只要一个/0的空间
		*m_data = '\0';
	}
}

拷贝构造函数,防止浅拷贝

myString::myString(const myString& str)
{
	m_data = new char[strlen(str.m_data) + 1];
	strcpy(m_data,str.m_data);
}

赋值函数

myString& myString::operator=(const myString& str)
{
	if (this == &str)	return *this;
	delete []m_data;
	m_data = new char[strlen(str.m_data) + 1];
	strcpy(m_data, str.m_data);
	return *this;
}

1、注意几点,赋值函数有返回值的,表示可以连续赋值
2、一开始先判断是不是本身,是的话直接返回了,效率高;不然的话就先清空自己的m_data,因为自己已经初始化了,再strcpy复制数据,返回this指针表示对象

析构函数,标准形式,先清空自己的数据空间,再把指针置空。

myString::~myString()
{
	delete[]m_data;
	m_data = NULL;
}

重载等于符号
长度不等直接返回错误,再strcmp比较。

bool myString::operator==(const myString& str) const
{
	if(strlen(m_data) != strlen(str.m_data))
		return false;
	return strcmp(m_data, str.m_data) ? false : true;
}

[ ]用于快速查找字符串中的值,由于可能会被修改,我们需要将返回类型加上引用以便可以做左值。对于索引值过大的情况直接抛出异常。

char& myString::operator[](int index)
{
	if (index > strlen(m_data))
		throw "invalid index";
	else
		return m_data[index];
}
myString myString::operator+(const myString& str) const
{//新建一个长度为自身+连接字符的字符串,逐段拷贝
	myString newString;
	newString.m_data = new char[strlen(m_data) + strlen(str.m_data) + 1];
	strcpy(newString.m_data,m_data);
	strcat(newString.m_data,str.m_data);
	return newString;
}

strcat(newString.m_data,str.m_data);把第二参数指向的字符串从一参指向字符串的’\0’开始复制。追加到末尾
可以返回一个新对象,由于是局部对象,所以不能返回引用,不然内存安全问题了。返回值的话会有一次拷贝的过程产生临时对象,再把临时对象拷贝给接收的对象。

myString& myString::operator+=(const myString & str)
{
	char *newData = new char[strlen(m_data) + strlen(str.m_data) + 1];
	strcpy(newData,m_data);
	strcat(newData,str.m_data);
	delete[]m_data;
	m_data = newData;
	return *this;
}

由于要返回对象本身,所以先delete原来的数据,再m_data = newData

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值