天天看点

2021-08-13c++——类之操作符重载

+号重载

1)成员函数重载

如果要返回Person类,构造Person的时候就一定要赋初始值。

如果不赋予初始值,就一定要有默认初始值,因为提供了含参构造函数,编译器就不会再提供默认构造函数了。

#include<iostream>
#include<string>

using namespace std;
class Person{
    public:
    int m_age;
    int m_money;
    Person(int a = 0,int b = 0):m_age(a),m_money(b){

    }
    Person operator+(Person p1){
        Person p;
        p.m_age = this->m_age + p1.m_age;
        p.m_money = this->m_money + p1.m_money;
        return p;
    }
};
int main(void){
    Person p1(10,200);
    Person p2(12,300);
    Person p3 = p1 + p2;
    
    cout << p3.m_age << " " << p3.m_money << endl;
}
           

2)全局函数重载

#include<iostream>
#include<string>

using namespace std;
class Person{
    public:
    int m_age;
    int m_money;
    Person(int a = 0,int b = 0):m_age(a),m_money(b){

    }
    // Person operator+(Person p1){
    //     Person p;
    //     p.m_age = this->m_age + p1.m_age;
    //     p.m_money = this->m_money + p1.m_money;
    //     return p;
    // }
};
Person operator+(Person p1,Person p2){
    Person p0;
    p0.m_age = p1.m_age + p2.m_age;
    p0.m_money = p1.m_money + p2.m_money;
    return p0;
}
int main(void){
    Person p1(10,200);
    Person p2(12,300);
    Person p3 = p1 + p2;
    
    cout << p3.m_age << " " << p3.m_money << endl;
}
           

<<操作符重载

1)成员函数重载

为什么这个不能用成员函数编写?

假如写成Person的成员函数,

class Person p{
	void operator<<(Person &p){
	}
	//这样展开以后会是p.operator<<
	//造成了本来要在右边的对象现在放在了左边,不符合输出的条件,而且ostream对象应该在右边,所以不能写成成员函数,
}

           

2)全局函数重载

#include<iostream>
#include<string>
using namespace std;
class Person{
    public:
    int m_age;
    int m_money;
    Person(int a = 0,int b = 0):m_age(a),m_money(b){
    }
};

ostream& operator<<(ostream &cout,Person &p){
    cout << "age : " << p.m_age << endl;
    cout << "money : " << p.m_money << endl;
    return cout;
}
//我这样写的问题在于只是将返回值设置为ostream对象可以链式编程,但是<<运算符所需要的两个对象我都没有传递进去
//注意的有两点
//1)是借助ostream类将其输出的,所以在传入的参数中需要有一个ostream类
//2)返回的时候必须返回引用,不能返回拷贝,具体的原理我不懂
//原因是流类的拷贝构造函数是私有的,不能被调用,而我们都知道当形参或返回值为对象类型时都要调用对象的拷贝构造函数进行对象的拷贝。
//真的是这样的吗?为什么要这样设计?
int main(void){
    Person p0(10,100);
    cout << p0 ;
    return 0;
}
           

++重载符

问题:

为什么不用全局函数而要用成员函数

一般情况下,前置递增符返回引用,后置递增符返回值;

前置递增符

#include<iostream>
#include<string>
using namespace std;
class Person{
    public:
    int m_age;
    int m_money;
    Person(int a = 0,int b = 0):m_age(a),m_money(b){
    }
    Person& operator++(){
        m_age++;
        m_money++;
        return *this;
    }
    //前置递增运算符返回引用,因为改变的是传入参数的本身,
    //返回引用使得可以接着改变,
    //如果返回值,即使本身被改变了,但是最终返回的值是拷贝后的结果
    //操作符重载的成员函数默认传递的是值吗?
};
ostream& operator<<(ostream &cout,Person &p){
    cout << "age : " << p.m_age << endl;
    cout << "money : " << p.m_money << endl;
    return cout;
}
int main(void){
    Person p0(10,100);
    cout << ++(++p0) ;
    cout << p0 ;
    return 0;
}
           

后置递增符

#include<iostream>
#include<string>
using namespace std;
class Person{
    public:
    int m_age;
    int m_money;
    Person(int a = 0,int b = 0):m_age(a),m_money(b){
    }
    Person operator++(int){//int为占位参数,用来区分是后置运算符重载
        Person p = *this;
        this->m_age++;
        this->m_money++;
        return p;
    }
};

ostream& operator<<(ostream &cout,Person p){
//ostream& operator<<(ostream &cout,const Person& p){
//或者是改成const reference
//之前出错的原因是在<<操作符重载的时候Person类传入的是引用,为什么这样对于后置递增运算符不行,但是对于前置运算符两者都可以。
    cout << "age : " << p.m_age << endl;
    cout << "money : " << p.m_money << endl;
    return cout;
}
int main(void){
    Person p1(10,100);
    cout << p1++ << endl;
    return 0;
}
           

关系运算符重载!= 、==

1)!=重载

#include<iostream>
#include<string>
using namespace std;
class Person{
    public:
    int m_age;
    int m_money;
    Person(int a = 0,int b = 0):m_age(a),m_money(b){

    }
    bool operator!=(Person& p1){
        if(this->m_age != p1.m_age || this->m_money != p1.m_money){
            return true;
        }
        return false;
    }
    //关系运算符的返回值是布尔值
};
ostream& operator<<(ostream &cout,Person &p){
    cout << "age : " << p.m_age << endl;
    cout << "money : " << p.m_money << endl;
    return cout;
}
int main(void){
    Person p1(10,100);
    Person p2(10,100);
    if(p1 != p2){
        cout <<" p1 and p2 aren't equal." << endl;
    }
    else cout << "p1 and p2 are equal." << endl;
    return 0;
}

           

2)==运算符

#include<iostream>
#include<string>
using namespace std;
class Person{
    public:
    int m_age;
    int m_money;
    Person(int a = 0,int b = 0):m_age(a),m_money(b){
    }
    bool operator==(Person& p2){//可以传递引用吗?
        if(this->m_age == p2.m_age && this->m_money == p2.m_money)
        return true;
        else return false;
    }
};
ostream& operator<<(ostream &cout,Person &p){
    cout << "age : " << p.m_age << endl;
    cout << "money : " << p.m_money << endl;
    return cout;
}
int main(void){
    Person p1(10,100);
    Person p2(10,100);
    if(p1 == p2){
        cout <<" p1 and p2 are equal." << endl;
    }
    else cout << "p1 and p2 aren't equal." << endl;
    return 0;
}
           

函数调用运算符重载

#include<iostream>
#include<string>
using namespace std;
class Person{
    public:
    int m_age;
    int m_money;
    Person(int a = 0,int b = 0):m_age(a),m_money(b){
    }
    void operator()(Person p1){
        cout << "age :" << p1.m_age << endl;
        cout << " money :" << p1.m_money << endl;
    }
};
ostream& operator<<(ostream &cout,Person &p){
    cout << "age : " << p.m_age << endl;
    cout << "money : " << p.m_money << endl;
    return cout;
}
int main(void){
    Person p1(13,100);
    Person p3;
    //不是写成Person(p3),不是类重载函数调用运算符进行隐式调用,而是类的实例进行函数调用
    p3(p1);
    //通过匿名函数对象进行操作符重载的调用
    Person()(p1);
    return 0;
}
           

继续阅读