本文主要講解運算符重載,由于白鳯大佬沒有具體講解,所以本文自行補充了運算符重載的相關知識
目錄
文章目錄
前言
運算符重載
加號運算符重載
左移運算符重載
遞增運算符重載?
總結
前言
本文主要對于運算符重載進行探討,分別對于成員函數重載和全局函數重載(友元函數重載)進行討論。
運算符重載
運算符重載是C++中的一項強大功能,它允許您為自定義的類或結構體定義特定的行為,以響應與內置類型相似的操作符。通過重載運算符,您可以實現自定義類型之間的數學運算、比較、位操作等。
運算符重載使用operator
關鍵字后跟要重載的運算符來實現。例如,+
表示加法運算符,-
表示減法運算符等。
運算符重載一般分為成員函數重載和全局函數重載
以下是一些常見的需要進行運算符重載的情況:
- 算術運算符:例如?
+
,?-
,?*
,?/
,?%
- 比較運算符:例如?
==
,?!=
,?<
,?>
,?<=
,?>=
- 賦值運算符:例如?
=
,?+=
,?-=
,?*=
,?/=
- 位操作運算符:例如?
&
,?|
,?^
- 下標操作符:
[]
- 函數調用操作符:
()
對于每個需要進行重載的運算符,您可以根據需求定義適當的成員函數或非成員函數。成員函數形式在對象本身上調用該操作,而非成員函數形式將兩個對象作為參數傳遞。
請注意,在進行運算符重載時,請遵循一些最佳實踐和規則:
- 不要改變原始對象的狀態(如果不是必要的)。
- 避免創建歧義或混亂的重載操作。
- 考慮使用友元函數來實現某些運算符重載,以便訪問私有成員。
運算符重載是C++語言中的一項強大功能,可以提高代碼的可讀性和表達能力。
加號運算符重載
加號運算符(+
)可以在C++中進行重載,使其適用于自定義類型的對象。要重載加號運算符,您可以使用成員函數或非成員函數的形式。
成員函數形式:本質為 p3 = p1.operator+(p2)
class MyClass {
public:MyClass operator+(MyClass& other) {// 在這里實現加法操作,并返回結果}
};
#include <iostream>class Complex {
private:double real;double imag;public:Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}Complex operator+(const Complex& other) const {return Complex(real + other.real, imag + other.imag);}void display() const {std::cout << "(" << real << " + " << imag << "i)" << std::endl;}
};int main() {Complex c1(2.5, 3.7);Complex c2(1.8, -2.9);Complex sum = c1 + c2; // 使用重載的加號運算符sum.display(); // 輸出:(4.3 + 0.8i)return 0;
}
全局函數形式:(友元函數訪問私有成員)本質為 p3 = operator+(p1,p2)
class MyClass {
public:};MyClass operator+(const MyClass& obj1, const MyClass& obj2) {// 在這里實現加法操作,并返回結果}
#include <iostream>class Complex {
private:double real;double imag;public:Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}// 聲明友元函數以便訪問私有成員friend Complex operator+(const Complex& c1, const Complex& c2);void display() const {std::cout << "(" << real << " + " << imag << "i)" << std::endl;}
};Complex operator+(const Complex& c1, const Complex& c2) {return Complex(c1.real + c2.real, c1.imag + c2.imag);
}int main() {Complex c1(2.5, 3.7);Complex c2(1.8, -2.9);Complex sum = c1 + c2; // 使用重載的加號運算符sum.display(); // 輸出:(4.3 + 0.8i)return 0;
}
倆個代碼實現內容一樣,主要一個是成員函數,一個全局函數,全局函數需要成為友元函數來訪問類的私有數據成員。?
同時運算符重載也可以發生函數重載?
左移運算符重載
如果我們有一個person類,建立一個對象p,當我們想直接使用cout<<p<<endl;來輸出對象p中的內容似乎并不能直接實現,C++并不認識這個類,也不知道如何輸出。
這里我們就可以使用左移運算符重載了,與上面的加號運算符一樣,左移運算符同樣是以operato<<形式實現的,這里我們仍然可以分為成員函數重載和全局函數重載來分別實現一下。
當我們按照成員函數來寫時,就會發現一個問題,首先你不能給自己傳入p,即p.operator<<(p),然后我們再使用p.operator<<(cout),而這樣簡化的版本就是p<<cout,與我們想要的cout<<p相反了,所以我們不使用成員函數來實現左移運算符,而使用全局函數。
void operator<<(cout)
{
//簡化完事 p << cout
}
?如果用全局函數首先要知道的事,cout是輸出流對象,即ostream對象
使用operator<<(ostream &cout,person &p)進行函數重載,簡化完事cout<<p
至于為什么不用void空值,而是ostream &,是因為,當你主函數使用函數重載輸出后,如果返回的事空值,就不能繼續追加輸出,例如<<endl;補上換行,因為cout后面一直能連續使用<<是鏈式編程,需要返回的還是cout,即返回ostream輸出流。
class preson
{
private:
string p_name;
int p_age;
public:
friend ostream & operator<<(ostream &cout,person &p);
}
ostream & operator<<(ostream &cout,person &p)
{cout<<"p_name"<<p.p_name<<"p_age"<<p._age<<endl;
}
遞增運算符重載?
遞增運算符重載,即要對++進行運算符重載
跟C++中的++a,a++一樣,遞增運算符重載也要分為前置遞增和后置遞增的重載
解決下述代碼中幾個重點問題
1、函數重載的返回類型就是自己建立的Integer類型是因為,如果有個對象num,當你想要實現對num++或者++num直接輸出,類似于a=1;cout<<a++<<endl;的操作時,你需要返回Integer類型,否則返回空值是沒有輸出的
2、為什么前置遞增返回值類型引用了,而后置遞增返回值類型沒有引用。
后置傳遞如果使用引用,那么值就錯了,要返回遞增前的值
這個主要是了解++運算符實現的本質
a=1;cout<<++(++a)<<endl;? 這個是對的,說明前置運算符計算本質是引用,對一個數修改
cout<<(a++)++<<endl;? 這個是錯的,說明后置運算符計算本質是值傳遞,無法二次修改
3、下述代碼偷懶了,應該演示一下++num,num++的輸出,而不是使用成員函數getValue來實現,其實只要將左移運算符重載一下就可以了,按照已講過的方法實現即可?
#include <iostream>
using namespace std;class Integer {
private:int value;
public:Integer(int val) : value(val) {}// 前置遞增運算符重載Integer& operator++() {++value;return *this;}// 后置遞增運算符重載Integer operator++(int) {Integer temp(value);++value;return temp;}int getValue() const {return value;}
};int main() {Integer num1(5);cout << "初始值: " << num1.getValue() << endl;// 前置遞增++num1;cout << "前置遞增后的值: " << num1.getValue() << endl;// 后置遞增Integer num2 = num1++;cout << "后置遞增后的值: " << num2.getValue() << endl;cout << "num1當前的值: " << num1.getValue() << endl;return 0;
}
總結
本文主要對運算符重載進行了探討,主要講述了運算符重載分為成員函數重載和全局函數重載(友元函數重載)這樣的操作,并舉例加號,左移以及遞增運算符的重載方法和一些注意事項。
通過上述的講解,可以實現更多的運算法重載的方法,當然還有很多運算符重載值得我們探討,本文講述的內容也比較有限。
推薦學習博客?https://xxetb.xetslk.com/s/4GgGz6