mystring.h
#include<iostream>
using namespace std;
#ifndef MYSTRING_H
#define MYSTRING_H
class MyString
{
friend ostream& operator<<(ostream&out,MyString &ob);//友元函数重载<<的友元声明
friend istream& operator>>(istream&in,MyString &ob);//友元函数重载>>的友元声明
private:
char *str;
int size;//字符串长度
public:
MyString();//无参构造
MyString(const char *str);//有参构造函数
MyString(const MyString &ob);//拷贝构造
~MyString();//析构函数
int Size(void);//返回字符串长度
char& operator[](int i);//成员函数重载[]
MyString& operator =(const MyString &ob);//成员函数重载= 实现深赋值 ob1=ob2;
MyString& operator+(const MyString &ob);//成员函数重载+ 实现ob1+ob2
MyString& operator+(const char *str);//成员函数重载+ 实现ob1+"abc"
bool operator==(const MyString&ob);//成员函数重载== 判断ob1==ob2
bool operator==(const char *str);//成员函数重载== 判断ob1=="abc"
};
ostream& operator<<(ostream&out,MyString &ob);//友元函数重载<<
istream& operator>>(istream&in,MyString &ob);//友元函数重载>>
#endif // MYSTRING_H
mystring.cpp
#include "mystring.h"
#include<iostream>
#include<cstring>
using namespace std;
MyString::MyString()
{
this->str=NULL;
this->size=0;
cout<<"无参构造"<<endl;
}
MyString::MyString(const char *str)
{
cout<<"char * 构造函数"<<endl;
this->str=new char [strlen(str)+1];
strcpy(this->str,str);
this->size=strlen(str);
}
MyString::MyString(const MyString &ob)
{
cout<<"拷贝构造函数"<<endl;
this->str=new char[strlen(ob.str)+1];
strcpy(this->str,ob.str);
this->size=ob.size;
}
MyString::~MyString()
{
if(this->str!=NULL)
{
delete str;
this->str=NULL;
}
cout<<"析构函数"<<endl;
}
int MyString::Size()
{
return this->size;
}
char& MyString::operator[](int i)
{
if(i>=0&&i<this->size)
return (this->str)[i];
else
cout<<"下标无效"<<endl;
}
MyString &MyString::operator =(const MyString &ob)
{
//先将this->str的旧空间释放掉
if(this->str!=NULL)
{
delete str;
this->str=NULL;
}
this->str=new char[strlen(ob.str)+1];
strcpy(this->str,ob.str);
this->size=strlen(ob.str);
cout<<"=号赋值"<<endl;
return *this;
}
MyString& MyString::operator+(const MyString &ob)
{
/*
int tmp_size=strlen(this->str)+strlen(ob.str)+1;
char *tmp=new char[tmp_size];
strcpy(tmp,this->str);
strcat(tmp,ob.str);
MyString s (tmp);
if(tmp!=NULL)
{
delete tmp;
tmp=NULL;
}
return s; //这种写法不能实现cout<<str1+str2<<endl;
//只能实现MyString s1=str1+str2;
// cout<<s1<<endl;是因为c++编译器规定临时变量不能作为非const引用
*/
int tmp_size=strlen(this->str)+strlen(ob.str)+1;
char *tmp=new char[tmp_size];
strcpy(tmp,this->str);
strcat(tmp,ob.str);
static MyString s(tmp);//static变量s只会实例化一个对象并且不会因为这句话的tmp改变值
if(strcmp(s.str,tmp)!=0)//更新s变量中的值
strcpy(s.str,tmp);
if(tmp!=NULL)//及时释放堆区申请的空间
{
delete tmp;
tmp=NULL;
}
return s;
}
MyString& MyString::operator+(const char *str)
{
int tmp_size=strlen(this->str)+strlen(str)+1;
char *tmp=new char[tmp_size];
strcpy(tmp,this->str);
strcat(tmp,str);
static MyString s (tmp);
if(strcmp(s.str,tmp)!=0)
strcpy(s.str,tmp);
if(tmp!=NULL)
{
delete tmp;
tmp=NULL;
}
return s;
}
bool MyString::operator==(const MyString &ob)
{
if((strcmp(this->str,ob.str)==0)&&(this->size==ob.size))
return true;
else
return false;
}
bool MyString::operator==(const char *str)
{
if((strcmp(this->str,str) == 0)&&(this->size==strlen(str)))
return true;
else
return false;
}
ostream& operator<<(ostream&out,MyString &ob)
{
out<<ob.str;
return out;
}
istream &operator>>(istream &in, MyString &ob)
{
//记得将原有数据擦除
if(ob.str!=NULL)
{
delete ob.str;
ob.str=NULL;
}
char buf[1024]="";//临时buf
in.getline(buf,1024);//先得到键盘输入的数据 然后根据buf的实际大小开辟空间,最多读1023最后一位补\0
ob.str=new char [strlen(buf)+1];
strcpy(ob.str,buf);
ob.size=strlen(buf);
return in;
}
main.cpp
#include <iostream>
#include"mystring.h"
using namespace std;
void test01()
{
MyString s("hehedada");
cout<<s<<endl;
//自定义对象必须重载>> 普通全局友元函数
cin>>s;
cout<<s<<endl<<s.Size();
MyString str2("hello cccc");
//重载[]运算符
cout<<str2[1]<<endl;
//重载[]运算符 返回值必须是左值才能写操作
//所以重载[]运算符 返回值必须是引用
str2[1]='E';
cout<<str2<<endl;
MyString str3("hello str3");
cout<<str3<<endl;
//将str2赋值给str3
str3=str2;//默认赋值语句,浅拷贝,有指针对象 要重载=
cout<<str3<<endl;
MyString str4;
str4="hello wch";//这里没有重载 = const char *,这边隐式转换调用了有参构造创建临时变量,针对构造函数只有一个数据成员
cout<<str4<<endl;
str4[1]='E';
cout<<str4<<" size="<<str4.Size()<<endl;
}
void test02()
{
MyString str5("i love");
MyString str6("you ");
MyString str7("eeee");
//重载+号运算符实现拼接 拼接有两种 1、对str5和str6进行读操作 不改变值2、将str6接到str5上
MyString s1;
s1=str5+str6+str7;
cout<<str5+str6+str7<<endl;
cout<<s1<<endl;
//s1=s1+"EEEE";
cout<<s1+"EEE"<<endl;
if(str5==str6)
{
cout<<"相等"<<endl;
}
else
{
cout<<"不相等"<<endl;
}
if(str5=="i love")
{
cout<<"相等"<<endl;
}
else
{
cout<<"不相等"<<endl;
}
}
int main(int argc, char *argv[])
{
test01();
cout<<"------------------------------------"<<endl;
test02();
return 0;
}
运行结果: