2010-03-03 78 views
0

我正在學習一些源代碼,我只是想知道,爲什麼一個類(或類)通常以這種方式實現:包含一個「實現」和「接口」指針的C++類的用途是什麼?


class EventHandler 
{ 
... 
    EventDispatcher* m_Dispatcher; 
    virtual bool ProcEvent(EventHandler* Sender, int Task, int Event, void* Param); 
... 
}; 

class ClassA: public EventHandler 
{ 
... 
    ClassA* m_Impl; 
    ClassA* m_Iface; 
... 
public: 
    // virtual functions 
    virtual bool ProcEvent(EventHandler* Sender, int Task, int Event, void* Param); 
    virtual void OnDataWritten(const PIOResult&) {;} 
    ... 

    // sample functions 
    void SetImplement(ClassA* aImpl); 
    void SetInterface(ClassA* aIface); 
    ClassA* GetImplement() { return m_Impl; } 
    ClassA* GetInterface() { return m_Iface; } 
    bool GetData(list& aList); 
}; 

// Implementation of some sample functions; Most of its function contain more 
// or less the same format as below, with the return m_Impl->XXX having the same 
// name as the function being defined (e.g. A::XXX) 
bool ClassA::GetData(list< Data >& aList) 
{ 
    if(m_Impl) 
     return m_Impl->GetData(aList); 
    else 
     return false; 
} 

class ClassAFactory: public EventHandler 
{ 
private: 
    ClassAFactory* m_Impl; 
    ClassAFactory* m_Iface; 

protected: 
    virtual ClassA* MakeTransport(); 

    virtual bool ProcEvent(EventHandler* Sender, int Task, int Event, void* Param); 
    virtual ClassA* CreateClassA() { return 0; } 

... 
}; 

// In some member function of ClassB (ClassB inherits ClassA) 

switch(status) 
{ 
    case 1: 
     GetInterface()->OnDataWritten(); 
    case 2: 
     // ... 
}; 


我相信這是一些設計模式,但我不熟悉它。如果我知道它是什麼,它可以幫助我理解。任何人都可以幫我指出它可能是什麼,或者這些類的用途是什麼,以便這樣實現?

我認爲這是一些事件處理和一些工廠一起使用,但我不知道。

+0

你可以提供一個關於如何使用它的更大提示嗎?如果我沒有更好的瞭解,我會說它是由對面向對象編程有基本誤解的人編寫的。否則,他們不明智地重載了一些大量使用的單詞的含義。 –

+0

這讓我想起了在直C中完成的OO hack,其中您使用指向同一結構的不同版本的指針來鏡像一些面向對象的功能。 – rerun

+0

我已經添加了一些,我希望它可以幫助。 – jasonline

回答

2

恐怕所用的名稱沒有usual的含義,因此沒有示例說明放入什麼或如何使用它們,這將很難猜測。

有2種設計模式,你應該檢查,頻繁使用這種self-recursion的(在類級別*):

而且我害怕你正在尋找一些不能效仿這兩者的東西。

Decorator中,重點是添加功能。爲此,您有一個Interface其中衍生Concrete類和Wrapper接口。然後,各種包裝將得到的Wrapper,你可以把它們連:

Interface* interface = new Wrapper2(new Wrapper1 (new Concrete())); 

每個包裝添加一些功能,而這裏我們只擁有完善的轉發......所以它不是一個Decorator

Composite模式不同。它的目標是隱藏你是否對待一系列元素或一個元素。通常的例子是一棵樹:如果使用Composite模式實現,您可以將操作應用於整個子樹或者僅應用於葉節點。

再次,這裏沒有這樣的事情。

所以我最好的猜測是,你要麼野生設計(也許是引入歧途的企圖模仿知名模式),或者你還沒有給予足夠的信息(源代碼),我們要弄清楚的作用。無論如何,這似乎很奇怪。

*注意:在課程級別,我指的是級別的對象指向A的另一個對象,但這並不意味着堆棧溢出(雙關意圖)。這個不是相同的實例位在SetImplementation調用期間肯定值得檢查:請注意,任何循環引用都會通過遞歸導致死亡。

+0

我同意「而且我恐怕你正在尋找一些不能效仿這兩者之一的東西。」 –

+0

@Matthieu:關於ClassA和ClassAFactory之間的關係的任何想法?這是另一種設計模式嗎? – jasonline

+0

@jasonline:這個名字暗示了一個'Factory'或者一個'AbstractFactory',這個術語再次被大量使用,卻沒有嚴格遵守四人幫所描述的模式。如果沒有實現,很難說,而且'm_Impl'和'm_Interface'沒有比'ClassA'更有意義... –

2

我瘋狂的猜測,但它可能是你正在尋找的「pimpl成語」? http://www.gamedev.net/reference/articles/article1794.asp

EDIT
用的GetData執行擴展代碼示例絕對是PIMPL方法的一個例子。但是,這並不能解釋m_Iface成員。你能提供一個例子嗎?

EDIT2
隨着m_Iface是如何顯示其添加的例子是明確我對於平普爾是錯誤的。它是一種裝飾器。 m_Impl指向底層對象,而m_Iface指向最外層,以便底層對象可以調用貫穿整個裝飾器鏈的調用。這個例子有點複雜,因爲ClassA都是接口類和默認實現。如果你想創建一個裝飾器到類中,你將不得不繼承ClassA。

+0

我不認爲這是一個pimpl成語。如果是,則實現指針應該指向另一個類的權限。但在上面的代碼中,它指向了類本身。 – jasonline

+0

嗯..你是對的...然後它看起來更像一個「裝飾器」模式實現,但仍然不能解釋m_Iface成員。 –

+0

我已經添加了一些關於如何調用m_Iface的信息。同時,我會檢查裝飾者模式。 – jasonline

0

這看起來比C++多得多。在任何面向對象的語言中,你都會使用繼承和虛函數來獲得這種行爲。

使用指向實現類的內部指針是非常好的(pimpl習語),但這個指針通常不會被調用者訪問。我根本沒有得到接口指針。

+0

@Gorpik,我添加了更多課程。我認爲這是一些事件處理,並與一些工廠一起使用。是的,我沒有使用接口指針。我找不到它在哪裏使用。 – jasonline

+0

@Gorpik:我添加了使用接口的示例函數。 – jasonline

0

我不確定這是否是pimpl成語的典型示例,但如果是這樣,則要點是將接口(應該是穩定的)與實現細節分開(您應該相對自由地進行更改)。

相關問題