2014-03-04 48 views
0

我的接口層次結構如下:充分利用層次的界面接口

class interface1 
{ 
public: 
    virtual ~interface1() = 0; 
} 

class interface2 : public interface1 
{ 
public: 
    virtual ~interface2() = 0; 
} 

我的數據模型有一個既可以從接口1或接口2派生類:以

class cls1 : public interface1 
{ 
} 
class cls2 : public interface2 
{ 
} 

我想寫一個超載的功能,可以在接口1或接口2上工作

void function1(interface1 * obj) 
{ 
    // do something here 
} 
void function1(interface2 * obj) 
{ 
    // do something here 
} 

現在我想同時創建的對象 - CLS1和CLS2,並調用功能1:

{ 
    ......... 
    cls1 *p1 = new cls1; 
    cls2 *p2 = new cls2; 

    function1(p1); 
    function1(p2);   
    ......... 
} 

我的問題是 - 在這兩種情況下,功能1(接口1 * OBJ)總是調用。我不想使用if-else與dynamic_cast結合(這是創建接口層次結構的關鍵)。 任何人都可以建議我調用function1(interface2 * obj)與cls2的對象?

+0

在一個不相關的音符,你的析構函數似乎缺少了'virtual'關鍵字。 – PaF

+0

我無法重現您的問題。如果應用了明顯的修復,但是完全相同的代碼,gcc使用相應的函數[如預期](http://ideone.com/a4H0dm)(ideone.com) – user2079303

+0

@PaF:是的,謝謝!更正! – vckane

回答

1

你要做的事聽起來很像虛擬功能。爲什麼不定義爲function1類的成員函數:

class interface1 
{ 
public: 
    virtual void function1() 
    { 
     // Do what you want to do when deriving from interface1 
    } 
} 

class interface2 : public interface1 
{ 
public: 
    virtual void function1() 
    { 
     // Do what you want to do when deriving from interface2 
    } 
} 
+0

這對我來說是顯而易見的解決方案,但並非如此簡單。如果function1()和funtion2()是不同類的一部分,並且對cls1和cls2有不同的實現呢?很好的例子是,訪客模式。 – vckane

0

人比我更瞭解對我說,就是是一個壞主意,靠編譯器檢測到您從一個類要隱含的返回值。這可能會導致無法解決的問題,因爲它們有時選擇的方式與您預期的不同。

所以,在這種情況下,我會用一個明確的演員,像

function1(static_cast<interface1*>(p1)); 
function1(static_cast<interface2*>(p2)); 

我知道這是不是因爲小巧,但如果你看看你的代碼,從上年現在會更有意義。

0

從更高層點的視野比其他答案:你所要完成的是派遣基於參數的類型的函數調用。一般而言,C++不支持這一點。

有兩種選擇:

  1. 作爲@PaF寫道,可以使功能虛擬化。
  2. 如果你真的不想擁有作爲類成員的功能,可以模擬所謂的雙重調度(根據調用的對象以及調用的對象的類型確定要調用的函數參數)通過應用訪問者模式。這樣,您可以根據參數的類型調用函數,同時避免使用dynamic_cast。