??C++語言中有一些多義詞,例如表示靜態的關鍵字static,將static應用在變數、函式或類成員等不同場合,它所表達的含義不一樣,源程式中相同的程式元素可能會具有不同的語法解釋,C++語言稱這些程式元素具有多型性,C++語言有多種不同的多型形式,常見的有關鍵字多型、多載函式多型、運算子多型、物件多型和引數多型等,
??對具有多型性的程式元素作出最終明確的語法解釋,這稱為多型的實作,不同多型形式具有不同的實作時間點,編譯時實作的多型稱為編譯多型,執行時實作的多型稱為執行多型,
一、關鍵字多型和多載多型
1、關鍵字多型
??C++語言中的某些關鍵字時多義詞,具有多型性,例如static、const、void以及public/private/protetced等,關鍵字多型是由編譯器在編譯源程式時根據背景關系進行語法解釋的,是一種編譯多型,
2、多載函式多型
??編譯時,由編譯器根據呼叫陳述句中實參的個數和型別自動呼叫形參最匹配的那個多載函式,形態的函式名,呼叫時可能會呼叫不同的函式,這就是多載函式多型,多載函式多型是由編譯器在編譯源程式時實作的,也是一種編譯多型,所謂實作多載函式多型,就是在編譯時將呼叫陳述句中的函式名轉換成對應多載函式的記憶體存盤地址,將源程式中的函式名轉換成某個具體的函式存盤地址,這種函式名到存盤地址的轉換被稱為是對函式的系結,
二、運算子多型
??相同的運算子,計算機會根據資料型別來選擇執行不同的運算,這就是運算子的多型性,運算子多型是由編譯器在編譯時進行語法解釋的,是一種編譯多型,
??通過一個復數的示例來更好的理解運算子多型,下面為復數類的代碼:
class Complex
{
private:
double real,image; //實數的實部和虛部
public:
Complex(double x=0,double y=0) {real = x;image = y;} //建構式
Complex(Complex &c) {real = c.real;image = c.image; } //拷貝建構式
void Show() { cout << real <<"+"<< image <<"i"<<endl;} //顯示復數
};
??重新定義C++語言已有運算子的運算規則,使同一運算子作用于不同資料型別資料時執行不同的運算,這就是運算子多載,正因為C++語言支持運算子多型,程式員才能多載運算子實作類運算,多載運算子就是以函式的形式來重新定義運算子的運算規則,其語法形式如下:
??函式型別 operator 運算子(形式引數)
??{ 函式體 }
??為類多載運算子,可以將運算子函式定義成類額成員函式,也可以定義成類外的一個友元函式,針對不同的運算子,其運算子函式的具體實作方法也有所不同,例如單目/雙目、前置/后置等,
1、雙目運算子“+”
??1)定義成類的成員函式
|
|
??如果不將運算子函式定義成類中的函式成員,那它就時類外的普通函式,為了讓類外的運算子函式能訪問類中的非公有成員,那就必須將它定義成類的友元函式,
??若運算子+被多載為復數類的函式成員,則呼叫形式為“c1.+c2”,其中c1為物件名,"."為成員運算子,"+"為函式成員名,c2為實參,
??若運算子+被多載為復數類的友元函式,則呼叫形式為“+(c1,c2)”,其中+為友元函式名,c1、c2均為實參,為了提高函式代碼執行效率和資料保護,可以將函式成員的形參定義為常參考如Complex operator +(const Complex &c)將形參c改為常參考,
??示例:
??Complex c1(1.3),c2(2,4),c3;
???? c3 = c1 + c2;c3.Show();//顯示復數c3,顯示結果:3+7i;
2、單目運算子 ++
??C++語言規定:前置單目運算子多載為函式成員時沒有形參,而后置單目運算子時需要有一個int型形參,這個int型形參沒有引數名,在函式體中并不使用,其目的純粹是為了使這兩個重名函式具有不同形參,這樣才能多載,
class Complex //通過成員函式多載++運算子
{
private:
double real,image; //實數的實部和虛部
public:
Complex(double x=0,double y=0) {real = x;image = y;} //建構式
Complex(Complex &c) {real = c.real;image = c.image; } //拷貝建構式
void Show() { cout << real <<"+"<< image <<"i"<<endl;} //顯示復數
Complex & operator ++() //實作前置++運算子的函式成員,這里說明回傳值是一個Complex的參考
{
real++; image++;
return *this;
}
Complex operator ++(int) //實作后置++運算子的函式成員
{
Cpmplex temp(*this);
real++; image++;
return temp; //回傳+1之前的物件temp
}
};
??示例:
??Complex c1(1.3),c2,c3;
??c2=++c1;c3=c2++;c1.Show();c2.Show(); //顯示結果:c1為2+4i;c2為2+4i;c3為2+4i;
3、關系運算子 ==
將關系運算子 == 多載為復數類的函式成員,其代碼如下:
bool Complex::operator ==(Complex c)
{
return (real=c.real && image == c.image);
}
值得注意的是,關系運算子函式的回傳結果為bool型,
?示例:
??Complex c1(1.3),c2(2,4);
??if( c1 == c2 ) //結果為false
4、賦值運算子 =
??物件可以用賦值運算子 = 進行賦值,如果將賦值運算子多載為復數類的函式成員,其代碼如下:
Complex & Complex::operator =(Complex c)
{
real = c.real; image = c.image;
return *this; //回傳賦值后當前物件的參考
}
??C++編譯器通常會自動為類多載賦值運算子 “=”,程式員也可以自己撰寫賦值運算子函式,其功能很像拷貝建構式,如果某個類的建構式中動態分配了記憶體,除了需要為該類撰寫解構式釋放這些記憶體,程式員還要撰寫它的拷貝建構式和多載賦值運算子 = ,其目的是進行深拷貝,為新建物件或別賦值物件動態再分配同樣多的記憶體,??
??示例:
??Complex c1(1.3),c2;
??c2 = c1;c2.Show(); //顯示c2為1+3i
5、右移運算子 >> 和左移運算子 <<
??為類多載右移和左移運算子是為了直接使用cin和cout指令來輸入和輸出物件,這里注意只能將右移運算子和左移運算子定義為類外的友元函式,
friend istream & operator >>(istream &is,Complex &c)
friend ostream & operator <<(ostream &os,const Complex &c); //在類中宣告友元函式
//下面為函式實作部分
istream & operator >>(istream &is,Complex &c) // 鍵盤依次輸入復數的實部和虛部
{
is >> c.real >>c.image;
return is;
}
ostream & operator <<(ostream &os,const Complex &c) //顯示幕上顯示復數
{
os << c.real << "+" << c.image <<"i";
return os;
}
??示例:
? Complex obj;
? cin >>obj; //輸入:3 5 [回車]
cout <<obj <<endl; //顯示:3+5i
6、運算子多載的幾點語法細則
??1) 除了條件運算子"?:"、sizeof運算子、成員運算子"."、指標運算子"*和作用域運算子“::”這五個運算子,C++其他運算子均可以被多載,
??2)多載后,運算子的優先級和結核性不會改變,
??3)多載后,運算子的運算元個數不能改變,同時至少有一個運算元是型別別,
??4) 多載后,運算子的含義應與原運算子相似,否則會給使用者造成困惑,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/500095.html
標籤:其他
