C++——字符类的运算符重载

运算符重载概念与原理

如果不做特殊处理,C++的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。

有时希望对象之间也能用这些运算符进行运算,使程序达到更简洁、易懂的目的。例如,复数是可以进行四则运算的,两个复数对象相加如果能直接用+运算符完成,不是很直观和简洁吗?

利用 C++ 提供的“运算符重载”机制,赋予运算符新的功能,就能解决用+将两个复数对象相加这样的问题。

运算符重载,就是对已有的运算符赋予多重含义,使同一运算符作用于不同类型的数据时产生不同的行为。运算符重载的目的是使得 C++ 中的运算符也能够用来操作对象。

函数名字为:关键字operator后面接需要重载的运算符符号。

函数原型:返回值类型 operator操作符(参数列表)

运算符重载注意点

1、运算重载符不可以改变语法结构。
2、运算重载符不可以改变操作数的个数。
3、运算重载符不可以改变优先级。
4、运算重载符不可以改变结合性。

可重载的运算符

双目算术运算符 + (加),-(减),*(乘),/(除),% (取模)
单目运算符 + (正),-(负),*(指针),&(取地址)
关系运算符 ==(等于),!= (不等于),< (小于),> (大于),<=(小于等于),>=(大于等于)
逻辑运算符 (逻辑或),&&(逻辑与),!(逻辑非)
自增自减运算符 ++(自增),–(自减)
位运算符 (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移)
赋值运算符 =, +=, -=, *=, /= , % = , &=, =, ^=, <<=, >>=
空间申请与释放 new, delete, new[ ] , delete[]
其他运算符 ()(函数调用),->(成员访问),,(逗号) [ ](下标)

不可重载运算符

域运算符 ::
长度运算符 sizeof
条件运算符 ?:
成员访问运算符 .

字符类的运算符重载

mystring.h

#include 
using namespace std;

#ifndef _MYSTRING_H
#define _MYSTRING_H

class MString
{
    friend ostream &operator<<(ostream &out, MString &obj); /*友元方法定义重载<<*/
    friend istream &operator>>(istream &in, MString &obj);  /*友元方法定义重载>>*/

private:
    /* data */
    char *str;
    int size; /*字符串长度*/

public:
    MString();                               /*无参构造*/
    MString(const char *str);                /*有参构造*/
    MString(const MString &obj);             /*拷贝构造*/
    ~MString();                              /*析构函数*/
    int Size(void);                          /*求字符串长度*/
    char operator[](int i);                  /*重载[]*/
    MString &operator+(const MString &obj);  /*重载+,两个对象相加*/
    MString &operator+(const char *str);     /*重载+,对象加字符串*/
    MString &operator=(const MString &obj);  /*重载=*/
    MString &operator+=(const MString &obj); /*重载+=*/
    bool operator==(const MString &obj);     /*重载==*/
    bool operator==(const char *str);        /*重载==,判断对象与字符串*/
};

#endif

mystring.cpp

#include 
#include 
#include "mystring.h"
using namespace std;

ostream &operator<<(ostream &out, MString &obj)
{
    out << obj.str;
    return out;
}

istream &operator>>(istream &in, MString &obj)
{
    if (obj.str != NULL) /*释放原有空间*/
    {
        delete obj.str;
        obj.str = NULL;
    }
    char buf[1024] = {0};  /*临时存放终端获取的数据*/
    in.getline(buf, 1024); /*将终端的数据读入buf中*/
    obj.str = new char[strlen(buf) + 1];
    strcpy(obj.str, buf);
    obj.size = strlen(buf);
    return in;
}

MString::MString()
{
    cout << "无参构造" << endl;
    this->str = NULL;
    this->size = 0;
}

MString::MString(const char *str)
{
    cout << "有参构造" << endl;
    this->str = new char[strlen(str) + 1];
    strcpy(this->str, str);
    this->size = strlen(str);
}
MString::MString(const MString &obj)
{
    cout << "拷贝构造" << endl;
    this->str = new char[strlen(obj.str) + 1];
    strcpy(this->str, obj.str);
    this->size = obj.size;
}

MString::~MString()
{
    cout << "析构函数" << endl;
    if (this->str != NULL)
    {
        delete str;
        this->str = NULL;
    }
}
int MString::Size(void)
{
    return this->size;
}
char MString::operator[](int i)
{
    if (i >= 0 && i < this->size)
    {
        return this->str[i];
    }
    else
    {
        cout << "下标错误" << endl;
        return 0;
    }
}
MString &MString::operator+(const MString &obj)
{
    int tmp_size = strlen(this->str) + strlen(obj.str);
    char *temp = new char[tmp_size];
    strcpy(temp, this->str);
    strcat(temp, obj.str);
    static MString s(temp);
    if (strcmp(s.str, temp) != 0)
    {
        strcpy(s.str, temp);
    }
    if (temp != NULL)
    {
        delete temp;
        temp = NULL;
    }
    return s;
}
MString &MString::operator+(const char *str)
{
    int temp_size = strlen(this->str) + strlen(str) + 1;
    char *temp = new char[temp_size];
    strcpy(temp, this->str);
    strcat(temp, str);
    static MString s(temp);
    if (strcmp(s.str, temp) != 0)
    {
        strcpy(s.str, temp);
    }
    if (temp != NULL)
    {
        delete temp;
        temp = NULL;
    }
    return s;
}
bool MString::operator==(const MString &obj)
{
    if (this->size == obj.size && strcmp(this->str, obj.str) == 0)
    {
        return true;
    }
    return false;
}
bool MString::operator==(const char *str)
{
    if (this->size == strlen(str) && strcmp(this->str, str) == 0)
    {
        return true;
    }
    return false;
}
MString &MString::operator=(const MString &obj)
{
    if (this->str != NULL)
    {
        delete str;
        this->str = NULL;
    }
    this->str = new char[strlen(obj.str) + 1];
    strcpy(this->str, obj.str);
    this->size = strlen(obj.str);
    return *this;
}
MString &MString::operator+=(const MString &obj)
{
    int temp_size = strlen(this->str) + strlen(obj.str);
    char *temp = new char[temp_size];
    strcpy(temp, this->str);
    strcat(temp, obj.str);
    if (this->str != NULL)
    {
        delete str;
        this->str = NULL;
    }
    this->str = new char[temp_size + 1];
    strcpy(this->str, temp);
    this->size = temp_size;
    return *this;
}

main.cpp

#include 
#include 
#include "mystring.h"
using namespace std;
int main()
{
    MString str1("hello");
    MString str2("world");
    cout << "str1: " << str1 << endl
         << "str2: " << str2 << endl;

    cout << "str1+str2: " << endl
         << str1 + str2 << endl;

    str1 += str2;
    cout << "str1+=str2: " << str1 << endl;
    cout << "str1+=str2的size: " << str1.Size() << endl;
    cout << "str1第3个字符: " << str1[3] << endl;

    str1 + "moni";
    cout << "str1+moni: " << str1 << endl;

    if (str1 == "welcome")
    {
        cout << "str1 == welcome" << endl;
    }
    else
    {
        cout << "str1 != welcome" << endl;
    }

    if (str1 == str2)
    {
        cout << "str1 == str2" << endl;
    }
    else
    {
        cout << "str1 != str2" << endl;
    }

    str1 = str2;
    cout << "str1=str2: " << str1 << endl;

    cout << "获取终端输入的字符串: ";
    cin >> str1;
    cout << "输出终端获取的字符串: " << str1 << endl;
}

测试结果

C++——字符类的运算符重载_第1张图片

你可能感兴趣的:(c++,重构)