close

在C++中 , 我們可以藉由呼叫 virtual function來dispatch到我們想要呼叫的那個class功能 , 

class Feature 
{
virtual void intersectWith(Feature* f) = 0;
virtual void intersectWith(Circle* f) = 0;
virtual void intersectWith(Square* f) = 0;
};
 
class Circle : public Feature
{
void intersectWith(Feature* f){ cout << "This is Feature in the Circle!!"; }
void intersectWith(Circle* f){ cout << "This is Circle!!"; }
void intersectWith(Square* f){ cout << "This is Square in the Circle!!"; }
};
class Square : public Feature
{
void intersectWith(Feature* f){ cout << "This is Feature in the Square!!"; }
void intersectWith(Circle* f){ cout << "This is Circle in the Square!!"; }
void intersectWith(Square* f){ cout << "This is Square!!"; }
}
 
以上面這個例子來說 , 若:
Feature* f1 = new Circle();
Feature* f2 = new Square();
Feature* f3;
此時我們若呼叫:
f1.intersectWith(f3);
f2.intersectWith(f3);
則分別會print出 This is Feature in the Circle!! 以及 This is Feature in the Square!!
這是由於virtual function會在run time時依照virtual table所記錄的內容自動幫我們動態決定應該要dispatch到哪一個class type.
 
但是若我們呼叫:
Feature* f3 = new Circle();
Feature* f4 = new Square();
f1.intersectWith(f4);
f2.intersectWith(f3);
照理說 , 我們想要印出的是 : This is Square in the Circle!! 以及 This is Circle in the Square!!
可是結果卻一樣是印出 This is Feature in the Circle!! 以及 This is Feature in the Square!!
這是由於argument的型別是在compile time時 , function overloading就已經幫我們決定好要使用哪個method function.
由於f1 以及 f2的type都是Feature* , 所以就會使用到argument為Feature*的那個method function.
 
如果我們要印出想要的內容 , 其時也很簡單 , 只要在動態決定一次就好了 , 而這就形成了double dispatching.
我們先要把intersectWith(Feature*) 這個virtual function的內容改為:
class Circle : public Feature
{
void intersectWith(Feature* f){ f.intersectWith(*this); }
void intersectWith(Circle* f){ cout << "This is Circle!!"; }
void intersectWith(Square* f){ cout << "This is Square in the Circle!!"; }
};
class Square : public Feature
{
void intersectWith(Feature* f){ f.intersectWith(*this); }
void intersectWith(Circle* f){ cout << "This is Circle in the Square!!"; }
void intersectWith(Square* f){ cout << "This is Square!!"; }
};
同樣呼叫:
Feature* f3 = new Circle();
Feature* f4 = new Square();
f1.intersectWith(f4);
f2.intersectWith(f3);
在第一次的dispatch中 , 我們會知道f2與f1是哪個class type , 此時我們會進到 void intersectWith(Feature* f){ f.intersectWith(*this); }
此時又進行一次的dispatch , 我們便會知道f4與f3是屬於哪個class type , 
因此最後便會印出:
This is Circle in the Square!! 以及 This is Square in the Circle!!
 
 
ref : http://en.wikipedia.org/wiki/Double_dispatch
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 JerryCheng 的頭像
    JerryCheng

    KwCheng's blog

    JerryCheng 發表在 痞客邦 留言(0) 人氣()