首頁 > 軟體

C++過載運運算元你真的瞭解嗎

2022-03-27 16:00:07

運運算元實際上是一個函數,所以運運算元的過載實際上是函數的過載,。編譯程式對運運算元的過載的選擇,遵循函數過載的選擇原則。當遇到不很明顯的運算時,編譯程式會尋找與引數相匹配的運運算元函數。

1.過載運運算元的必要性

C++語言中的資料型別分為基本資料型別和構造資料型別。基本資料型別可以直接完成算術運算。例如:

#include<bits/stdc++.h>
using namespace std;
int main(void){
	int a=10;
	int b=20;
	cout<<a+b<<endl;
} 

程式中實現了兩個整型變數的相加,可以正確輸出執行結果30。通過兩個浮點變數、兩個雙精度變數都可以直接運用加法運運算元+來求和。但是類屬於新構造的資料型別,類的兩個物件就無法通過加法運運算元來求和。例如:

#include<bits/stdc++.h>
using namespace std;
class CBook{
	public:
		CBook(int iPage){
			m_iPage=iPage;
		}
		void display(){
			cout<<m_iPage<<endl;
		}
	protected:
		int m_iPage;
};
int main(void){
	CBook book1(10);
	CBook book2(20);
	tmp=book1+book2;//錯誤
	tmp.display(); 
}

當編譯器編譯到語句book1+book2時會報錯,因為編譯器不知道如何進行兩個物件的相加,要實現兩個類物件的加法運算有兩種方法,一種是通過成員函數,一種是通過過載運運算元。

首先看通過成員函數方法實現求和的例子:

#include<bits/stdc++.h>
using namespace std;
class CBook{
	public:
		CBook(int iPage){
			m_iPage=iPage;
		}
		int add(CBook a){
			return m_iPage+a.m_iPage;
		}
		void display(){
			cout<<m_iPage<<endl;
		}
	protected:
		int m_iPage;
};
int main(void){
	CBook book1(10);
	CBook book2(20);
	cout<<book1.add(book2)<<endl;
}

程式執行結果正確。使用成員函數實現求和的形式比較單一,並且不利於程式碼複用。如果要實現多個物件的累加其程式碼的可讀性會大大降低,使用過載運運算元的方法可以解決這些問題。

2.過載運運算元的形式與規則

過載運運算元的宣告形式如下:

operator型別名():

operator是需要過載的運運算元,整個語句沒有返回型別,因為型別名就代表了它的返回型別。過載運運算元將物件轉化成型別名規定的型別,轉換時的形式就像強制轉換一樣。但如果沒有過載運運算元定義,直接強制型別轉換會導致編譯器將無法通過編譯。

過載運運算元不可以是新建立的運運算元,只能是C++語言中已有的運運算元,可以過載的運運算元如下:

算術運運算元:+ - * / % ++ --

位元運算運運算元:& | ~ ^ >> <<

邏輯運運算元 ! && ||

比較運運算元 <  >  >=  <=  ==  !=

賦值運運算元 =   +=    -=    *=  /=  %=    &=  |=   ^=     <<=    >>=

其他運運算元: [ ]   ()   ->   ,    new    delete    new[]    delete[]        ->*

並不是所有的C++語言中已有的運運算元都可以過載,不允許過載的運運算元有 .  *  ::    ?和:

過載運運算元時不能改變運運算元運算元的個數,不能改變運運算元原有的優先順序,不能改變運運算元原有的結合性,不能改變運運算元原有的語法結構,即單目運運算元只能過載為單目運運算元,雙目運運算元只能過載為雙目運運算元,過載運運算元含義必須清楚,不能有二義性。

範例:通過過載運運算元實現求和:

#include<bits/stdc++.h>
using namespace std;
class CBook{
	public:
		CBook(int iPage){
			m_iPage=iPage;
		}
		CBook operator+(CBook b)
		{
			return CBook(m_iPage+b.m_iPage);
		}
		void display(){
			cout<<m_iPage<<endl;
		}
	protected:
		int m_iPage;
};
int main(void){
	CBook book1(10);
	CBook book2(20);
	CBook tmp(0);
	tmp=book1+book2;
	tmp.display();
}

