C++ Mystring类(构造、析构和重载)

转载:https://blog.csdn.net/qq_42292831/article/details/84889076

功能实现:

<基本功能>

1> 实现头文件的封装:MyString.h

2> 缺省构造函数对字符串的初始化( MyString()3> 使用构造函数初始化字符串的另外两种方式 * 2( 动态指针+拷贝构造函数 )

4> 析构函数( 释放动态申请的字符串空间 )

5> 重载输出运算符( <<6> 重载赋值运算符 * 2=7> 重载下标运算符( [],索引输出 )

<拓展功能>

1> 字符串长度的比较

2> 字符串的排序功能

3> 字符串的倒置

4> 字符串中指定两个字符的交换

5> 查找某字符串是否位于指定的字符串中(采用暴力查找)

<细节修改>

1> 使用自定义函数来替换strlen()strcpy()

*******************************************************************************************************************

一: 基本功能 (实现源码)

1) MyString.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
 
#include <iostream>
#include <string.h>    //会借用strlen与strcpy函数实现相应的功能
using namespace std;
 
class MyString {
public:
	MyString();
	MyString(const char *const);
	MyString(const MyString &);
	~MyString();
	int length()const;    //const函数不能修改其数据成员,仅仅起到输出数据的作用
	int size() const;    //和length功能一致
	const char * getString() const;    //直接调用字符串首指针返回
	friend ostream & operator << (ostream &, const MyString &);    //重载输出运算符
	MyString & operator = (const MyString &);
	MyString & operator = (const char *	);
	char & operator [] (const int index);
 
private:
	char * str;    //指向数组首地址(此时为野指针)
	int len;
 
};

2)MyString.cpp
注意:定义一个字符串类的时候至少是一个空串。

#include "MyString.h"
using namespace std;
 
MyString::MyString()    //构造空字符串
{
	str = new char[1];
	str[0] = '\0';
	len = 0;
}
 
MyString::MyString(const char * const P)    //按照动态指针来构造相应的字符串
{
	if (P)
	{
		len = strlen(P);    //取长度
		str = new char[len + 1];    //开空间
		strcpy(str, P);    //复制值
	}
	else
	{
		MyString();    //如果传入的字符串为空,直接调用缺省值构造函数
	}
}
 
MyString::MyString(const MyString & AnotherMyString)  //拷贝构造函数,这里的形参使用了const,该形参类中的所有函数都要使用const来修饰
{
	len = AnotherMyString.length();
	str = new char[len + 1];
	strcpy(str, AnotherMyString.str);
}
 
int MyString::length() const   //求长度成员函数
{
	return len;
}
 
int MyString::size() const
{
	return len;
}
 
const char * MyString::getString()const
{
	return str;
}
 
 //=等号运算符重载
MyString & MyString::operator=(const MyString &AnotherMyString)
{
	if (&AnotherMyString == this)  //如果是自己赋值给自己
	{
		return *this;
	}
	delete[] str;
	len = AnotherMyString.length();
	str = new char[len + 1];
	strcpy(str, AnotherMyString.str);
	return *this;
	// TODO: 在此处插入 return 语句
}
 
MyString & MyString::operator=(const char * P)
{
	delete[] str;
	len = strlen(P);
	str = new char[len + 1];
	strcpy(str, P);
	return *this;
	// TODO: 在此处插入 return 语句
}
 
char & MyString::operator[](const int index)
{
	if (index > len)    //如果索引越界,输出最后一个字符
	{
		cout << "Warning!!!" << endl;
		cout << "Out of boundary! The last char is: ";
		return str[len - 1];
	}
	else
	{
		return str[index-1];
	}
	// TODO: 在此处插入 return 语句
}
 
MyString::~MyString()    //释放数组空间
{
	delete[] str;    //数组要用:delete[] 
	len = 0;
}
 
ostream & operator << (ostream & output, const MyString & str)    //重载输出运算符
{
	output << str.getString();
	return output;
	// TODO: 在此处插入 return 语句
}

3)test_main.cpp

#include "MyString.h"
using namespace std;
 
