天天看點

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;
}
           

繼續閱讀