" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言運算符的重載詳解

 更新時間:2022年02月24日 09:12:43   作者:PingBryant  
這篇文章主要為大家詳細介紹C語言運算符的重載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

運算符重載的規(guī)則 

  • 思考:用“+”、“-”能夠?qū)崿F(xiàn)復數(shù)的加減運算嗎?
  • 實現(xiàn)復數(shù)加減運算的方法:

             ——重載“+”、“-”運算符

  • 運算符重載是對已有的運算符賦予多重含義,使同一個運算符作用于不同類型的數(shù)據(jù)時導致不同的行為。
  • C++ 幾乎可以重載全部的運算符,而且只能夠重載C++中已經(jīng)有的。

                不能重載的運算符:“.”、“.*”、“::”、“?:”

  • 重載之后運算符的優(yōu)先級和結(jié)合性都不會改變。
  • 運算符重載是針對新類型數(shù)據(jù)的實際需要,對原有運算符進行適當?shù)母脑?。例如?                

                使復數(shù)類的對象可以用“+”運算符實現(xiàn)加法;

                使時鐘類對象可以用“++”運算符實現(xiàn)時間增加1秒。

  • 重載為類的非靜態(tài)成員函數(shù);
  • 重載為非成員函數(shù)。 

1. 運算符重載為成員函數(shù)

重載為類成員的運算符函數(shù)定義形式:

函數(shù)類型 operator 運算符(形參)

{

......

}

參數(shù)個數(shù)=原操作數(shù)個數(shù)-1 (后置++、--除外) 

雙目運算符重載規(guī)則 

  • 如果要重載 B 為類成員函數(shù),使之能夠?qū)崿F(xiàn)表達式 oprd1 B oprd2,其中 oprd1 為A 類對象,則 B 應(yīng)被重載為 A 類的成員函數(shù),形參類型應(yīng)該是 oprd2 所屬的類型。
  • 經(jīng)重載后,表達式 oprd1 B oprd2 相當于 oprd1.operator B(oprd2) 。 

例1 復數(shù)類加減法運算重載為成員函數(shù)

要求:將+、-運算重載為復數(shù)類的成員函數(shù)。

規(guī)則:實部和虛部分別相加減。

操作數(shù):兩個操作數(shù)都是復數(shù)類的對象。

#include<iostream>
using namespace std;
//定義復數(shù)類
class Complex
{ 
	public:
		Complex(double x=0.0, double y=0.0);  //構(gòu)造函數(shù)
		Complex(const Complex &c);  //復制構(gòu)造函數(shù) 
		~Complex();  //析構(gòu)函數(shù)
		void display() const;  //復數(shù)打印函數(shù)
		Complex operator +(const Complex &c) const;  //加法運算符重載
		Complex operator -(const Complex &c) const;  //減法運算符重載 
	private:
		double real;  //實部
		double imag;  //虛部 
}; 
Complex::Complex(double x, double y): real(x), imag(y){}
Complex::~Complex(){}
Complex::Complex(const Complex &c): real(c.real), imag(c.imag){}
void Complex::display() const
{
	cout<<"("<<real<<", "<<imag<<")"<<endl;	
}
Complex Complex::operator +(const Complex &c) const
{
	Complex temp;
	temp.real = real + c.real;
	temp.imag = imag + c.imag;
	return temp;
	/*或者創(chuàng)建一個臨時無名對象作為返回值*/
	//return Complex(real+c.real, imag+c.imag); 
}
Complex Complex::operator -(const Complex &c) const
{
	Complex temp;
	temp.real = real - c.real;
	temp.imag = imag - c.imag;
	return temp;
}
int main()
{
	Complex c1(6.7, 4.4);
	Complex c2(3.2, 1.7);
	cout<<"c1 = ";
	c1.display();
	cout<<endl;
	cout<<"c2 = ";
	c2.display();
	cout<<endl;
	Complex c3, c4;
	c3 = c1 + c2;
	c4 = c1 - c2;
	cout<<"c1 + c2 = ";
	c3.display();
	cout<<endl;
	cout<<"c1 - c2 = ";
	c4.display();
	cout<<endl;
	return 0;
} 

運行結(jié)果:

c1 = (6.7, 4.4)
c2 = (3.2, 1.7)
c1 + c2 = (9.9, 6.1)
c1 - c2 = (3.5, 2.7)

