亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++教程:C++操作符的重載

2020-05-23 14:25:42
字體:
來源:轉載
供稿:網友
在表達式中,我們常會用到各種操作符(運算符),例如1+3和4*2。然而,這些操作符只能用于C++內置的一些基本數據類型。如果我們自己編寫一個復數類,它也會有加減法的操作,那么它能否擺脫一串冗長的函數名,而享用加號呢?

在第六章我們學到過,函數是可以重載的,即同名函數針對不同數據類型的參數實現類似的功能。在C++中,操作符也是可以重載的,同一操作符對于不同的自定義數據類型可以進行不同的操作。

作為成員函數

在我們學習操作符重載前,我們先看看原先這個復數類是如何定義的:(程序16.3.1)
//complex.h
#include <iostream>
using namespace std;
class Complex//聲明一個復數類
{
   public:
   Complex(Complex &a);//拷貝構造函數
   Complex(double r=0,double i=0);
   void display();//輸出復數的值
   void set(Complex &a);
   Complex plus(Complex a);//復數的加法
   Complex minus(Complex a); //復數的減法
   Complex plus(double r); //復數與實數相加
   Complex minus(double r); //復數與實數相減
   private:
   double real;//復數實部
   double img;//復數虛部
};
Complex::Complex(Complex &a)
{
   real=a.real;
   img=a.img;
}
Complex::Complex(double r,double i)
{
   real=r;
   img=i;
}
void Complex::display()
{
   cout <<real <<(img>=0?"+":"") <<img <<"i";//適合顯示1-3i等虛部為負值的復數
}
void Complex::set(Complex &a)
{
   real=a.real;
   img=a.img;
}
Complex Complex::plus(Complex a)
{
   Complex temp(a.real+real,a.img+img);
   return temp;
}
Complex Complex::minus(Complex a)
{
   Complex temp(real-a.real,img-a.img);
   return temp;
}
Complex Complex::plus(double r)
{
   Complex temp(real+r,img);
   return temp;
}
Complex Complex::minus(double r)
{
   Complex temp(real-r,img);
   return temp;
}

//main.cpp
#include "complex.h"
#include <iostream>
using namespace std;
int main()
{
   Complex a(3,2),b(5,4),temp;
   temp.set(a.plus(b));//temp=a+b
   temp.display();
   cout <<endl;
   temp.set(a.minus(b));//temp=a-b
   temp.display();
   cout <<endl;
   return 0;
}
運行結果:
8+6i
-2-2i

雖然程序16.3.1已經實現了復數的加減法,但是其表達形式極為麻煩,如果有復數a、b、c和d,要計算a+b-(c+d)將會變得非常復雜。如果不是調用函數,而是使用操作符的話,就會直觀得多了。

聲明一個操作符重載的語句格式為:
    返回值類型operator 操作符(參數表);

事實上,在聲明和定義操作符重載的時候,我們可以將其看作函數了,只不過這個函數名是一些操作符。在聲明和定義操作符重載時需要注意以下幾點:
  1. 操作符只能是C++中存在的一些操作符,自己編造的操作符是不能參與操作符重載的。另外,“::”(域解析操作符)、“.”(成員操作符)、“……?……:……”(條件操作符)和sizeof等操作符不允許重載。
  2. 參數表中羅列的是操作符的各個操作數。重載后操作數的個數應該與原來相同。不過如果操作符作為成員函數,則調用者本身是一個操作數,故而參數表中會減少一個操作數。(請對比程序16.3.2與程序16.3.3)
  3. 各個操作數至少要有一個是自定義類型的數據,如結構或類。
  4. 盡量不要混亂操作符的含義。如果把加號用在減法上,會使程序的可讀性大大下降。