int main()
{
	MyString a;
	cout << "【调用缺省构造函数实现初始化】" << endl;
	cout << "string a = " << a << endl;
	cout << "Length = " << a.length() << endl << endl;
 
	MyString b("123456");
	cout << "【调用普通构造函数实现初始化】" << endl;
	cout << "string b = " << b << endl;
	cout << "Length = " << b.length() << endl << endl;
 
	MyString c(b);
	cout << "【调用拷贝构造函数实现初始化】" << endl;
	cout << "string c = " << c << endl;
	cout << "Length = " << c.length() << endl << endl;
 
	MyString d = b;    //这里不会再次调用缺省构造函数进行初始化
	cout << "【调用 =(对象) 实现赋值】" << endl;
	cout << "string d = " << d << endl;
	cout << "Length = " << d.length() << endl << endl;
 
	MyString e = "00000000";
	cout << "【调用 =(动态指针) 实现赋值】" << endl;
	cout << "string d = " << e << endl;
	cout << "Length = " << e.length() << endl << endl;
 
	MyString f = "abcdefghijklmn";
	char str = f[5];
	cout << "【调用 []  实现索引定位输出】" << endl;
	cout << "f[5] = " << str << endl << endl;
 
	return 0;
}

2018.12.20更新

二:拓展功能

<>字符串长度的比较
使用</>/>=/<=等符号进行比较,返回boolbool operator >(const MyString &str);
bool operator >(const char * c_str);
bool operator <(const MyString &str);
bool operator <(const char * c_str);
bool operator >=(const MyString &str);
bool operator >=(const char * c_str);
bool operator <=(const MyString &str);
bool operator <=(const char * c_str);
<>字符串的排序功能
使用类中的成员函数对类中的私有字符串进行从小到大的排序:
A.Sort_String_LB();
A.Sort_String_BL();
<>字符串的倒置
使用类中的成员函数对类中的私有字符串进行倒置:
A.Reverse();
<>字符串中指定两个字符的交换
A.ChangeTwoCharPosition(int firstposition,int second position);
<>查找某字符串是否位于指定的字符串中(采用暴力查找)
A.Find(char *search_string);

完整版源码:
MyString.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
 
#include <iostream>
#include <string.h>    //会借用strlen与strcpy函数实现相应的功能
using namespace std;
 
class MyString {
public:
	//构造函数+析构函数
	MyString();
	MyString(const char *const);
	MyString(const MyString &);
	~MyString();
 
	//直接调用字符串首指针返回,返回的指针可以直接使用cout<<输出
	const char * getString() const;    
 
	//求字符串的长度(直接返回类中的私有成员len的值)
	//const函数不能修改其数据成员,仅仅起到输出数据的作用
	int length()const;    
	int size() const;   
 
	//重载赋值运算符,使得可以使用对象与"xxxxxx"来赋值
	MyString & operator = (const MyString &);
	MyString & operator = (const char *	);
 
	//重载下标运算符
	char & operator [] (const int index);
 
	//重载输出运算符
	friend ostream & operator << (ostream &, const MyString &);    
 
	//字符串长度比较
	bool operator >(const MyString &str);
	bool operator >(const char * c_str);
	bool operator <(const MyString &str);
	bool operator <(const char * c_str);
	bool operator >=(const MyString &str);
	bool operator >=(const char * c_str);
	bool operator <=(const MyString &str);
	bool operator <=(const char * c_str);
 
	//字符串内部内容的冒泡排序(ASCII码),Little->Big
	void Sort_String_LB();
	void Sort_String_BL();
 
	//对字符串进行倒置
	void Reverse();
 
	//交换字符串中两个字符的位置
	void ChangeTwoCharPosition(int firstposition, int secondposition);
 
	//查询某字符串是否是指定字符串的子串(暴力模式)
	bool Find(char *search_string);
 
private:
	char * str;    //指向数组首地址(此时为野指针)
	int len;    //字符串的长度
 
};

MyString.cpp

#include "MyString.h"
using namespace std;
 
MyString::MyString()    //构造空字符串
{
	str = new char[1];
	str[0] = '\0';
	len = 0;
}
 
MyString::MyString(const char * const P)    //按照动态指针来构造相应的字符串
{
	if (P)
	{
		len = strlen(P);    //取长度
		str = new char[len + 1];    //开空间
		strcpy(str, P);    //复制值
	}
	else
	{
		MyString();    //如果传入的字符串为空,直接调用缺省值构造函数
	}
}
 
MyString::MyString(const MyString & AnotherMyString)  //拷贝构造函数,这里的形参使用了const,该形参类中的所有函数都要使用const来修饰
{
	len = AnotherMyString.length();
	str = new char[len + 1];
	strcpy(str, AnotherMyString.str);
}
 
int MyString::length() const   //求长度成员函数
{
	return len;
}
 
int MyString::size() const
{
	return len;
}
 
const char * MyString::getString()const
{
	return str;
}
 