前置單目運算符++和--重載規(guī)則 

  • 如果要重載 U 為類成員函數(shù),使之能夠?qū)崿F(xiàn)表達式 U oprd,其中 oprd 為A類對象,則 U 應(yīng)被重載為 A 類的成員函數(shù),無形參。
  • 經(jīng)重載后,表達式 U oprd 相當于 oprd.operator U()。 

后置單目運算符++和--重載規(guī)則 

  • 如果要重載 ++或--為類成員函數(shù),使之能夠?qū)崿F(xiàn)表達式 oprd++ 或 oprd-- ,其中 oprd 為A類對象,則 ++或-- 應(yīng)被重載為 A 類的成員函數(shù),且具有一個 int 類型形參。
  • 經(jīng)重載后,表達式 oprd++ 相當于 oprd.operator ++(0)。 

例2 重載前置++和后置++為時鐘類成員函數(shù)

前置單目運算符,重載函數(shù)沒有形參。         

后置++運算符,重載函數(shù)需要有一個int形參。         

操作數(shù)是時鐘類的對象。         

實現(xiàn)時間增加1秒鐘。

#include<iostream>
using namespace std;
class Clock
{
	public:
		Clock(int hour=0, int minute=0, int second=0);
		~Clock();
		void showTime() const;
		Clock& operator ++();  //前置單目運算符重載
		Clock operator ++(int);  //后置單目運算符重載 
	private:
		int hour;
		int minute;
		int second;
};
Clock::Clock(int hour, int minute, int second)
{
	if(0<=hour && hour<24 && 0<=minute && minute<60 && 0<=second && second<60)
	{
		this->hour = hour;
		this->minute = minute;
		this->second = second;
	}
	else
	{
		cout<<"Time error!"<<endl;
	}
}
Clock::~Clock(){}
void Clock::showTime() const
{
	cout<<hour<<":"<<minute<<":"<<second<<endl;
}
Clock& Clock::operator ++()  //函數(shù)返回值是對象的引用是為了更高效(減少臨時對象的生成)
{
	second++;
	if(second >= 60)
	{
		second %= 60;
		minute++;
		if(minute >= 60)
		{
			minute %= 60;
			hour = (hour + 1) % 24;
		}
	}
	return *this;
}
Clock Clock::operator ++(int)  //注意形參表中的整型參數(shù)
{
	Clock old = *this;
	++(*this);   //調(diào)用前置“++”運算符
	/*也可以寫具體: 
	second++;
	if(second >= 60)
	{
		second %= 60;
		minute++;
		if(minute >= 60)
		{
			minuet %= 60;
			hour = (hour + 1) % 24;
		}
	}
	*/
	return old; 
} 
int main()
{
	Clock myClock(23, 59, 59); 
 	cout << "First time output: "; 
 	myClock.showTime(); 
 	cout << "Show myClock++: "; 
 	(myClock++).showTime(); 
 	cout << "Show ++myClock: "; 
 	(++myClock).showTime();
	return 0;
}

運行結(jié)果:

First time output: 23:59:59
Show myClock++: 23:59:59
Show ++myClock: 0:0:1

2. 運算符重載為非成員函數(shù)          

有些運算符不能重載為成員函數(shù),例如二元運算符的左操作數(shù)不是對象,或者是不能由我們重載運算符的對象。 

運算符重載為非成員函數(shù)的規(guī)則 

  • 函數(shù)的形參代表依自左至右次序排列的各操作數(shù)。
  • 重載為非成員函數(shù)時:

                參數(shù)個數(shù)=原操作數(shù)個數(shù)(后置++、--除外)。

  • 至少應(yīng)該有一個自定義類型的參數(shù)。
  • 后置單目運算符++和--的重載函數(shù),形參列表中要增加一個int,但不必寫形參名。
  • 如果在運算符的重載函數(shù)中需要操作某類對象的私有成員,可以將此函數(shù)聲明為該類的友元。
  • 雙目運算符B重載后, 表達式oprd1 B oprd2等同于operator B(oprd1,oprd2)。
  • 前置單目運算符B重載后,表達式B oprd等同于operator B(oprd)。
  • 后置單目運算符++和--重載后,表達式oprd B等同于operator B(oprd,0)。