下面我們把操作符作為成員函數,來實現復數的加減法:(程序16.3.2)
//complex.h
#include <iostream>
using namespace std;
class Complex//聲明一個復數類
{
   public:
   Complex(Complex &a);
   Complex(double r=0,double i=0);
   void display();
   void operator =(Complex a);//賦值操作
   Complex operator +(Complex a);//加法操作
   Complex operator -(Complex a);//減法操作
   Complex operator +(double r);//加法操作
   Complex operator -(double r);//減法操作
   private:
   double real;
   double img;
};
//未定義的函數與程序16.3.1相同
void Complex::operator =(Complex a)
{
   real=a.real;
   img=a.img;
}
Complex Complex::operator +(Complex a)
{
   Complex temp(a.real+real,a.img+img);
   return temp;
}
Complex Complex::operator -(Complex a)
{
   Complex temp(real-a.real,img-a.img);
   return temp;
}
Complex Complex::operator +(double r)
{
   Complex temp(real+r,img);
   return temp;
}
Complex Complex::operator -(double r)
{
   Complex temp(real-r,img);
   return temp;
}
//main.cpp
#include "complex.h"
#include <iostream>
using namespace std;
int main()
{
   Complex a(3,2),b(5,4),c(1,1),d(4,2),temp;
   temp=a+b;//這樣的復數加法看上去很直觀
   temp.display();
   cout <<endl;
   temp=a-b;
   temp.display();
   cout <<endl;
   temp=a+b-(c+d);//可以和括號一起使用了
   temp.display();
   cout <<endl;
   return 0;
}

運行結果:
8+6i
-2-2i
3+3i
以上程序的main.cpp中,復數的加法表達得非常簡潔易懂,與程序16.3.1相比有了很大的進步。并且,我們發現使用了括號以后,可以更方便地描述各種復雜的運算。操作符在重載之后,結合性和優先級是不會發生變化的,符合用戶本來的使用習慣。

作為友元

前面我們把操作符作為成員函數,實現了復數的加減法。如果我們把操作符作為普通的函數重載,則需要將其聲明為友元。這時,參數表中的操作數個數應該與操作符原來要求的操作數個數相同。

下面我們來看一下,用友元和操作符重載來實現復數的加減法:(程序16.3.3)
//complex.h
#include <iostream.h>//由于VC編譯器存在問題,這里使用標準的寫法居然無法通過編譯
class Complex
{
   public:
   Complex(Complex &a);
   Complex(double r=0,double i=0);
   void display();
   friend Complex operator +(Complex a,Complex b);//作為友元
   friend Complex operator -(Complex a,Complex b);
   friend Complex operator +(Complex a,double r);
   friend Complex operator -(Complex a,double r);
   private:
   double real;
   double img;
};
//未定義的函數與程序16.3.1相同
Complex operator +(Complex a,Complex b)
{
   Complex temp(a.real+b.real,a.img+b.img);
   return temp;
}
Complex operator -(Complex a,Complex b)
{
   Complex temp(a.real-b.real,a.img-b.img);
   return temp;
}
Complex operator +(Complex a,double r)
{
   Complex temp(a.real+r,a.img);
   return temp;
}
Complex operator -(Complex a,double r)
{
   Complex temp(a.real-r,a.img);
   return temp;
}
//main.cpp
#include "complex.h"
#include <iostream.h>//由于VC編譯器存在問題,這里使用標準的寫法無法通過編譯
int main()
{
   Complex a(3,2),b(5,4),c(1,1),d(4,2),temp;
   temp=a+b;
   temp.display();
   cout <<endl;
   temp=a-b;
   temp.display();
   cout <<endl;
   temp=a+b-(c+d);
   temp.display();
   cout <<endl;
   return 0;
}

運行結果:
8+6i
-2-2i
3+3i

在上面這個程序中,加號和減號操作符由成員函數變成了友元函數。細心的讀者可能注意到了,那個賦值操作符的定義跑哪兒去了?

事實上,賦值操作符有點類似于默認拷貝構造函數,也具有默認的對象賦值功能。所以即使沒有對它進行重載,也能使用它對對象作賦值操作。但是如果要對賦值操作符進行重載,則必須將其作為一個成員函數,否則程序將無法通過編譯。

在操作符重載中,友元的優勢盡顯無遺。特別是當操作數為幾個不同類的對象時,友元不失為一種良好的解決辦法。

