C++重载运算符练习

实现自己的字符串类

myString.h

#pragma once
#include <iostream>
using namespace std;
#include <string.h>

class myString
{
	friend ostream& operator<<(ostream& out, myString& ob);
	friend istream& operator>>(istream& in, myString& ob);

private:
	char* str;
	int len;
public:
	myString();//无参构造
	myString(const char* str);//有参构造
	~myString();//析构
	myString(const myString& ob);//深拷贝构造
	myString& operator=(const myString& ob);//重载=,实现ob3 = ob2 = ob1;
	char& operator[](int index);//重载[],实现ob[index] = 'A',index是下标
	myString& operator=(const char* str);//重载=,实现ob2 = ob1 = "hehexixi";
	myString& operator+(const myString& ob);//重载+,实现ob1+ob2+ob3是字符串拼接效果
	myString& operator+(const char* str);//重载+,实现ob1+"字符串常量"是字符串拼接的效果
	bool operator==(const myString& ob);//重载==,实现ob1==ob2,判断2个字符串是否相等
	bool operator==(const char* str);//重载==,实现ob1=="字符串常量",判断2个字符串是否相等
	bool operator!=(const myString& ob);//重载!=,实现ob1!=ob2,判断2个字符串是否不相等
	bool operator!=(const char* str);//重载!=,实现ob1 != "字符串常量",判断2个字符串是否不相等
};

myString.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "myString.h"

//重载<<,实现cout << ob1 << ob2 << endl;
ostream& operator<<(ostream& out, myString& ob)
{
	out << ob.str;
	return out;//返回标准输出流对象out的引用,可以实现链式调用
}

//重载>>,实现cin >> ob1 >> ob2;
istream& operator>>(istream& in, myString& ob)
{
	if (ob.str != NULL)//先将原有数据释放
	{
		delete ob.str;
		ob.str = NULL;
	}
	char buf[1024];
	in >> buf;//临时空间接收键盘输入数据

	ob.str = new char[strlen(buf) + 1];//根据键盘输入数据的长度开辟空间
	strcpy(ob.str, buf);//接收键盘输入数据
	ob.len = strlen(buf);//接收键盘输入数据的长度

	return in;//返回标准输入流对象in的引用,可以实现链式调用
}

myString::myString()
{
	str = NULL;
	len = 0;
	cout << "无参构造" << endl;
}

myString::myString(const char* str)
{
	this->str = new char[strlen(str) + 1];
	strcpy(this->str, str);
	cout << "有参构造" << endl;
	len = strlen(str);
}

myString::~myString()
{
	if (this->str != NULL)
	{
		delete[] this->str;
		this->str = NULL;
	}
	cout << "析构" << endl;
}

myString::myString(const myString& ob)
{
	this->str = new char[strlen(ob.str) + 1];
	strcpy(this->str, ob.str);
	cout << "深拷贝构造" << endl;
	this->len = ob.len;
}

myString& myString::operator=(const myString& ob)//重载=,实现ob3 = ob2 = ob1;
{
	if (this->str != NULL)//如果已有对象是通过有参构造创建的,那就他就已经有指向堆空间,我们不知道原有空间能否容下拷贝的字符串,如果直接拷贝字符串内容,可能会溢出
	{
		delete [] this->str;//所以要先释放原有空间,再根据拷贝的字符串长度开辟新空间
		this->str = NULL;
	}
	this->str = new char[ob.len + 1];
	strcpy(this->str, ob.str);
	this->len = ob.len;

	return *this;//返回引用实现链式调用
}

char& myString::operator[](int index)//重载[],实现ob1[index] = 'A',index代表下标
{
	if(index >= 0 && index < this->len)//判断下标合法性
		return this->str[index];//想要实现类似ob1[index] = 'A'的效果,也就是ob1[index]可以作为左值,就必须返回引用
	cout << "非法下标" << endl;
}

myString& myString::operator=(const char* str)//重载=,实现ob2 = ob1 = "hehexixi";
{
	if (this->str != NULL)//如果已有对象是通过有参构造创建的,那就他就已经有指向堆空间,我们不知道原有空间能否容下拷贝的字符串,如果直接拷贝字符串内容,可能会溢出
	{
		delete[] this->str;//所以要先释放原有空间,再根据拷贝的字符串长度开辟新空间
		this->str = NULL;
	}
	this->str = new char[strlen(str) + 1];
	strcpy(this->str, str);
	this->len = strlen(str);

	return *this;//返回引用实现链式调用
}

