运算符重载概念:对己有的运算符重新进行定义,赋予其另一种功能 ,以适应不同的数据类型

一、加号运算符重载

作用:实现两个自定义数据类型相加的运算

示例:operator+(成员函数重载的使用方式)

  1. #include <iostream>
  2. using namespace std;
  3. class Add
  4. {
  5. public:
  6. Add()
  7. {
  8. m_A = 100;
  9. m_B = 100;
  10. }
  11. Add operator+(Add a) //加号重载
  12. {
  13. Add temp;
  14. temp.m_A = this->m_A + a.m_A;
  15. temp.m_B = this->m_B + a.m_B;
  16. return temp;
  17. }
  18. int m_A;
  19. int m_B;
  20. };
  21. int main()
  22. {
  23. Add a,b,c;
  24. a.m_A = 10;
  25. a.m_B = 10;
  26. b.m_A = 10;
  27. b.m_B = 10;
  28. c = a + b; //他的本质调用其实是Add c=a.operator+(b);
  29. cout << c.m_A << endl;
  30. cout<< c.m_B<<endl;
  31. system("pause");
  32. }

示例:operator+(全局函数重载的使用方式)

#include <iostream>
using namespace std;
class Add
{
public:
    Add()
    {
        m_A = 100;
        m_B = 100;
     }

    int m_A;
    int m_B;
};
Add operator+(Add &a,Add &b)    //加号重载
{
    Add temp;
    temp.m_A = a.m_A + b.m_A;
    temp.m_B = b.m_B + b.m_B;
    return temp;
}
int main()
{
    Add a,b,c;
    a.m_A = 10;
    a.m_B = 10;
    b.m_A = 10;
    b.m_B = 10;
    c = a + b;      //他的本质调用其实是Add c=operator+(a,b);
    cout << c.m_A << endl;
    cout<< c.m_B<<endl;
    system("pause");
}

二、左移运算符重载

作用:可以输出自定义数据类型

示例:operator<<(全局函数重载的使用方式)

注:成员函数重载左移运算符没有意义

#include <iostream>
using namespace std;
class Add
{
public:
    int m_A;
    int m_B;
};
ostream& operator<<(ostream &t,Add &b)          //左移运算符重载,这里的&t是引用cout,是cout的别名,因此这里没有问题
{
    t << "m_A=" << b.m_A << "   m_B=" << b.m_B;
    return t;
}
int main()
{
    Add a;
    a.m_A = 10;
    a.m_B = 10;
    cout << a<<endl<<a;
    system("pause");
}

如果成员变量为私有,可以用友元声明来实现:

#include <iostream>
using namespace std;
class Add
{
    friend ostream& operator<<(ostream& cout, Add& b);   //友元声明
    friend void test();                                  //友元声明
private:
    int m_A;                                             //私有的成员变量
    int m_B;                                             //私有的成员变量
};
ostream& operator<<(ostream &cout,Add &b)          //左移运算符重载
{
    cout << "m_A=" << b.m_A << "   m_B=" << b.m_B;
    return cout;
}
void test()
{
    Add a;
    a.m_A = 10;
    a.m_B = 10;
    cout << a << endl << a;
}
int main()
{
    test();

    system("pause");
}

三、递增运算符重载

作用:通过重载递增运算符,实现自己的整型数据

示例:前置和后置递增

#include <iostream>
using namespace std;
class Myint
{
friend ostream& operator<<(ostream& t, Myint m);
public:
    Myint()
    {
        m_Num = 0;
    }
    Myint& operator++()        //前置++运算符
    {
        m_Num++;
        return *this;
    }

    Myint operator++(int)      //后置++运算符
    {
        Myint temp=*this;      //先记录当前的值
        m_Num++;               //再进行递增
        return temp;          //然后返回先前的值
    }
private:
    int m_Num;
};
ostream& operator<<(ostream& t, Myint m)
{
    t << m.m_Num;
    return t;
}
int main()
{
    Myint myint;
    cout<<"前置递增为:"<<endl;
    cout << ++myint << endl;
    cout << ++myint << endl;
    cout<<"后置递增为:"<<endl;
    cout << myint++ << endl;
    cout << myint++ << endl;
    system("pause");
}

结果:

四、赋值运算符重载

C++编译器至少给一个类添加4个函数

  • 默认构造函数,函数体为空
  • 默认析构函数,函数体为空
  • 默认拷贝构造函数(无参,函数体为空)
  • 默认运算符operator=,对属性进行值拷贝

如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

示例:operator=

#include <iostream>
using namespace std;
class Person
{
public:

    Person(int age)
    {
        m_Age = new int(age);
    }

    Person& operator=(const Person &p)       //重载赋值运算符
    {
                                      //m_Age = p.m_Age   这个是编译器提供的浅拷贝
        if (m_Age != NULL)            //应该先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝
        {
            delete m_Age;
            m_Age = NULL;
        }
        this->m_Age = new int(*p.m_Age);              //然后做深拷贝的操作
        return *this;
    }
    ~Person()
    {
        if (m_Age != NULL)
        {
            delete m_Age;
            m_Age = NULL;
        }
    }
    int* m_Age;
};
void test()
{
    Person p1(10);
    Person p2(20);
    Person p3(30);
    p3 = p2 = p1;
    cout << *p1.m_Age << endl;
    cout << *p2.m_Age << endl;
    cout << *p3.m_Age << endl;
}
int main()
{
    test();
}

结果:
image.png

五、关系运算符重载

作用:重载关系运算符,可以让两个自定义类型对象进行对比操作

示例:operator==和operator!=

#include <iostream>
using namespace std;
class Person
{
public:
    Person(string name,int age)
    {
        m_Age = age;
        m_Name = name;
    }
    int m_Age;
    string m_Name;

    bool operator==(Person& p)        //重载关系运算符operator==
    {
        if (this->m_Age == p.m_Age && this->m_Name == p.m_Name)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    bool operator!=(Person& p)
    {
        if (this->m_Age != p.m_Age || this->m_Name != p.m_Name)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

};
void test()
{
    Person p1("tom", 18);
    Person p2("tom", 28);
    if (p1 == p2)
    {
        cout << "p1和p2是相等的"<<endl;
    }
    else
    {
        cout << "p1和p2是不相等的" << endl;
    }
    if (p1 != p2)
    {
        cout << "p1和p2是不相等的" << endl;
    }
    else
    {
        cout << "p1和p2是相等的" << endl;
    }
}
int main()
{
    test();
}

结果:
image.png

六、函数调用运算符重载

  • 函数调用运算符()也可以重载
  • 由于重载后使用的方式非常像函数的调用,因此称为仿函数
  • 仿函数没有固定写法,非常灵活

    示例:operator()

    #include <iostream>
    using namespace std;
    class MyPrint
    {
    public:
      void operator()(string text)  //函数调用运算符重载  因为调用时非常像函数,所以也叫仿函数
      {
          cout << text;
      }
    };
    void test()
    {
      MyPrint print;
      print("hello word!\n");     //调用重载
    }
    int main()
    {
      test();
    }
    
    结果:
    image.png
    **