又見加加和減減

在第五章我們學習了增減量操作符,并且知道它們有前后之分。那么增減量操作符是如何重載的呢?同樣是一個操作數,它又是如何區分前增量和后增量的呢?

前增量操作符是“先增后賦”,在操作符重載中我們理解為先做自增,然后把操作數本身返回。后增量操作符是“先賦后增”,在這里我們理解為先把操作數的值返回,然后操作數自增。所以,前增量操作返回的是操作數本身,而后增量操作返回的只是一個臨時的值。

在C++中,為了區分前增量操作符和后增量操作符的重載,規定后增量操作符多一個整型參數。這個參數僅僅是用于區分前增量和后增量操作符,不參與到實際運算中去。

下面我們就來看看,如何重載增量操作符:(程序16.3.4)
//complex.h
#include <iostream.h>//由于VC編譯器存在問題,這里使用標準的寫法無法通過編譯
class Complex
{
   public:
   Complex(Complex &a);
   Complex(double r=0,double i=0);
   void display();
   friend Complex operator +(Complex a,Complex b);
   friend Complex operator -(Complex a,Complex b);
   friend Complex operator +(Complex a,double r);
   friend Complex operator -(Complex a,double r);
   friend Complex& operator ++(Complex &a);//前增量操作符重載
   friend Complex operator ++(Complex &a,int); //后增量操作符重載
   private:
   double real;
   double img;
};
//未定義的函數與程序16.3.3相同
Complex& operator ++(Complex &a)
{
   a.img++;
   a.real++;
   return a;//返回類型為Complex的引用,即返回操作數a本身
}
Complex operator ++(Complex &a,int)//第二個整型參數表示這是后增量操作符
{
   Complex temp(a);
   a.img++;
   a.real++;
   return temp;//返回一個臨時的值
}
//main.cpp
#include "complex.h" 
#include <iostream.h>//由于VC編譯器存在問題,這里使用標準的寫法無法通過編譯
int main()
{
   Complex a(2,2),b(2,4),temp;
   temp=(a++)+b;
   temp.display();
   cout <<endl;
   temp=b-(++a);
   temp.display();
   cout <<endl;
   a.display();
   cout <<endl;
   return 0;
}

運行結果:
4+6i
-2+0i
4+4i

根據運行結果,可以看到a++和++a被區分開來了。而調用后增量操作符的時候,操作數仍然只有一個,與那個用于區分的整型參數無關。

