多態的類型:分為4類,重載多態,強制多態,包含多態,參數多態。
以前所學過的普通函數的重載也屬於重載多態。強制多態是指將一個變元的類型加以變化,以符合一個函數或操作的要求,比如int型與float型相加,要先進行類型轉換。
多態的實現:分為兩類,編譯時的多態與運行時的多態。
前者在編譯的過程中確定了同名的具體操作對象,而后者是在程序運行過程中才多態地確定操作所指向的對象。這種確定操作具體對象的過程就是綁定。綁定工作在編譯連接階段完成的情況為靜態綁定,在程序運行過程中完成的情況是動態綁定。
運算符重載
運算符重載時對已有的運算符賦予多重含義,使同一個運算符作用於不同的數據類型時有不同的行為。
重載形式
重載為類的非靜態成員函數,重載為非成員函數。
兩種重載方式的聲明語法形式一般相同
都為
返回類型 operator 運算符(形參表)
{
函數體
}
非成員函數一般定義為友元函數。
**實現‘+’的重載**
#include<iostream>
using namespace std;
class counter {
private:
float a;
public:
counter(float a=0):a(a){}
counter operator+(counter& c)const { **//定義為類的非靜態成員函數**
return counter(a + c.a);
}
//friend counter operator+(counter& c1,counter& c2); **//定義為非成員函數**
void print()const {
cout <<"和為:"<< a << endl;
}
};
/*counter operator+(counter& c1, counter& c2) {
return counter(c1.a + c2.a);
}*/
int main() {
float i, j;
cout << "輸入要相加的兩個數:";
cin >> i >> j;
counter c1(i),c2(j),c3;
c3 = c1 + c2;
c3.print();
return 0;
}
虛函數
聲明語法 virtual 函數類型 函數名(形參表);virtual關鍵詞只能在聲明時出現,函數實現時不能出現。
派生類的虛函數關鍵詞virtual,當與基類的虛函數相同,可以省略。此時,派生類的虛函數會覆蓋基類的虛函數,以及基類中同名函數的其他重載形式。基於這一特性,虛函數主要用來處理同一類族中不同的對象。
#include<iostream>
using namespace std;
class BaseClass {
public:
virtual void fun1() {
cout << "調用BaseClass::fun1" << endl;
}
void fun2() {
cout << "調用BaseClass::fun2" << endl;
}
};
class DerivedClass :public BaseClass {
public:
void fun1() {
cout << "調用DerivedClass::fun1" << endl;
}
void fun2() {
cout << "調用DerivedClass::fun2" << endl;
}
};
void print(BaseClass *p) {
p->fun1();
p->fun2();
}
int main() {
DerivedClass c2;
print(&c2);
}
代碼中是將派生類對象的地址傳給基類指針*p,輸出為派生類的的虛函數的執行,說明派生類的虛函數將基類的虛函數覆蓋掉了
純虛函數
聲明語法 virtual 函數類型 函數名 (形參表)=0;與虛函數不同的是,純虛函數在基類中不需要實現。它是抽象類的標志。
抽象類
如上,它必定帶有純虛函數。抽象類的作用是通過他為一個類族傳建一個公共的接口。由於派生類的虛函數會覆蓋積累的虛函數,在聲明純虛函數后,相當於純虛函數的函數體由派生類的虛函數來實現,使它們能夠更有效地發揮多態特性。
#include<iostream>
using namespace std;
class base1 {
public:
virtual void display()const = 0;//定義純虛函數
};
class base2:public base1{
public:
void display()const {
cout << "baseclass \n";
}
};
void print(base1* p) {
p->display();
}
int main() {
//#include<iostream>
using namespace std;
class base1 {
public:
virtual void display()const = 0;
};
class base2:public base1{
public:
void display()const {
cout << "baseclass \n";
}
};
void print(base1* p) {
p->display();
}
int main() {
//baseclass1 A1;
base2 A2;
print(&A2);//與虛函數相同,通過指針或引用來調用純虛函數
return 0;
}
在主函數中加入baseclass1 A1;會報錯
說明純虛函數不能實例化,也就是不能有實際對象。