C++——運算子過載

孢芝發表於2020-10-22

運算子過載

運算子作用

對已有的運算子重新進行定義,賦予其另一種功能,以適應不容的資料型別

運算子過載需要注意

  • 對於內建的資料型別的表示式的運算子是不可能改變的
  • 不要濫用運算子過載

過載’+'運算子

方法

  1. 成員函式過載’+'
    //成員函式實現 + 號運算子過載
    Person operator+(const Person& p) {
        Person temp;
        temp.m_A = this->m_A + p.m_A;
        temp.m_B = this->m_B + p.m_B;
        return temp;
    }

實現
    //成員函式過載本質呼叫
    Person p3 = p1.operator+(p2);
    //簡化呼叫
    Person p3 = p1+p2;
  1. 全域性函式過載’+'
//全域性函式實現+號運算子過載
Person operator+(const Person& p1, const Person& p2) {
    Person temp(0, 0);
    temp.m_A = p1.m_A + p2.m_A;
    temp.m_B = p1.m_B + p2.m_B;
    return temp;
}

實現
    //全域性函式過載本質呼叫
    Person p3 = operator+(p1,p2);
    //簡化呼叫
    Person p3 = p1+p2;

運算子過載也可以發生函式過載
//全域性函式實現+號運算子過載
Person operator+(const Person& p2, int val)  
{
    Person temp;
    temp.m_A = p2.m_A + val;
    temp.m_B = p2.m_B + val;
    return temp;
}
實現
    Person p3 = p1 + 100;

<<左移運算子過載

  • 過載<<左移運算子配合友元可以實現輸出自定義的資料型別
  • 成員函式不可以用來過載左移<<運算子,因為無法實現cout在左側

示例程式碼

#include <iostream>
#include <string>
using namespace std;
class Person {
       friend Person operator + (const Person& p1, const Person& p2);
       friend ostream & operator << (ostream & cout, const Person& p);
public:
       Person() {}
       Person(string name,int age,int tech) {
              this->m_Name = name;
              this->m_Age = age;
              this->m_Techology = tech;
       }
       void Print() {
              cout << "Name:" << this->m_Name << endl;
              cout << "Age:" << this->m_Age << endl;
              cout << "Techology:" << this->m_Techology << endl;
       }
private:
       string m_Name;
       int m_Age;
       int m_Techology;
};
Person operator + (const Person& p1, const Person& p2) {
       Person tmp;
       tmp.m_Name = "baby";
       tmp.m_Age = p1.m_Age + p2.m_Age;
       tmp.m_Techology = p1.m_Techology + p2.m_Techology;
       return tmp;
}
ostream & operator << (ostream& cout, const Person &p) {
       cout << "Name:" << p.m_Name << endl;
       cout << "Age:" << p.m_Age << endl;
       cout << "Techology:" << p.m_Techology << endl;
       return cout;
}
int main()
{
       Person p1("ZXW", 18, 100);
       Person p2 = Person("HHK",21,100);
       Person p3 = p1 + p2;
       p1.Print();
       p2.Print();
       p3.Print();
       cout << endl;
       cout << p1 << p2 << p3;
       return 0;
}

輸出

Name:ZXW
Age:18
Techology:100
Name:HHK
Age:21
Techology:100
Name:baby
Age:39
Techology:200


Name:ZXW
Age:18
Techology:100
Name:HHK
Age:21
Techology:100
Name:baby
Age:39
Techology:200

++遞增運算子過載

作用:通過過載遞增運算子,實現自己的整形資料

過載前置++運算子

//前置++遞增運算子
Myint& operator++() {
    this->m_Value++;
    return *this;
}
返回的一定是引用,因為++(++x)可以疊加,體現了鏈式程式設計思想

過載後置++運算子

//後置++遞增運算子
Myint operator++(int) {
    Myint tmp = *this;
    this->m_Value++;
    return tmp;
}
返回的一定是值,因為(x++)++語法是錯誤的,沒有采用鏈式程式設計思想

示例程式碼

#include <iostream>
using namespace std;

class Myint {
	friend ostream& operator<<(ostream& out, const Myint& myint);
public:
	Myint() {}
	Myint(int x) {
		this->m_Value = x;
	}
	//前置++遞增運算子
	Myint& operator++() {
		this->m_Value++;
		return *this;
	}
	//後置++遞增運算子
	Myint operator++(int) {
		Myint tmp = *this;
		this->m_Value++;
		return tmp;
	}
private:
	int m_Value;
};

ostream& operator<<(ostream& out, const Myint& myint) {
	cout << myint.m_Value << endl;
	return cout;
}

int main()
{
	Myint myint1(10);
	cout << ++(++myint1) << endl;
	cout << myint1++ << endl;
	cout << myint1 << endl;
	return 0;
}

輸出

12

12

13

=運算子過載

C++編譯器至少給一個類新增4個函式

  • 預設建構函式(無參,函式體為空)
  • 預設解構函式(無參,函式體為空)
  • 預設拷貝建構函式,對屬性值進行值拷貝
  • 賦值運算子operator=,屬性進行值拷貝(編譯器提供的是淺拷貝)
如果類中有屬性指向堆區,做賦值操作時也會出現深淺拷貝問題
(淺拷貝會引發堆區記憶體重複釋放,程式進而崩潰,需要用深拷貝來解決)

關係運算子過載

作用:過載關係運算子,可以讓兩個自定義型別對你選哪個進行對比操作

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

函式呼叫運算子

  • 函式呼叫運算子過載後的使用方式非常像函式的呼叫,所以稱為仿函式
  • 仿函式沒有固定的寫法,非常靈活
  • STL庫中用到了大量的仿函式

示例程式

class{

    int operator()(int x,int y){
        return x+y;
    }
}

main(){

    類名 add;
    cout<<add(100,100)<<endl;
}

輸出

200

匿名函式物件

cout<<add()(100,100)<<endl;

add()是一個匿名物件
add()(100,100)是一個匿名函式物件

輸出

200

相關文章