至此,我們已經學完了類的一些基本特性和要素。在接下來的章節中,我們要更深入地發掘面向對象程序設計的優勢。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线免费高清视频| 国产日韩在线免费| 亚洲国产精品久久久| 久久91亚洲精品中文字幕| 91在线观看欧美日韩| 日韩av电影手机在线观看| 欧美精品久久一区二区| 九九精品视频在线观看| 一区二区三区www| 日韩电影中文字幕| 在线视频欧美日韩精品| 国产日韩欧美综合| 欧美日韩亚洲系列| 欧美精品亚州精品| 色与欲影视天天看综合网| 日韩免费观看网站| 成人国产精品久久久久久亚洲| 91视频8mav| 在线免费观看羞羞视频一区二区| 97人人模人人爽人人喊中文字| 欧洲午夜精品久久久| www.美女亚洲精品| 久久久久久久国产精品| 91中文字幕在线观看| 成人欧美在线视频| 91香蕉国产在线观看| 这里只有精品视频在线| 91精品久久久久久久久青青| 国产精品综合不卡av| 亚洲理论片在线观看| 亚洲综合中文字幕在线观看| 欧美寡妇偷汉性猛交| 日韩电视剧在线观看免费网站| 国产精品亚洲一区二区三区| 国产精品视频在线播放| 久久躁狠狠躁夜夜爽| 亚洲成人动漫在线播放| 色妞欧美日韩在线| 国产精品天天狠天天看| 亚洲一区二区免费| 91精品国产高清久久久久久| 欧美日韩国产一中文字不卡| 亚洲欧美资源在线| 97在线视频免费看| 97**国产露脸精品国产| 国产欧美日韩丝袜精品一区| 亚洲免费成人av电影| 国产精品对白刺激| 国产啪精品视频| 欧洲美女7788成人免费视频| 国产日韩在线看片| 欧美成人中文字幕在线| y97精品国产97久久久久久| 亚洲精品99999| 这里只有精品在线观看| 日韩av在线不卡| 国产精品自产拍在线观看中文| 国产精品永久免费视频| 91丨九色丨国产在线| 国产99视频在线观看| 欧美成人合集magnet| 国产a∨精品一区二区三区不卡| 国内精品美女av在线播放| www.亚洲免费视频| 亚洲网站视频福利| 中文字幕亚洲欧美日韩在线不卡| 国产精品18久久久久久麻辣| 亚洲精品欧美一区二区三区| 91欧美精品成人综合在线观看| 欧美高清无遮挡| 欧美成人激情图片网| 久久久久中文字幕2018| 欧美一级视频一区二区| 国产成人精品视频在线| 欧美大片在线看| 色香阁99久久精品久久久| 欧美性视频精品| 亚洲深夜福利网站| 91免费版网站入口| 国产欧美精品日韩精品| 国产成人在线播放| 国产精品久久中文| 国产成人精品久久亚洲高清不卡| 亚洲乱码一区二区| 国产精品久久久久久久一区探花| 国产精品jizz在线观看麻豆| 国产精品无av码在线观看| 91九色国产视频| 亚洲精品自拍第一页| 亚洲伊人成综合成人网| 国产91免费观看| 国产精品老牛影院在线观看| 亚洲国产精久久久久久| 97国产成人精品视频| 国产精品自拍偷拍视频| 日韩最新在线视频| 亚洲第一区中文字幕| 国产suv精品一区二区| 久久久久久999| 欧美在线一区二区三区四| 亚洲人成五月天| 粗暴蹂躏中文一区二区三区| 奇米一区二区三区四区久久| 成人欧美一区二区三区在线| 51精品国产黑色丝袜高跟鞋| 亚洲欧美一区二区激情| 国产国语videosex另类| 国产精品一区二区三区在线播放| 夜夜嗨av一区二区三区四区| 亚洲欧美日韩精品久久奇米色影视| 久久久国产精品视频| 日韩欧美成人网| 国产91网红主播在线观看| 日韩在线观看免费高清完整版| 国产不卡视频在线| 日韩精品亚洲视频| 91精品国产成人| 69**夜色精品国产69乱| 欧美日韩国产一区中文午夜| 国产不卡av在线免费观看| 欧美黄色三级网站| 亚洲天堂2020| 国产视频亚洲精品| 亚洲已满18点击进入在线看片| www.久久撸.com| 亚洲午夜国产成人av电影男同| 中文字幕一区电影| 亚洲欧洲国产一区| 国语自产精品视频在线看抢先版图片| 欧美日韩成人黄色| 伊人久久久久久久久久久| 欧美激情综合亚洲一二区| 国产精品成人一区二区| 欧美孕妇与黑人孕交| 在线日韩第一页| 青草热久免费精品视频| 国产成人精品免费久久久久| 精品久久久中文| 久久精品久久久久久国产 免费| 亚洲激情在线观看| 精品中文字幕在线观看| 亚洲第一av网站| 成人一区二区电影| 亚洲成人aaa| 久久影视电视剧免费网站| 日韩中文字幕欧美| 亚洲精品久久久久久下一站| 久久久久久久97| 色先锋资源久久综合5566| 色偷偷偷亚洲综合网另类| 亚洲а∨天堂久久精品9966| 国产精品99蜜臀久久不卡二区| 国产日产亚洲精品| 日韩av网站导航| 中文字幕精品久久| 欧美另类精品xxxx孕妇| 久久久成人精品| 国产日韩欧美黄色| 色综合亚洲精品激情狠狠| 岛国av一区二区在线在线观看| 久久夜色精品国产欧美乱| 亚洲日本成人网| 久久免费国产精品1| 国产91成人在在线播放|