2010-02-28 55 views
4

以下類層次結構表示抽象資源處理程序和資源層次結構。兩者都有作爲基類的接口。現在想象你編寫一個系統,你可以在這些接口下實現多個特定的資源系統。這只是一個例子。特定的主類創建從東西派生的資源。現在,當創建的資源交給基本接口時,它將作爲指向基本資源類的指針遞交,但我想處理特定資源並訪問其特定屬性。C++使用鏡像層次結構進行雙重調度

我知道雙重派遣,但我不認爲它在這種情況下工作。我想阻止RTTI和dynamic_casts。你有處理這種情況的建議嗎?

class resource; 

class main_resource_handler 
{ 
public: 
    virtual resource* create_resource() = 0; 
    virtual void do_some(resource* st) = 0; 
}; 

class resource 
{ 
}; 

class specific_resource : public resource 
{ 
public: 
    int i; 
}; 

class specific_resource_handler : public main_resource_handler 
{ 
public: 
    stuff* create_resource) { 
     return new specific_resource); 
    } 
    void do_some(resource* st) { 
     // in here i want to work with specific resource 
    } 
    void do_some(specific_resource* st) { 
     // i want to get here 
    } 
} 

main_resource_handler* handler = new specific_resource_handler(); 
resource* res = handler->create_resource(); 
handler->do_some(res); /// here 
+1

有在回答這個問題的一些想法:http://stackoverflow.com/questions/696350/avoiding -parallel繼承的層次結構 – quamrana 2010-02-28 18:52:03

回答

0

我不知道爲什麼你需要資源和處理程序 - 看起來你正在暴露一個額外的耦合,將被封裝。如果創建資源剛剛返回客戶端可直接調用方法的資源,則問題不存在。

如果您想要安全,請讓資源記住創建它的處理程序的地址,然後檢查do_some(resource* st)。如果資源是由當前處理程序創建的,並且處理程序只能創建給定類型的資源,則可以安全地轉換它並調用特定的函數。儘管如上所述,如果函數只是資源上的虛擬函數,那麼按照定義類型安全。

1

我想你不是問正確的問題。

要做到你的要求,你需要的是要補充一點:

template<typename T> 
class helper : public main_resource_handler 
{ 
public: 
    virtual resource* create_resource() { return new T; } 
    virtual void do_some(resource* st) { do_some_specific(static_cast<T*>(st)); } 
private: 
    virtual void do_some_specific(T* st) = 0; 
}; 

並改變這一點:

class specific_resource_handler : public helper<specific_resource> 
{ 
private: 
    virtual void do_some_specific(T* st) { ... } 
} 

static_cast是唯一安全的,如果你能保證你會總是在正確類型的處理程序上調用do_some。但是,如果您已經知道這是正確的處理程序,那麼就不需要進行基類的方法調用。所以大概你想要得到某種resource,不知道它的確切類型,並將其傳遞給適當的處理程序。這是棘手......