C++ 实现字符串类(重载运算符)

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;
}

运行结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值