String系列——运算符重载

本节实现所有运算符的重载。意图很简单,对于运算符重载不清楚的可以查看相关运算符重载的写法。
操作符重载很多,可以选择看。

定义

#pragma once
class MString{
public:
    //构造函数
    MString():m_len(0),m_str(0){}
    MString(const MString& s);
    MString(const char* s);
    MString(size_t n);
    ~MString();
    //赋值操作符,实现对象赋值
    MString& operator=(const MString& s);
    //赋值操作符,实现字符串赋值
    MString& operator=(const char* s);
    //转换成c类型字符串
    const char* c_str(){ return m_str; }
    //判断字符是否为空
    bool empty(){ return m_len>0? true:false; }
    //返回字符串长度
    size_t length(){ return m_len; }
    //返回字符串大小
    size_t size(){return m_len;}
    //删除pos开始的n个字符,不能为左值
    const MString& erase(size_t pos, size_t n);
    //对象末尾添加字符串s
    MString& append(const MString& s);
    //返回从pos开始的n个字符
    MString substring(size_t pos,size_t n);
    //从位置pos开始插入字符串s
    MString& insert(size_t pos,const MString& s);
    MString& insert(size_t pos,const char* s);
    //把字符串s中从pos开始的n个字符返回赋给当前字符串
    MString& assign(const MString& s, size_t,size_t);
    MString& assign(const char* s, size_t,size_t);

    //-------操作符重载-----------------------------------------
    /*---很多参数为MString对象的都可以再重载一个char*类型的方法--------------*/
    //比较操作符
    bool operator==(const MString& s2){ return strcmp(m_str,s2.m_str) == 0; }
    bool operator>=(const MString& s2){ return strcmp(m_str,s2.m_str) >= 0; }
    bool operator<=(const MString& s2){ return strcmp(m_str,s2.m_str) <= 0; }
    bool operator>(const MString& s2) { return strcmp(m_str,s2.m_str) > 0;  }
    bool operator<(const MString& s2) { return strcmp(m_str,s2.m_str) < 0;  }
    bool operator!=(const MString& s2){ return strcmp(m_str,s2.m_str) != 0; }

    //操作符,取地址
    MString& operator&();
    //操作符,取值
    MString& operator*();
    //操作符 ,->
    MString* operator->();

    //自增,自减
    MString& operator++();    //前缀
    MString& operator++(int); //后缀
    MString& operator--();    //前缀
    MString& operator--(int); //后缀

    //转换操作符,一般一个类只有一个转换操作符。
    //operator char*()const;

    //调用操作符
    int operator() (MString& s1, MString& s2);

    //操作符s[n],允许作为左值
    char& operator[](size_t n);
    //操作符s[n],不允许作为左值
    const char& operator[](const size_t n) const;
    //重载 s1 += s;
    MString& operator+=(const MString& s);  
    //重载 s1 += s;
    MString& operator+=(const char* s);
    //重载 s = s1+s2 改变被加对象
    MString& operator+(const MString& s);
    //重载 s = s1+s2 不改变被加对象
    friend MString operator+(const MString& s1, const MString& s2);
    //重载输入输出
    friend ostream& operator<<(ostream& out,const MString& str);
    friend istream& operator>>(istream& in,MString& str);
private:
    size_t m_len;
    char* m_str;
};

实现

//------操作符重载-----------------------------------------------
//操作符,取地址
MString& MString::operator&()
{
    return *this;
}
//操作符,取值
MString& MString::operator*()
{
    return *this;
}
//操作符 ,->
MString* MString::operator->()
{
    return this;
}

//自增,自减
MString& MString::operator++()   //前缀
{
    ++m_str;
    return *this;
}
MString& MString::operator++(int)//后缀
{
    MString* ret = new MString(*this);
    ++*this;
    return *ret;
}
MString& MString::operator--()    //前缀
{
    --m_str;
    return *this;
}
MString& MString::operator--(int) //后缀
{
    MString* ret = new MString(*this);
    ++*this;
    return *ret;
}

//转换操作符,一般一个类只有一个转换操作符。不能同时和[]重载运算符同时出现,会歧义。
//MString::operator char*()const
//{
//  return m_str;
//}

//调用操作符,在STL叫做适配器,很少使用。
int MString::operator() (MString& s1, MString& s2)
{
    return strcmp(s1->m_str,s2->m_str);
}

//操作符s[n],允许作为左值
 char& MString::operator[](size_t n)
 {
    assert(n>=0&&n<=m_len);
    return m_str[n];
 }
//操作符s[n],不允许作为左值
const char& MString::operator[](const size_t n) const
{
    assert(n>=0&&n<=m_len);
    return m_str[n];
}
//重载 s1 += s;
MString& MString::operator+=(const MString& s)
{
    if (!s.m_len){
        return *this;
    }
    m_len = m_len + s.m_len;
    char* tmp_str = new char[m_len +1];
    strcpy(tmp_str,this->m_str); 
    strcat(tmp_str,s.m_str);
    m_str[m_len] = '\0';
    if (m_str !=  NULL)
    {
        delete[] m_str;
    }
    m_str = tmp_str;
    return *this;
}
//重载 s1 += s;
MString& MString::operator+=(const char* s)
{
    if (strlen(s) < 1){
        return *this;
    }
    m_len = m_len + strlen(s);
    char* tmp_str = new char[m_len +1];
    strcpy(tmp_str,this->m_str); 
    strcat(tmp_str,s);
    tmp_str[m_len] = '\0';
    if (m_str !=  NULL)
    {
        delete[] m_str;
    }
    m_str = tmp_str;
    return *this;
}
//重载 s = s1+s2 改变被加对象
MString& MString::operator+(const MString& s)
{
    if (s.m_len <  1)
    {
        return *this;
    }
    char* tmp_str;
    m_len += s.m_len;
    tmp_str = new char[m_len+1];
    strcpy(tmp_str, m_str);
    strcat(tmp_str, s.m_str);
    tmp_str[m_len] = '\0';
    if (m_str != NULL)
    {
        delete[] m_str;
    }
    m_str = tmp_str;
    return *this;
}

//重载 s = s1+s2 不改变被加对象
MString operator+(const MString& s1, const MString& s2)
{
    MString* tmp = new MString(s1.m_len+s2.m_len);
    strcpy(tmp->m_str, s1.m_str);
    strcat(tmp->m_str, s2.m_str);
    tmp->m_str[tmp->m_len] = '\0';

    return *tmp;
}
//重载输入输出
ostream& operator<<(ostream& out,const MString& str)
{
    out << str.m_str;
    return out;
}
istream& operator>>(istream& in,MString& str)
{
    //遇到空格,就代表输入终止
    char* buf = new char[256];
    if(in >> buf){
        delete[] str.m_str;
        str.m_len = strlen(buf);
        str.m_str = new char[str.m_len+1];
        strcpy(str.m_str, buf);
    }
    return in;
}

本节是上一节的延续,代码都经过测试。

你可能感兴趣的:(C/C++)