1. 什么是Multi-methods.
在闡述這個概念之前,我們先看一下什么是多態(Polymorphisn)。多態是面向對
象程序設計的一個重要的特征, 多態是允許你將父對象的指針(或者引用)設置成為它的子對象的技術,賦值之后,該父對象指針(或者引用)就可以根據當前賦
值給它的子對象的特性以不同的方式運作。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。多態性在C++中都是通過虛函數
(Virtual Function) 實現的。 例如:
class Parent

......{
public:
virtual void Test() = 0;
}

class Sub1: public Parent

......{
public:
void Test()

......{
cout<<"HI, this is sub1"<<endl;
}
}
class Sub2: public Parent

......{
void Test()

......{
cout<<"HI, this is sub2"<<endl;
}
}

Parent* p1 = new Sub1();
Parent* p2 = new Sub2();
p1->Test(); //call the Test method of class Sub1;
p2->Test();//call the Test method of class Sub1;


在c
++中,多態性的內涵是:通過virtual function技術,真實的函數調用完全依賴于對象的真實類型(這就是late
binding)。我們的問題是:virtual function調用可不可以依賴于兩個或者兩個以上的對象?這就是multi-methods.
例子:
//method declaration
bool intersect(const Shape&, const Shape&,)

......{
//...
}
bool intersect(const Rectangle&, const Circle&,)

......{
//...
}

class Shape

......{
//...
}
class Rectangle: public Shape

......{
//...
}
class Circle: public Shape

......{
//...
}

Shape* s1 = new Rectangle();
Shape* s2 = new Circle();

//while calling the following method, what happend?
//the actual function which will be called is bool intersect(const Shape&, const Shape&,), not bool intersect(const Rectangle&, const Circle&,)
// but what we want is the latter, not former
intersect(*s1,*s2);
//maybe you can call like this, which will meet our requirement, but, unfor?tunately , it violats the principle: we should program based on interface not implementation.
intersect(*(dynamic_cast<Rectangle*>(s1)),*(dynamic_cast<Circle*>(s2)));




2. C++ committee曾經考慮的解決方案(摘自 The Design and Evolution of C++, by Stroustrup)
c++從語言自身來支持multi-method:
//solution 1:
(s1@s2)->intersect(); //rather than intersect(s1,s2);
//solution 2:
bool intersect(virtual const Shape&,virtual const Shape&);
bool intersect(virtual const Rectangle&,virtual const Circle&) //overrides

...{
}

或許,C++在將來的某個版本會支持multi-method.
3. workarounds for multi-method.
3.1 用double dispatch設計模式解決。
double dispatch(雙分派)設計模式是指:在選擇一個方法的時候,不僅僅要根據消息接收者(receiver)的運行時型別(Run time type),還要根據參數的運行時型別(Run time type)。接下來我們用double dispatch來解決一下上面的那個問題:
class Shape

......{
//...
virtual bool intersect(const Shape&) const = 0;
virtual bool intersect(const Rectangle&) const = 0;
virtual bool intersect(const Circle&) const =0;
}
class Rectangle: public Shape

......{
//...
bool intersect(const Shape& s) const

......{
return s.intersect(*this); // *this is a Rectangle and calling which intersect method totally depends on the real type of s!
}
bool intersect(const Rectangle&) const

......{
//...
}
bool intersect(const Circle&) const

......{
//...
}
}
class Circle: public Shape

......{
//...
bool intersect(const Shape& s) const

......{
return s.intersect(*this); // *this is a Circle and calling which intersect method totally depends on the real type of s!
}
bool intersect(const Rectangle&) const

......{
//...
}
bool intersect(const Circle&) const

......{
//...
}
}
對于double dispatch, 最大的問題是:這樣的設計與類的繼承結構高度耦合,當類的繼承結構改變后,會影響到現有的代碼。從上面的例子可以看到:Shape 類是不應該意識到它的子類的存在。不過當前的主流面向對象程序設計語言(C++/Java/C#等)都并不支持multi-method, 從這個意義上說:double dispatch還是一個合理,有效地解決方案
3.2 另一個可選的方案是RTTI。
bool intersect(const Shape& s1, const Shape& s2)

...{
//the follwing code, can implement by using index table, the key is the type_id of the real object(such as typeid(s1) and typeid(s2))
//the query result is the pointer to function (such as the pointer to function: bool intersect(const Rectangle&, const Circle&).
if( typeid(s1)==typeid(Rectangle) && typeid(s1)==typeid(Rectangle))

...{
intersect(*(dynamic_cast<Rectangle*>(s1)),*(dynamic_cast<Circle*>(s2)));
}
else if(...)

...{
//...
}

}
bool intersect(const Rectangle&, const Circle&,)

...{
//...
}

class Shape

.........{
//...
}
class Rectangle: public Shape

.........{
//...
}
class Circle: public Shape

.........{
//...
}

Shape* s1 = new Rectangle();
Shape* s2 = new Circle();
//as a result , for the caller, the code is based on interface not implementation
intersect(*s1,*s2);