類CBook過載了求和運運算元後,由它宣告的兩個物件book1和book2可以向兩個整型變數一樣相加。

3.過載運運算元的運算

過載運運算元後可以完成物件和物件之間的運算,同樣也可以通過過載運算實現物件和普通型別資料的運算。例如:

#include<bits/stdc++.h>
using namespace std;
class CBook{
	public:
		int m_Pages;
	void OutputPage(){
		cout<<m_Pages<<endl;
	}
	CBook(){
		m_Pages=0;
	}
	CBook operator+(const int page){
		CBook book;
		book.m_Pages=m_Pages+page;
		return book;
	}
};
int main(void){
	CBook Book1,Book2;
	Book2=Book1+10;
	Book2.OutputPage(); 
}

通過修改運運算元的引數為整數型別,可以實現CBook物件與整數相加。

對於兩個整型變數的相加,可以調換加數和被加數的順序,因為加法符合交換律。但是對於通過過載運運算元實現的加法,不可以交換順序。

illegal:

Book2=10+Book1;//非法程式碼

對於++和--運運算元,由於涉及前置運算和後置運算,在過載這類運運算元時如何區分呢?預設情況是,如果過載運運算元沒有引數則表示是前置運算,例如:

void operator++()//前置運算 
{
	++m_Pages;
}

如果過載運運算元使用了整數作為引數,則表示的是後置運算,此時的引數值可以被忽略,它只是一個標識,標識後置運算。

void operator++(int)//後置運算 
{
	++m_Pages;
}

預設情況下,將一個整數賦值給一個物件是非法的,可以通過過載運運算元將其變成合法的。例如:

void operator = (int page){//過載運運算元 
	m_Pages=page;
}

通過過載運運算元也可以實現將一個整型數複製給一個物件,例如:

#include<bits/stdc++.h>
using namespace std;
class CBook{
	public:
		int m_Pages;
		void OutputPages()
		{
			cout<<m_Pages<<endl;
		}
	CBook(int page){
		m_Pages=page;
	}
	operator = (const int page){
		m_Pages=page;
	}
}; 
int main(void){
	CBook mybook(0);
	mybook = 100;
	mybook.OutputPages();
}

程式中過載了賦值運運算元,給mybook物件賦值100,並通過OutpuName()函數將其進行輸出。

也可以通過過載建構函式將一個整數賦值給一個物件

#include<bits/stdc++.h>
using namespace std;
class CBook{
	public:
		int m_Pages;
		void OutputPages()
		{
			cout<<m_Pages<<endl;
		}
	CBook(){
	}
	CBook(int page){
		m_Pages=page;
	}
	
}; 
int main(void){
	CBook mybook;
	mybook = 100;
	mybook.OutputPages();
}

程式中定義了一個過載的建構函式,以一個整數作為函數引數,這就可以將一個整數賦值給一個CBook類的物件,語句mybook=100;將呼叫建構函式CBook(int page)重新構造一個CBook物件,並將其賦值給mybook物件。

4.跳脫運運算元

C++語言中普通的資料型別可以進行強制型別轉換,例如:

int i=10;
double d;
d = double(i)

程式中將整數i強制轉換為double型。

語句

d=double(i)//等同於d=double(i)

double()在C++語言中被轉化為轉換運運算元。通過過載轉換運運算元可以將類物件轉換為想要的資料。

範例:轉換運運算元

#include<bits/stdc++.h>
using namespace std;
class CBook{
	public:
		CBook(double iPage=0);
		operator double(){
			return m_iPage;
		}
	protected:
		int m_iPage;
}; 
CBook::CBook(double iPage){
	m_iPage = iPage;
}
int main(void){
	CBook book1(10.0);
	CBook book2(20.00);
	cout<<double(book1)+double(book2)<<endl;
}

程式過載了轉換運運算元double(),然後將類CBook的兩個物件強制轉換為double型別後再進行求和,最後輸出求和的結果。

總結

本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!     


IT145.com E-mail:sddin#qq.com