C++ 運算符重載

  • C++中幾乎可以重載全部的運算符,而且只能重載C++中已經有的。不能重載的運算符:“. ”、“.*”、“::”、“?.”;
  • 重載之後運算符的優先級和結合性都不會改變;
  • 運算符重載是針對新類型的實際需要,對原有運算符進行適當的改造;
  • 例如:使用複數類的對象可以用“+”運算符實現加法,是時鐘類對象可以用“++”運算符實現時間增加1秒。

1. 運算符重載爲成員函數

   1.1 雙目運算符重載爲類的成員函數

 重載爲類成員的運算符函數定義形式:

函數類型  operator 運算符(形參)
{
   ...
}
參數個數=原操作數個數-1  (後置++,--除外)

雙目運算符重載規則:

  • 如果要實現重載B爲類成員函數,使之能夠實現表達式oprd1 B oprd2,其中oprd1爲A類對象,則B應被重載爲A類的成員函數,形參類型應該爲oprd2所屬的類型。
  • 經重載後,表達式oprd1 B oprd2 相當於oprd1.operator B(oprd2)

例:複數類加減法運算符重載爲成員函數:

/*
//要求:將+、-重載爲複數類的成員函數
//規則:實部和虛部分別相加減
//操作數:兩個操作數都是複數類的對象
*/

#include<iostream>
using namespace std;

class Complex{
public:
	Complex(double r = 0.0, double i = 0.0)
	{
		real = r;
		image = i;
	}
	//運算符+重載成員函數
	Complex operator +(const Complex &c2) const;
	//運算符+重載成員函數
	Complex operator -(const Complex &c2) const;
	void display() const;    //輸出複數
private:
	double real;
	double image;
};

Complex Complex::operator+(const Complex &c2) const
{
	//創建一個臨時無名對象作爲返回值
	return Complex(real + c2.real, image + c2.image);
}

Complex Complex::operator-(const Complex &c2) const
{
	//創建一個臨時無名對象作爲返回值
	return Complex(real - c2.real, image - c2.image);
}

void Complex::display() const
{
	cout << "(" << real << "," << image << ")" << endl;
}

int main()
{
	Complex c1(5, 4), c2(2, 10), c3;
	cout << "c1 = ";
	c1.display();
	cout << "c2 = ";
	c2.display();
	c3 = c1 - c2;
	cout << "c3 = c1 - c2 = ";
	c3.display();
	c3 = c1 + c2;
	cout << "c3 = c1 + c2 = ";
	c3.display();

	system("pause");
	return 0;
}

1.2 單目運算符重載爲成員函數

前置單目運算符重載規則:

  • 如果要重載U爲類成員函數,使之能夠實現表達式U oprd,其中oprd爲A類對象,則U應被重載爲A類的成員函數,無形參;
  • 經重載後,表達式U oprd相當於oprd.operator U();

後置單目運算符++和--重載規則:

  • 如果要重載++或者--爲類成員函數,使之能夠實現表達式oprd++或者oprd--,其中oprd爲A類對象,則++或--應被重載爲A類的成員函數,且具有一個int類型形參;
  • 經重載後,表達式oprd++相當於oprd.operator ++(0)

例:重載前置++和後置++爲時鐘類成員函數

  • 前置單目運算符,重載函數沒有形參
  • 後置++運算符,重載函數需要一個int形參
  • 操作數是時鐘類的對象
  • 實現時間增加1秒鐘
#include<iostream>
using namespace std;

class Clock{
public:
	Clock(int hour = 0, int minute = 0, int second = 0);
	void showTime() const;
	//前置單目運算符重載
	Clock & operator ++();
	//後置單目運算符重載
	Clock operator ++(int);
private:
	int hour, minute, 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;
}

void Clock::showTime() const
{
	cout << hour << ":" << minute << ":" << second << endl;
}

Clock &Clock::operator++()
{
	second++;
	if (second >= 60)
	{
		second -= 60;
		minute++;
		if (minute >= 60)
		{
			minute -= 60;
			hour = (hour + 1) % 24;
		}
	}
	return *this;
}

Clock Clock::operator++(int)
{
	//注意形參表中的整型參數
	Clock old = *this;
	++(*this);   //調用前置"++"運算符
	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();

	system("pause");
	return 0;
}

2.  運算符重載爲非成員函數

運算符要重載爲非成員函數的規則:

  • 函數的形參代表依自左向右次序排列的各操作數。
  • 重載爲非成員函數時,參數個數=原操作數個數(後置++,--除外),至少應該有一個自定義類型的參數。
  • 後置單目運算符++和--的重載函數,形參列表重要增加一個int,但不必寫形參名。
  • 如果在運算符的重載函數中需要操作某類對象的私有成員,可以將此函數聲明爲該類的友元。

運算符重載爲非成員函數的規則

  • 雙目運算符B重載後,表達式 oprd1 B oprd2  等同於operator B(oprd1,oprd2)
  • 前置單目運算符B重載後,表達式B oprd等同於operator B(oprd)
  • 後置單目運算符++和--重載後,表達式oprd B等同於operator B(oprd,0)

例:重載Complex的加減法和“<<”運算符爲非成員函數

(1)將+、-(雙目)重載爲非成員函數,並將其聲明爲複數類的友元,兩個操作數都是複數類的常引用。

(2)將<<(雙目)重載爲非成員函數,並將其聲明爲複數類的友元,它的左操作數是std::ostream引用,右操作數爲複數類的常引用,返回std::ostream引用,用以支持下面形式的輸出:

cout<<a<<b;

該輸出調用的是:

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

#include<iostream>
using namespace std;

class Complex
{
public:
	Complex(double r = 0.0, double i = 0.0)
	{
		real = r;
		image = i;
	}
	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 image;
};
Complex operator+(const Complex &c1, const Complex &c2)
{
	return Complex(c1.real + c2.real, c1.image + c2.image);
}
Complex operator-(const Complex &c1, const Complex &c2)
{
	return Complex(c1.real - c2.real, c1.image - c2.image);
}
ostream & operator<<(ostream &out, const Complex &c)
{
	out << "(" << c.real << "," << c.image << ")";
	return out;
}

int main()
{
	Complex c1(5, 4), c2(2, 10), c3;
	cout << "c1 = " << c1 << endl;
	cout << "c2 = " << c2 << endl;
	c3 = c1 - c2;
	cout << "c3 = c1 - c2 = " << c3 << endl;
	c3 = c1 + c2;
	cout << "c3 = c1 + c2 = " << c3 << endl;
	system("pause");
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章