运算符重载

对于内置的数据类,编译器直到如何进行运算

对于自定义数据类型,需要运算符重载

加号运算符重载

class Person
{
public:
    int m_A;
    int m_B;
    //成员函数重载
    Person operator+ (Person &p1)
    {
        Person temp;
        temp.m_A = this->m_A + p1.m_A;
        temp.m_B = this->m_B + p1.m_B;
        return temp;
    }
};

Person p3 = p1 + p2;
Person p4 = p1.operator+(p2);   //本质
//全局函数重载+号
Person operator+(Person &p1, Person &p2)
{
    Person temp;
    temp.m_A = p1.m_A + p2.m_A;
    temp.m_B = p1.m_B + p2.m_B;
    return temp;
}

Person p3 = p1 + p2;
Person p4 = operator+(p1, p2);  //本质

左移运算符重载

//左移运算符重载
class Person
{
    friend ostream & operator<<(ostream &cout, Person &p);
private:
    int m_A = 10;
    int m_B = 20;

    // 通常不会利用成员函数 实现左移运算重载,因为无法实现cout在左侧
    // 只能利用全局函数重载左移运算符

};

// 只能利用全局函数重载左移运算符
ostream & operator<<(ostream &cout, Person &p) 
{
    cout << p.m_A << " and " << p.m_B ;
    return cout;
    //利用链式调用,否则 cout << p1 << endl; 会崩
}

int main()
{
    Person p1;
    cout << p1 << endl;

    system("pause");
    return 0;
}

重载左移运算符配合友元可以实现输出自定义的数据类型

只有当要访问类对象的私有成员时才必须使用友元,只访问public成员不使用友元也是可以的。

递增运算符重载

实现自定义数据类型的自增

// 递增运算符重载
class MyInteger
{
    friend ostream & operator<<(ostream &cout, MyInteger &myint);

public:
    MyInteger()
    {
        m_Num = 0;
    }
    // 重载前置++运算符
    // 前置递增返回引用
    MyInteger & operator++()
    {
        m_Num++;
        return *this;
    }

    // 重载后置++运算符
    // 这个int代表一个占位参数,用于区分前置和后置递增
    // 后置递增返回值,因为temp时局部的,不能返回局部变量的引用
    MyInteger operator++(int)
    {
        //先记录当时的结果
        MyInteger temp = *this;  //将当前对象拷贝了一份
        //后递增
        m_Num++;
        //将记录的结果返回
        return temp;    // 返回的是拷贝的对象

    }

private:
    int m_Num;
};

//重载左移运算符 返回引用是为了一直对一个数据进行递增操作
ostream & operator<<(ostream &cout, MyInteger &myint)
{
    cout << myint.m_Num;
    return cout;
}

void test()
{
    MyInteger myint;
    //cout << ++myint << endl;
    cout << ++(++myint) << endl;
    cout << myint << endl;
    cout << "---------"<

赋值运算符重载

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

  1. 默认构造函数
  2. 默认析构函数
  3. 默认拷贝构造函数
  4. 赋值运算符 operator=,对属性进行值拷贝,默认系统的是浅拷贝
class Person
{
public:
    Person(int age)
    {
        m_Age = new int(age); //维护了堆区开辟的数据
    }
    int *m_Age;
    ~Person()
    {
        if (m_Age != NULL)
        {
            delete m_Age; //这里析构会崩,堆区重复释放
            m_Age = NULL;
        }
    }

};
void test()
{
    Person p1(18);
    Person p2(20);

    p2 = p1; // 浅拷贝

    cout << "p1的年龄是: " << *p1.m_Age << endl;
    cout << "p2的年龄是: " << *p2.m_Age << endl;
}
// 解决 深拷贝解决浅拷贝问题
// 所以就要重写 赋值运算符

class Person
{
public:
    Person(int age)
    {
        m_Age = new int(age); //维护了堆区开辟的数据
    }
    int *m_Age;
    ~Person()
    {
        if (m_Age != NULL)
        {
            delete m_Age; //这里析构会崩,堆区重复释放
            m_Age = NULL;
        }
    }

    Person & operator=(Person &p)
    {
        //编译器是提供浅拷贝
        //m_Age = p.m_Age;

        //先判断是否有属性在堆区
        if (m_Age != NULL)
        {
            delete m_Age;
            m_Age = NULL;
        }
        //深拷贝
        m_Age = new int(*p.m_Age);
        
        //返回对象自身
        return *this;
    }
};

void test()
{
    Person p1(18);
    Person p2(20);
    Person p3(60);

    p3 = p2 = p1; // 浅拷贝

    cout << "p1的年龄是: " << *p1.m_Age << endl;
    cout << "p2的年龄是: " << *p2.m_Age << endl;
    cout << "p3的年龄是: " << *p3.m_Age << endl;
}

关系运算符重载

让两个自动以类型对象进行对比操作

// 关系运算符重载
class Person
{
public:
    Person(string name, int age)
    {
        m_Name = name;
        m_Age = age;
    }

    string m_Name;
    int m_Age;

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

void test()
{
    Person p1("tom", 15);
    Person p2("tom", 11);

    if (p1 == p2)
    {
        cout << "p1 == p2" << endl;
    }
    if (p1 != p2)
    {
        cout << "p1 != p2" << endl;

    }
}

函数调用运算符重载

函数调用运算符() 也可以重载

重载后称仿函数

仿函数没有固定的写法,非常灵活

class MyPrint
{
public:
    //函数重载调用运算符
    int operator()(int a,int b)
    {
        return a + b;
    }
};
void test()
{
    MyPrint myPrint;
    int num = myPrint(1,2); //使用起来非常像函数调用,所以称为仿函数
    //仿函数非常灵活,参数功能等依据功能需求自定义,没有固定写法

    //匿名函数对象
    cout << MyPrint()(12, 12) << endl;
}

你可能感兴趣的:(运算符重载)