例3 重載 Complex 的加減法和“<<”運算符為非成員函數(shù)

  • 將+、‐(雙目)重載為非成員函數(shù),并將其聲明為復數(shù)類的友元,兩個操作數(shù)都是復數(shù)類的常引用(使用常引用,既保證程序執(zhí)行的高效率,又保護數(shù)據(jù)不被隨意篡改)。
  • 將<<(雙目)重載為非成員函數(shù),并將其聲明為復數(shù)類的友元,它的左操作數(shù)是std::ostream引用,右操作數(shù)為復數(shù)類的常引用,返回std::ostream引用,用以支持下面形式的輸出:        

 cout << a << b;

該輸出調(diào)用的是:         

operator << (operator << (cout, a), b);

#include<iostream>
using namespace std;
class Complex
{
	public:
		Complex(double x=0.0, double y=0.0);
		~Complex();
		friend Complex operator +(const Complex &c1, const Complex &c2);  //聲明為類的友元
		friend Complex operator -(const Complex &c1, const Complex &c2);
		friend ostream& operator <<(ostream &out, const Complex &c);
	private:
		double real;
		double imag;
};
Complex::Complex(double x, double y): real(x), imag(y){}
Complex::~Complex(){}
Complex operator +(const Complex &c1, const Complex &c2)
{
	Complex temp;
	temp.real = c1.real + c2.real;
	temp.imag = c1.imag + c2.imag; 
	return temp;
	/*或者創(chuàng)建一個臨時無名對象作為返回值*/
	//return Complex(c1.real+c2.real, c1.imag+c2.imag); 
} 
Complex operator -(const Complex &c1, const Complex &c2)
{
	return Complex(c1.real-c2.real, c1.imag-c2.imag);
}
ostream& operator <<(ostream& out, const Complex &c)
{
	out<<"("<<c.real<<", "<<c.imag<<")";
	return out;
}
/*若輸出為復數(shù)的標準形式:
在復數(shù)兩端加上括號,實部和虛部均保留兩位小數(shù),
如(8.23+2.00i)、(7.45-3.40i)*/
/*
ostream& operator <<(ostream& out, const Complex &c)
{
    if(c.imag>0)
        out<<setiosflags(ios::fixed)<<setprecision(2)<<"("<<c.real<<"+"<<c.imag<<"i)"<<endl;
    else
        out<<setiosflags(ios::fixed)<<setprecision(2)<<"("<<c.real<<c.imag<<"i)"<<endl;
    return out;
}
*/
int main()
{
	Complex c1(5, 4), c2(2, 10), c3; 
 	cout << "c1 = " << c1 << endl; 
 	cout << "c2 = " << c2 << endl; 
 	c3 = c1 - c2;   //使用重載運算符完成復數(shù)減法 
 	cout << "c3 = c1 - c2 = " << c3 << endl; 
 	c3 = c1 + c2;   //使用重載運算符完成復數(shù)加法 
 	cout << "c3 = c1 + c2 = " << c3 << endl;
	return 0;
}

運行結(jié)果:

c1 = (5, 4)
c2 = (2, 10)
c3 = c1 - c2 = (3, -6)
c3 = c1 + c2 = (7, 14)

類的友元函數(shù)重載插入運算符和重載提取運算符在調(diào)用時只需像平常cin >> xxx 或 cout << xxx即可,而類的成員函數(shù)重載插入運算符和重載提取運算符在調(diào)用時是要xxx >> cin 或 xxx << cout,剛好和平常的用法是相反的。而xxx >> cin相當于xxx.operator>>(cin);xxx << cout相當于xxx.operator<<(cout)。

用引用&,減少對象拷貝,增加速度和效率。插入和提取運算符,操作的對象是ostream和istream。如果不加&的話,程序也是沒問題的,可以運行。但是在每次調(diào)用<<操作的時候,都會產(chǎn)生一個新的臨時的ostream對象。包括對“=”運算符的重載也是一樣。“=”更能說明這個問題。一般來說是 xxx & opreator = (xxx a);就是因為我們希望對于a=b; 把b的值直接賦值給a就好了,用xxx &做返回類型,返回的是a的別名/引用,不會創(chuàng)建新的臨時對象。如果沒有&,那么會創(chuàng)建新的臨時值返回,低效。重點就是對引用&的使用的理解。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容! 

相關(guān)文章

最新評論