C++第4章 (運算子的過載)
一,過載方法
運算子的過載實質是函式的過載
雙目運算子 過載為友元,單目運算子過載為 成員函式
一般格式
函式型別 operator運算子名稱(形參表)
{ 對運算子的過載處理 }
operator是關鍵字
例過載 + 號
#include <iostream> using namespace std; class Complex{ public: Complex(); Complex(double, double); Complex operator+(Complex &); void display(); private: double real; double imag; }; Complex::Complex(){ real = 0; imag = 0; } Complex :: Complex(double r, double i){ real = r; imag = i; } Complex Complex::operator+(Complex &c2) { Complex c; c.real = real + c2.real; c.imag = imag + c2.imag; return c; } void Complex::display(){ cout << "( " << real << " , " << imag << " )" << endl; } int main (){ Complex c1(3, 4), c2(5, -10), c3; c3 = c1 + c2; cout << "c1 = "; c1.display(); cout << "c2 = "; c2.display(); cout << "c1 + c2 = "; c3.display(); return 0; }
簡單寫法
Complex Complex :: operator+(Complex &c2){
return Complex(real + c2.real, imag + c2.imag);
}
相當於
c1.operator + (c2);
如果寫為
c3 = 3 + c2; //錯誤
c3 = Complex(3, 0) + c2; //正確
二,運算子過載規則
(1)C++不語序使用者自己定義新的運算子,只能對已有的C++運算子進行過載
(2)不能過載的運算子只有 5 個
. | (成員訪問運算子) |
* | (成員指標訪問運算子) |
:: | (域運算子) |
sizeof | (長度運算子) |
?: | (條件運算子) |
(3)過載不能改變運算子運算物件(即運算元)的個數(雙目運算子 單目運算子)
(4)過載不能改變運算子的優先級別。
(5)過載不能改變運算子的結合性(如 = 的左右)
(6)過載運算子的函式不能有預設的引數。
(7)過載運算子必須和使用者定義的定義型別物件一起使用,其引數至少應該有一個是類物件。
int operator+(int a, int b){ return (a - b); //錯誤 } //實際上是可以的 但是 這樣不遵守規則
但是可以寫複數和常數相加
Complex Complex :: operator+(double a){ //成員函式,類內宣告類外定於
return Complex(real + a, imag);
}
Complex :: operator+(double a, Complex &c2){ //只能為友元函式
return Complex(c2.real + a, c2.imag);
}
(8)= 和 & 不用過載
(9)> 可以過載為 小於 但是 這樣違背了運算子過載的初衷,並且容易混淆
三,運算過載函式作為類成員和友元函式
兩種處理方式
(1)把運算過載函式作為類的成員函式
(2)運算子過載函式可以不是類的成員函式(普通函式),在類中把它宣告為友元函式。
class Complex{
public:
Complex();
Complex(double, double);
friend Complex operator+(Complex &, Complex &);
void display();
private:
double real;
double imag;
};
Complex operator+(Complex &c1, Complex &c2)
{
Complex c
c.real = c1.real + c2.real;
c.imag = c1.imag + c2.imag;
return c;
}
相當於
operator + ( c1, c2 );
class Complex{
public:
Complex();
Complex(double, double);
friend Complex operator + (Complex &, Complex &);
friend Complex operator + (Complex &, double);
friend Complex operator + (double , Complex &);
void display();
private:
double real;
double imag;
};
Complex::Complex(){
real = 0;
imag = 0;
}
Complex :: Complex(double r, double i){
real = r;
imag = i;
}
Complex operator + (Complex &c1, Complex &c2)
{
Complex c;
c.real = c1.real + c2.real;
c.imag = c1.imag + c2.imag;
return c1;
}
Complex operator + (Complex &c1, double a){
return Complex(c1.real + a, c1.imag);
}
Complex operator + (double a, Complex &c1){
return Complex(c1.real + a, c1.imag);
}
(1)C++規定,賦值運算子=, 下標運算子 [ ],函式呼叫運算子 (),成員運算子 ->,必須作為成員函式
(2)插入流 << 和提取運算子 >> ,型別轉換運算子不能定義為類的成員函式。只能作為友元函式。
(3)一般將單目運算子和符合運算子(+= ,-= ,/=,*=,&=,!=,'=,%=,%=,>>=,<<=)過載為成員運算子
(4)一般雙目運算子過載為友元函式
四,過載雙目運算子
== < >
#include<iostream>
#include<cstring>
using namespace std;
class String {
public :
String (){ p = NULL; }
String (char *str);
friend bool operator > (String &, String &);
friend bool operator < (String &, String &);
friend bool operator == (String &, String &);
void display();
private :
char *p;
};
String :: String (char *str){
p = str;
}
void String :: display(){
cout << p;
}
bool operator > (String &str1, String &str2){
if(strcmp ( str1.p, str2.p ) > 0)
return true;
else
return false;
}
bool operator < (String &str1, String &str2){
if(strcmp ( str1.p, str2.p ) < 0)
return true;
else
return false;
}
bool operator == (String &str1, String &str2){
if(strcmp ( str1.p, str2.p ) == 0)
return true;
else
return false;
}
void compare (String &str1, String &str2){
if(str1 > str2){
str1.display();
cout << " > " ;
str2.display();
}
else if(str1 < str2){
str1.display();
cout << " < " ;
str2.display();
}
else
{
str1.display();
cout << " = " ;
str2.display();
}
}
int main (){
String str1("Hello"), str2("the word"), str3("Computer");
String str4("What!");
compare(str1, str2);
return 0;
}
五,過載單目運算子
++ -- +=
++i 和 i++
#include<iostream>
using namespace std;
class Time{
public :
Time () ;
Time (int , int) ;
Time operator++(); //前置:++ 運算子 ++i
Time operator++(int); //後置 ++ 運算子 i++
void display();
private :
int minute;
int sec;
};
Time::Time(){
minute = 0;
sec = 0;
}
Time :: Time (int m, int s){
minute = m;
sec = s;
}
Time Time:: operator ++ (){
if(++sec >= 60){
sec -= 60;
++minute;
}
return *this;
}
Time Time::operator ++(int){
Time temp(*this);
sec ++;
if(sec >= 60){
sec -= 60;
++minute;
}
return temp;
}
void Time::display(){
cout << minute << ": " << sec << endl;
}
int main()
{
Time t1(30, 59);
t1 ++;
t1.display();
Time t2 ;
t2 = t1 ++;
t2.display();
t1.display();
return 0;
}
六,過載輸入流和輸出流 << >>
istream & operator >> ( istream &, 自定義類 &)
ostream & operator << ( ostream &, 自定義類 & )
<<有兩個引數,一個是輸出流物件(我們常用的cout),還有就是要輸出的東西。
例如:cout<<"haha";
也就是說<<的第一個引數必須是輸出流物件。
在成員函式裡實現<<過載,我們知道this會作為第一個引數,而這是不符合要求的。
>>類似!
所以我們過載 " >> " 和 " << " 的函式只能作為友元函式,而不能將它們定義為成員函式。
#include <iostream>
using namespace std;
class Complex{
public :
Complex ();
Complex (double ,double);
Complex operator +(Complex &);
friend ostream &operator << (ostream &, Complex &);
private :
double real;
double imag;
};
Complex:: Complex(){
real = 0;
imag = 0;
}
Complex :: Complex (double r, double i){
real = r;
imag = i;
}
Complex Complex::operator +(Complex &c2){
return Complex (real + c2.real, imag + c2.imag);
}
ostream &operator <<(ostream &cout, Complex &c){
cout << "( " << c.real << " , " << c.imag << " )" << endl;
return cout;
}
int main (){
Complex c1(2, 4), c2 (3, 6), c3;
c3 = c1 + c2;
cout << c3 ;
return 0;
}
operator << ( cout , c3 );
#include<iostream>
using namespace std;
class Complex{
public :
friend ostream& operator <<(ostream &, Complex &);
friend istream& operator >>(istream &, Complex &);
private :
double real;
double imag;
};
ostream &operator << (ostream &cout, Complex &c){
cout << "( " << c.real << " ";
if(c.imag >= 0)
cout << "+";
cout << " " << c.imag << "i )" << endl;
return cout;
}
istream &operator >> (istream &cin, Complex &c){
cout << "Please cin the real and imag : ";
cin >> c.real >> c.imag;
return cin;
}
int main(){
Complex c1, c2;
cin >> c1 >> c2;
cout << c1 << c2;
return 0;
}