5.类和对象_2

//运算符重载
//对于内置数据和类型,编译器知道如何运算
//加号运算符重载
//左移运算符重载:输出自定义数据类型
//C++编译器至少给一个类添加4个函数:默认构造函数、默认析构函数、默认拷贝函数、赋值运算符operator=()
#include <iostream>
using namespace std;
class Person
{
    friend ostream& operator<< (ostream& cout, const Person& p);
    friend class Person;
    friend void test01();
public:
    Person(int a,int b):m_A(a),m_B(b) {};
private:
    int m_A;
    int m_B;
    //相当于编译器给相加函数起了统一的名称
    //通过成员函数重载
    //加号运算符重载
    Person operator+ (Person& p) const
    {
        Person tmp(0,0);
        tmp.m_A = this->m_A + p.m_A;
        tmp.m_B = this->m_B + p.m_B;
        return tmp;
    }

    //左移运算符重载
    //// 利用成员函数,最终就是p.operator<<cout,简化后是p<<cout
    //// 所以通常不用成员函数重载运算符<<,因为cout在左侧
    //void operator<< (cout) const
    //{

    //}
};
//通过全局函数重载加法运算符
/*
Person operator+ (Person& p1, Person& p2)
{
    Person tmp(0,0);
    tmp.m_A = p1.m_A + p2.m_A;
    tmp.m_B = p1.m_B + p2.m_B;
    return tmp;
}
*/
//重载左移运算符
ostream& operator<< (ostream& cout,const Person& p)
{
    cout <<"m_A: " << p.m_A << " m_B: " << p.m_B;
    return cout;
}
void test01()
{
    Person p1(10, 20);
    Person p2(20, 30);
    Person p3 = p1 + p2;
    cout << p3.m_A << " " << p3.m_B << endl;
    cout << p3 << endl;
}
//重载递增运算符
class MyInteger
{
    friend ostream& operator<< (ostream& cout, const MyInteger& myint);
public:
    MyInteger()
    {
        m_Num = 0;
    }
    //重载前置++运算符
    MyInteger& operator++()
    {
        m_Num++;
        return *this;
    }
    //重载后置++运算符
    //void operator++(int) int代表占位参数,用于区分前置和后置
    MyInteger operator++(int)
    {
        MyInteger temp(*this);
        m_Num++;
        return temp;
    }
private:
    int m_Num;
};
ostream& operator<< (ostream& cout, const MyInteger& myint)
{
    cout << myint.m_Num;
    return cout;
}
void test02()
{
    MyInteger myint;
    cout << ++(++myint) << endl;

    MyInteger myint2;
    cout << myint2++ << endl;
    cout << myint2++ << endl;
}
class Person02
{
public:
    Person02(int age) :m_Age(new int(age)){}
    ~Person02()
    {
        if (m_Age != nullptr)
        {
            delete m_Age;
        }
    }
    int getAge()
    {
        return *m_Age;
    }
    Person02& operator=(Person02& p)
    {
        *m_Age = p.getAge();
        return *this;
    }
private:
    int* m_Age;
};
void test03()
{
    Person02 p1(18);
    Person02 p2(20);
    cout << "p1: " << p1.getAge() << endl;
    cout << "p2: " << p2.getAge() << endl;
    p1 = p2;
    cout << "p1: " << p1.getAge() << endl;
    cout << "p2: " << p2.getAge() << endl;
    Person02 p3(22);
    p1 = p2 = p3;
    cout << "p1: " << p1.getAge() << endl;
    cout << "p2: " << p2.getAge() << endl;
    cout << "p3: " << p3.getAge() << endl;
}
//关系运算符重载

//函数调用运算符重载
class MyFunc
{
public:
    void operator()(string test)
    {
        cout << test << endl;
    }
};
int main()
{
    //test01();
    //test02();
    //test03();
    MyFunc mf;
    mf("Hello!"); //由于使用非常像函数调用,因此称为仿函数
    MyFunc()("Hello World!"); //匿名对象,特点:当前行执行后立即被释放。也叫匿名函数对象
    system("pause");
    return 0;
}