- 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;
}