实现自己的字符串类
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;
}