MyString & MyString::operator=(const MyString &AnotherMyString)
{
	if (&AnotherMyString == this)
	{
		return *this;
	}
	//delete[] str;
	len = AnotherMyString.length();
	str = new char[len + 1];
	strcpy(str, AnotherMyString.str);
	return *this;
	// TODO: 在此处插入 return 语句
}
 
MyString & MyString::operator=(const char * P)
{
	//delete[] str;
	len = strlen(P);
	str = new char[len + 1];
	strcpy(str, P);
	return *this;
	// TODO: 在此处插入 return 语句
}
 
char & MyString::operator[](const int index)
{
	if (index > len)    //如果索引越界,输出最后一个字符
	{
		cout << "Warning!!!" << endl;
		cout << "Out of boundary! The last char is: ";
		return str[len - 1];
	}
	else
	{
		return str[index-1];
	}
	// TODO: 在此处插入 return 语句
}
 
bool MyString::operator>(const MyString & str)
{
	if (this->len > str.len)
	{
		return true;
	}
	else
	{
		return false;
	}
	return false;
}
 
bool MyString::operator>(const char * c_str)
{
	if (this->len > int (strlen(c_str)))
	{
		return true;
	}
	else
	{
		return false;
	}
	return false;
}
 
bool MyString::operator<(const MyString & str)
{
	if (this->len < str.len)
	{
		return true;
	}
	else
	{
		return false;
	}
	return false;
}
 
bool MyString::operator<(const char * c_str)
{
	if (this->len < int(strlen(c_str)))
	{
		return true;
	}
	else
	{
		return false;
	}
	return false;
}
 
bool MyString::operator>=(const MyString & str)
{
	if (this->len > str.len)
	{
		return true;
	}
	else if (this->len = str.len)
	{
		return true;
	}
	else
	{
		return false;
	}
	return false;
}
 
bool MyString::operator>=(const char * c_str)
{
	if (this->len > int(strlen(c_str)))
	{
		return true;
	}
	else if (this->len = strlen(c_str))
	{
		return true;
	}
	else
	{
		return false;
	}
	return false;
}
 
bool MyString::operator<=(const MyString & str)
{
	if (this->len < str.len)
	{
		return true;
	}
	else if (this->len = str.len)
	{
		return true;
	}
	else
	{
		return false;
	}
	return false;
}
 
bool MyString::operator<=(const char * c_str)
{
	if (this->len > int (strlen(c_str)))
	{
		return true;
	}
	else if (this->len = strlen(c_str))
	{
		return true;
	}
	else
	{
		return false;
	}
	return false;
}
 
void MyString::Sort_String_LB()
{
	int length = this->len;
	char temp_data;
	char *c_str = this->str;
	bool ischanged = false;
	for (int i = length-1; i > 0; i--)
	{
		for (int j = 0; j < i; j++)
		{
			if (c_str[j] > c_str[j + 1])
			{
				temp_data = c_str[j];
				c_str[j] = c_str[j + 1];
				c_str[j + 1] = temp_data;
				ischanged = true;
			}
		}
		if (!ischanged)
		{
			return;
		}
	}
}
 
void MyString::Sort_String_BL()
{
	int length = this->len;
	char temp_data;
	char *c_str = this->str;
	bool ischanged = false;
	for (int i = length - 1; i > 0; i--)
	{
		for (int j = 0; j < i; j++)
		{
			if (c_str[j] < c_str[j + 1])
			{
				temp_data = c_str[j];
				c_str[j] = c_str[j + 1];
				c_str[j + 1] = temp_data;
				ischanged = true;
			}
		}
		if (!ischanged)
		{
			return;
		}
	}
}
 
void MyString::Reverse()
{
	int length = this->len;
	char *c_str = this->str;
	char temp_data;
	for (int i = 0; i < length/2; i++)
	{
		temp_data = c_str[i];
		c_str[i] = c_str[length-1-i];
		c_str[length-1-i] = temp_data;
	}
}
 
void MyString::ChangeTwoCharPosition(int firstposition, int secondposition)
{
	int length = this->len;
	char *c_str = this->str;
	char temp_data;
	if (firstposition > len || secondposition > len)
	{
		cout << "输入下标越界,数组实际长度为: " << length << endl;
		return;
	}
	else
	{
		temp_data = c_str[firstposition-1];
		c_str[firstposition-1] = c_str[secondposition-1];
		c_str[secondposition-1] = temp_data;
	}
}
 
