2017-06-16 66 views
0

我很難用文字清楚地將我的想法可視化。下面的例子可以解釋我的想法。我有兩個抽象類和兩個派生類,每個抽象類都知道別人

class Base1{ 
     public: 
     virtual void f1() = 0; 
     std::string get(){ return "HelloWorld";} 
}; 

class Derived1: public Base1{ 
     public: 
     void f1() {} 
     void update (std::string& update){ 
      **should call like** Base2::Derived2::update_data(this);} 
}; 

=>和

class Base2{ 
     public: 
     virtual void f2() = 0; 
}; 

class Derived2: public Base2{ 
     public: 
     void f2() {} 
     void get (Base1& d1){ d1.Base1::get(); } 
     void update_data (Base1& d1){ d1.Base1::get(); } 
}; 

=>類被稱爲

int main(){ 
Derived1 d1; 
Derived2 d2; 

d2.get (d1); 
std::string hi = "hiWorld"; 
d1.update (hi); 
return 0; 
} 

我怎樣才能實現**should call like**不及格d1.update()中的Base2實例。

另一個問題是,當每個類對象知道其他對象時,它會調用什麼?

謝謝。

+0

'Derived1'需要知道'Derived2'的實例。假設該實例由名爲'thing'的變量(或數據成員)表示,則它可以執行'thing.update_data(* this)'。這顯然依賴於在調用點編譯器可見的類Derived2'的定義(以及創建'thing'時) – Peter

+1

您如何期望Derived1 :: update()知道Derived2對象的哪個實例要調用update_data( ),在這種情況下? –

+0

您可能應該閱讀有關類和對象(或類的實例)之間的差異。它會幫助你理解如何達到你想要的。我還建議你閱讀關於觀察者模式,因爲它可能是你想要達到的目標。 – Logman

回答

0

看來你需要一種叫做double-dispatch的技術。 C++只能直接支持單一派遣 - 您獲得的行爲僅基於單個實例。

a->virtualFunction(params); // exactly which implementation is called depends on the concrete type of a. 

對於雙調度,(不存在),你就需要像

(a,b)->virtualFunction(params); // where the call is based on both parameters. 

有這個問題的一些解決方案。這些工作需要一種類型需要知道另一種類型的工作,但只能這樣。

考慮一組我們想在表面上繪製的幾何形狀。 類Surface; class drawable { public: virtual〜Drawable(){} virtual void draw(Surface *)= 0; };

class Surface { 
    public: 
     virtual ~Surface() {} 
    // details ommitted. 
    } 

    class Rectangle : public Drawable { 
    }; 
    class Circle : public Drawable { 
    } 

    // and some surfaces 

    class PrinterSurface : public Surface { 
    }; 

    class PlotterSurface : public Surface { 
    }; 

我們實際要調用的代碼依賴於曲面和形狀。

爲了解決這個問題,我們選擇一個最有界的層次結構,並告訴另一個層次結構有關該類型的具體實例。

在這個例子中,認爲比渲染它們的技術會存在更多的形狀和可繪製的對象。

因此,每個可繪製物品都會知道如何繪製每個表面。

class Drawable { 
    public: 
     virtual ~Drawable() {} 
     virtual void drawPrinter(Surface *) = 0; 
     virtual void drawPlotter(Surface *) = 0; 
     virtual void drawSurface(Surface *) = 0; 
    }; 

    class Surface { 
    public: 
     virtual ~Surface() {} 
     virtual void draw(Drawable * pDrawable) = 0; 
    } 

    class PrinterSurface : public Surface { 
     void draw(Drawable * pDrawable) { 
      pDrawable->drawPrinter(this); 
     } 

    }; 

我們Surface->draw(Drawable *)通話將被彈到一個具體的實現,其中每個可繪製瞭解如何渲染到設備,但這些設備都沒有的Drawable小號

色域的知識對於進一步閱讀:wikipedia : double dispatch獲取更完整的描述。

,我會建議設計模式書wikipedia : design patterns

的設計模式提供給設計的一個詞彙,這使得在問這個問題的形式要容易得多的一些想法。

相關問題