myString& myString::operator+(const myString& ob)//重载+,实现ob1+ob2+ob3是字符串拼接效果
{
	//计算字符串拼接后的长度newLen
	int newLen = this->len + ob.len;
	//根据newLen开辟临时空间
	char* tmp_str = new char[newLen + 1];
	memset(tmp_str, 0, newLen + 1);//将临时空间内容全设置为0;

	strcpy(tmp_str, this->str);
	strcat(tmp_str, ob.str);//将两段字符串拼接到临时空间

	//因为要实现链式调用,就要返回引用,但有不能返回局部对象的引用,所以设计成static静态对象
	static myString newstr(tmp_str);//根据临时空间中的字符串内容创建新字符串对象(调用有参构造)

	//释放临时空间
	if (tmp_str != NULL)//必须判断一下,因为有可能*this和ob是通过无参构造创建的对象,成员指针都为NULL
	{
		delete[] tmp_str;
		tmp_str = NULL;
	}

	return newstr;//返回静态对象的引用
}

myString& myString::operator+(const char* str)//重载+,实现ob1+"字符串常量"是字符串拼接的效果
{
	//计算字符串拼接后的长度newLen
	int newLen = this->len + strlen(str);
	//根据newLen开辟临时空间
	char* tmp_str = new char[newLen + 1];
	memset(tmp_str, 0, newLen + 1);//将临时空间内容全设置为0;

	strcpy(tmp_str, this->str);
	strcat(tmp_str, str);//将两段字符串拼接到临时空间

	//因为要实现链式调用,就要返回引用,但有不能返回局部对象的引用,所以设计成static静态对象
	static myString newstr(tmp_str);//根据临时空间中的字符串内容创建新字符串对象(调用有参构造)

	//释放临时空间
	if (tmp_str != NULL)//必须判断一下,因为有可能*this和ob是通过无参构造创建的对象,成员指针都为NULL
	{
		delete[] tmp_str;
		tmp_str = NULL;
	}

	return newstr;//返回静态对象的引用
}

bool myString::operator==(const myString& ob)//重载==,实现ob1==ob2,判断2个字符串是否相等
{
	if ( (strcmp(this->str, ob.str) == 0) && (this->len == ob.len) )
		return true;
	return false;
}

bool myString::operator==(const char* str)//重载== ,实现ob1 == "字符串常量", 判断2个字符串是否相等
{
	if ( (strcmp(this->str, str) == 0) && (this->len == strlen(str) )  )
		return true;
	return false;
}

bool myString::operator!=(const myString& ob)//重载!=,实现ob1!=ob2,判断2个字符串是否不相等
{
	if ((strcmp(this->str, ob.str) == 0) && (this->len == ob.len))
		return false;
	return true;
}

bool myString::operator!=(const char* str)//重载!=,实现ob1 != "字符串常量",判断2个字符串是否不相等
{
	if ((strcmp(this->str, str) == 0) && (this->len == strlen(str)))
		return false;
	return true;
}


test.cpp

#include "myString.h"

int main()
{
	myString str1("hehe");
	myString str2, str3;
	str2 = str1;
	cout <<"str2: " << str2 << endl;
	str2[1] = 'E';
	cout << "str2: " << str2 << endl;

	cin >> str3;
	cout << "str3: " << str3 << endl;

	myString str4(str3);
	cout << "str4: " << str4 << endl;

	str4 = str1 = "hehexixi";
	cout << "str4: " << str4 << endl;

	myString str5("你");
	myString str6("厉害");
	cout << str5 + str6 << endl;

	cout << str5 + "牛b" << endl;

	if (str5 == str6)
	{
		cout << "两个字符串相等" << endl;
	}
	else
	{
		cout << "两个字符串不相等" << endl;
	}

	if (str6 == "厉害")
	{
		cout << "两个字符串相等" << endl;
	}
	else
	{
		cout << "两个字符串不相等" << endl;
	}

	if (str5 != str6)
	{
		cout << "两个字符串不相等" << endl;
	}
	else
	{
		cout << "两个字符串相等" << endl;
	}

	if (str6 != "厉害")
	{
		cout << "两个字符串不相等" << endl;
	}
	else
	{
		cout << "两个字符串相等" << endl;
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值