c++学习:运算符重载编写字符串类实战

发布时间:2023年12月29日

目录

先定义一个类

定义构造和析构函数

用out<<

用s1.clear();清空数组

用s1.size();返回字符个数

加入扩容数组函数

用s2.append("world");和s1 += "nihao";追加数组数据

用if(s1 == s2)比较两个对象的数组

用if(s1 == "123456")比较对象的数组和字符串

用if(s1.compare(s2) == 0)和s1.compare("123456")比较两个的数组

用if(s1.find("123456")!=NULL)查找对象的数组中是否有字符串

思考s7 = s6;会发生什么

思考MString s9 = s8;会发生什么


先定义一个类

//char类型的数组类
class MString
{
public:
    MString(){}
    ~MString(){}
private:
    char *m_str;
    int m_size;
};

定义构造和析构函数

如果我想用不同的方法创建类的对象:例如

MString s0;
MString s1(10); //10代表的是数组的元素的个数
MString s2("hello"); //创建一个数据为hello的数组
MString s3('c',20);// 字符c 连续拷贝20个数组  cccccccccccccccccc

代码

public:
    MString(int size = 1024) // MString s0;  MString s1(10);
    {
        this->m_size = size;
        this->m_str = new char[this->m_size];

        memset(this->m_str,0,this->m_size);
    }
    MString(const char*str) // MString s2("hello");
    {
        //数组是一个动态数组 ,按需分配
        this->m_size = strlen(str) + 1;
        this->m_str = new char[this->m_size];

        strcpy(this->m_str,str);
    }
    MString(char ch,int length) // MString s3('c',20);
    {
        //数组是一个动态数组 ,按需分配
        this->m_size = length + 1;
        this->m_str = new char[this->m_size];

        for(int i=0; i<length; i++)
        {
            m_str[i] = ch;
        }
    }
    ~MString()
    {
        //释放堆的内容
        delete []this->m_str;
    }

用out<<s3<<endl;直接输出数组

ostream& operator<<(ostream &out,MString &ra)
{
    out<<ra.m_str;

    return out;
}

在类中定义友元函数
friend ostream& operator<<(ostream &out,MString &ra);

用s1.clear();清空数组

public:
    void clear()
    {
        memset(this->m_str,0,this->m_size);
    }

用s1.size();返回字符个数

public:
    int size()
    {
        return m_size;
    }

加入扩容数组函数

public:
    //扩容
    void setSize(int size)
    {
        if(m_size >= size)
            return ;

        //1、先保存原来的空间的数据
        char temp[this->m_size];
        memset(temp,0,this->m_size);

        strcpy(temp,m_str);

        //2、释放原来的空间
        delete []this->m_str;
        //3、申请更大的堆空间
        this->m_str = new char[size];
        this->m_size = size;
        memset(m_str,0,this->m_size);

        //4、重新把数据赋值回去
        strcpy(m_str,temp);
    }

用s2.append("world");和s1 += "nihao";追加数组数据

public:
    void append(const char*str)
    {
        //如果原来的空间不够。那么必须扩容
        if(strlen(m_str)+strlen(str)+1 > this->m_size)
        {
            //1、先保存原来的空间的数据
            char temp[this->m_size];
            memset(temp,0,this->m_size);

            strcpy(temp,m_str);

            //2、释放原来的空间
            delete []this->m_str;
            //3、申请更大的堆空间
            this->m_size = strlen(m_str)+strlen(str)+1;
            this->m_str = new char[m_size];

            memset(m_str,0,this->m_size);

            //4、重新把数据赋值回去
            strcpy(m_str,temp);
        }

        sprintf(this->m_str,"%s%s",this->m_str,str);
    }

    void operator+=(const char*str)
    {
        append(str);
    }

用if(s1 == s2)比较两个对象的数组

public:
    int operator==(MString &ra)
    {
        return !strcmp(this->m_str,ra.m_str);
    }

用if(s1 == "123456")比较对象的数组和字符串

public:
    int operator==(const char*str)
    {
        return !strcmp(this->m_str,str);
    }

用if(s1.compare(s2) == 0)和s1.compare("123456")比较两个的数组

public:
    int compare(const char*str) //compare  如果相同 返回 0   不同 非0
    {
        return strcmp(this->m_str,str);
    }
    int compare(MString &ra)
    {
        return strcmp(this->m_str,ra.m_str);
    }

用if(s1.find("123456")!=NULL)查找对象的数组中是否有字符串

public:
    char* find(const char*str)
    {
        return strstr(this->m_str,str);
    }

思考s7 = s6;会发生什么

s7 = s6; ------编译器在编译的时候 会自动转换成 运算符函数调用 s7.operator=(s6)
如果类中有 指针成员 指向堆空间,最好自定义赋值运算符函数

public:
    //如果没有自定义赋值运算符函数,那么此时编译器会自动给你生成默认的赋值函数
    void operator=(MString &ra) //MString &ra = s6
    {
        cout<<"void operator=(MString &ra)"<<endl;
        this->m_str = ra.m_str;
        this->m_size = ra.m_size;
    }
    //编译器默认生成的赋值函数  可能会造成内存泄漏
    //---------------------------------------------------------------------
    //这个可以防止内存泄漏
    void operator=(MString &ra) //MString &ra = s6
    {
        strcpy(this->m_str,ra.m_str);
        this->m_size = ra.m_size;
    }

思考MString s9 = s8;会发生什么

  • 在定义一个类对象的时候,通过另外一个对象来初始化,调用拷贝构造函数

  • MString s9 = s8;------->MString s9(s8);

    public:
        MString(const MString& other) {
            // 实现复制构造函数的代码
        }

文章来源:https://blog.csdn.net/weixin_59669309/article/details/135281089
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。