bool MyString::Find(char * search_string)   
{
	int length = this->len;
	char *c_str = this->str;
	bool judge = false;
	//确保i每次可以往后移动一位
	int temp_data=0;
 
	for (int i = 0,j=0; j < strlen(search_string)&&i<length; )
	{
		if (c_str[i] == search_string[j])
		{
			//cout << c_str[i] << "==" << search_string[j] << endl;
			//cout << i << "::" << j << endl;
			judge = true;
			i++;
			j++;
		}
		else
		{
			judge = false;
			temp_data++;
			i = temp_data;
			j = 0;
		}
	}
	return judge;
}
 
 
MyString::~MyString()    //释放数组空间
{
	delete[] str;
	len = 0;
}
 
ostream & operator << (ostream & output, const MyString & str)    //重载输出运算符
{
	output << str.getString();
	return output;
	// TODO: 在此处插入 return 语句
}

Test_Possess.cpp

#include "MyString.h"
using namespace std;
 
int main()
{
	MyString a;
	cout << "【调用缺省构造函数实现初始化】" << endl;
	cout << "string a = " << a << endl;
	cout << "Length = " << a.length() << endl << endl;
 
	MyString b("123456");
	cout << "【调用普通构造函数实现初始化】" << endl;
	cout << "string b = " << b << endl;
	cout << "Length = " << b.length() << endl << endl;
 
	MyString c(b);
	cout << "【调用拷贝构造函数实现初始化】" << endl;
	cout << "string c = " << c << endl;
	cout << "Length = " << c.length() << endl << endl;
 
	MyString d = b;    //这里不会再次调用缺省构造函数进行初始化
	cout << "【调用 =(对象) 实现赋值】" << endl;
	cout << "string d = " << d << endl;
	cout << "Length = " << d.length() << endl << endl;
 
	MyString e = "00000000";
	cout << "【调用 =(动态指针) 实现赋值】" << endl;
	cout << "string d = " << e << endl;
	cout << "Length = " << e.length() << endl << endl;
 
	MyString f = "abcdefghijklmn";
	char str = f[5];
	cout << "【调用 []  实现索引定位输出】" << endl;
	cout << "f[5] = " << str << endl << endl;
 
	//测试字符串的大小比较功能
	MyString A1 = "123456789";
	MyString B1 = "4321";
	MyString C1 = "456";
	MyString D1 = "456789";
	if (A1 >= B1)
	{
		cout << "A1>=B1" << endl;
	}
	else
	{
		cout << "A1<B1" << endl;
	}
 
	//测试字符串的排序功能
	B1.Sort_String_LB();
	cout << B1 << endl;
 
	//测试字符串的倒置功能
	A1.Reverse();
	cout << A1 << endl;
 
	//测试指定两个字符的交换
	A1.ChangeTwoCharPosition(1, 9);
	cout << A1 << endl;
 
	//判断某字符串是否为指定字符串的子串
	if (D1.Find("678"))
	{
		cout << "Successful!" << endl;
	}
	else
	{
		cout << "Fail!" << endl;
	}
	return 0;
}

2018.12.29更新

三:细节部分修改

本次更新了 “取消了strlen()与strcpy()的使用,在间接调用该接口的自定义函数中,使用自定义方法实现这两个接口的功能”

这里仅仅给出了替换部分部分示例,其他部分也可按照相同原理替换:

1> 使用指针实例化对象部分

MyString::MyString(char * P)    //按照动态指针来构造相应的字符串
{
	char * temp_P = P;   //使得指针指向的内存重置
	if (P)
	{
		int xx_length = 0;
		while (*P != '\0')
		{
			xx_length++;
			P = P + sizeof(char);
		}
		len = xx_length;
		P = temp_P;
		//len = strlen(P);    //取长度
		str = new char[len + 1];    //开空间
		strcpy(str, P);    //复制值
	}
	else
	{
		MyString();    //如果传入的字符串为空,直接调用缺省值构造函数
	}
}

2> 重载 “=” 运算符函数的过程

MyString & MyString::operator=(char * P)
{
	//delete[] str;
	char *temp_P = P;
	int xx_length = 0;
	char temp = '0';
	while (*P != '\0')
	{
		xx_length++;
		P = P + sizeof(char);
	}
	//len = strlen(P);
	len = xx_length;
	P = temp_P;
	str = new char[len + 1];
	for (int i = 0; i < len; i++)
	{
		*str = *P;
		str += sizeof(char);
		P += sizeof(char);
	}
	//strcpy(str, P);
	return *this;
	// TODO: 在此处插入 return 语句
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值