C 單分派和雙分派問題

2021-10-06 15:48:25 字數 1956 閱讀 7079

分派說的是根據物件的型別和引數型別來確定最終呼叫的實際函式,體現出來也就是多型性。c++多型一般分為兩種,一種是靜態多型,也就是通過過載(同名不同參)以及通過模板的實現;另一種就是動態多型,也稱執行時多型,通過虛函式的繼承與重寫來實現的。

單分派:也就是只能同時進行一種方式的分派,也即要麼就是通過過載實現靜態多型,要麼就是通過虛函式繼承實現執行時多型。具體化表現就是:只能根據物件的動態型別以及引數的靜態型別,來確定實際呼叫函式。

雙分派:也就是可以在支援靜態多型的基礎上再進行動態多型。可以根據物件的動態型別和引數的動態型別來確定實際呼叫函式。

c++僅支援單分派,舉個栗子:經典的工程師解決問題

#include using namespace std;

// 三個問題類,乙個問題父類,兩個子類; 兩個工程師類,基礎工程師和資深工程師

class problem

我們期望的結果應該是:

******problem

diffcultproblem

primaryengineer solve ******problem // e1->solve(p1)

primaryengineer solve diffcultproblem // e1->solve(p2)

seniorengineer solve ******problem // e2->solve(p1)

seniorengineer solve diffcultproblem // e2->solve(p2)

但是結果卻是這樣的:

因為c++只支援單分派模式。結果可知,在solve 函式的分派上,可以根據呼叫物件的實際型別,來決定呼叫函式(虛函式表決定),但是引數型別卻不能根據傳入引數的實際型別進行選擇,只能根據靜態型別選擇。 

我們做一下改變:傳入時就將型別確定,看是否會如想象中輸出。還是原來的**,將p1 p2型別直接指定。

// problem *p1 = new ******problem();

// problem *p2 = new diffcultproblem();

******problem *p1 = new ******problem();

diffcultproblem *p2 = new diffcultproblem();

結果如下:因為是單分派寫法,所以確實都如所想一般。

那麼問題來了,就想實現雙分派呢?c++可以實現雙分派嗎?當然是可以的!我們觀察到,在第一次的實現中,p1, p2的靜態型別是 problem父類, 但是實際型別卻是兩個子類,他們的函式呼叫自然也是在虛函式表中指定好了的正確呼叫。既然如此,那就可以通過兩次執行時多型的特性來實現乙個類似雙分派的功能。直接上**:

#include using namespace std;

class primaryengineer;

class seniorengineer;

class problem

};class seniorengineer : public primaryengineer

};int main()

結果如下:

靜態分派和動態分派

靜態分派 所有依賴靜態型別來定位方法執行版本的分派成為靜態分派,發生在編譯時期,典型 應用為方法過載。靜態分派發生在編譯階段,因此確定靜態分派的動作實際上不是由虛擬機器來執行的。動態分派 典型應用為重寫,是一種動態的概念。向上轉型後呼叫子類覆寫的方法便是乙個很好地說明動態分派的例子。就是說,我們在判...

再論雙分派

暴力雙分派速度快,可是當類增多時,代價依然很大。map雙分派在速度優化上有dynamic cast和static cast兩種選擇,loki把這個選擇做成了policy。矩陣雙分派速度上有天然的優勢,但是你要修改你的類。於是loki也把這個做成了policy供你選擇。矩陣雙分派的思想是,在你的cla...

人員分派問題

人員分派問題 工作人員x1,x2,x3.xn去做n件工作y1,y2,y3,yn,每人適合做其中一件或幾件,問能否每人都有乙份適合的工作?如果不能,最多幾人可以有適合的工作?分析 n個人完成n件工作,如果每人都有乙份合適的工作,即1個人完成一件工作,1對 1 可裝化為找最大對集問題。匈牙利演算法 詳見...