2012-02-08 50 views
4

作爲一個簡單的例子,如果我有類如何最好地實現一個模板類與互相依賴

template <class T, class U> class ProcessEvent 
{ 
    public: 
    ProcessEvent(T* t) : var1(t) { var2 = new U; } 
    Process() { var2->Process(var1); } 
    private: 
    T* var1; 
    U* var2; 
}; 

class Foo 
{ 
    /*data*/ 
}; 

class FooProcessor 
{ 
    void Process(Foo* foo) {/*functionality*/} 
}; 

class Bar 
{ 
    /*data*/ 
}; 

class BarProcessor 
{ 
    void Process(Bar* bar) {/*functionality*/} 
}; 

類型,以便類的processEvent可以有兩套不同的模板類型,

ProcessEvent<Foo, FooProcessor> 
ProcessEvent<Bar, BarProcessor> 

但是,第二個模板類型FooProcessor和BarProcessor直接由第一模板類型隱含的,是實現細節,用戶不關心。我的目標是具有與上述相同的功能,但是ProcessEvent只接受一個模板參數Foo或Bar。除了通過ProcessEvent的專業化,這可以做到嗎?

+1

'U * = new()'和'U-> Process(T)'在語法上是無效的,你是什麼意思? – 2012-02-08 16:10:38

+0

@Matt對不起,我認爲我解決了它 – user334066 2012-02-08 16:16:21

回答

4

你可以做到這一點,如下所示:

template<typename T> 
class Spec 
{ 
}; 

template<> 
class Spec<Foo> 
{ 
    typedef FooProcessor type; 
}; 

template<> 
class Spec<Bar> 
{ 
    typedef BarProcessor type; 
}; 

然後分別使用Spec<T>::type,與T =酒吧或T =富,只要你需要BarProcessor和FooProcessor。

+1

這得到一個+1,因爲雖然它比我的解決方案更羅嗦,但它也更靈活(並且不需要訪問'Foo'類來提供這些特性)。 – 2012-02-08 16:26:50

+0

雖然Mark的回答是最簡單的,但我在他的評論 – user334066 2012-02-09 00:16:06

6

爲了清晰起見,我將假設您已經簡化了,並且正在使用智能指針或者至少正確地管理內存。

做到這一點,最簡單的方法是在第一類的一個別名:

class Foo 
{ 
    typedef FooProcessor Processor; 
    // Stuff. 
}; 

然後在模板中擺脫U和使用typename T::Processor代替。

+0

好吧,這比我的版本+1更簡單。 – 2012-02-08 16:19:38

1

我假設一個FooProcessor只能處理Foo,一個BarProcessor只能處理Bar,但其他類型可能有多個處理器類。因此,你可以做到這一點侵入:

class FooProcessor 
{ 
public: 
    typedef Foo value_type; 
}; 

class BarProcessor 
{ 
public: 
    typedef Bar value_type; 
}; 

您可以使用多態:所以它需要過程類作爲模板參數

template< typename T > 
class Processor 
{ 
public: 
    typedef T value_type; 
    virtual ~Processor() {} 
    virtual void process(value_type *) = 0; 
}; 

class FooProcessor : public Processor<Foo> 
{ 
    // implement process 
}; 

你可以使用一個適配器類像馬特·菲利普斯的,但在倒車時,:

template<typename T> 
class Spec 
{   
}; 

template<> class Spec<FooProcessor> 
{   
    typedef Foo type; 
};     

template<> class Spec<Bar>   
{   
    typedef BarProcessor type;   
};   

使用插入式輸入和Spec適配器鍵入您的ProcessEvent模板將使用處理器類型作爲參數,並使用value_type或type派生另一個。

使用多態性,您的ProcessEvent會將對象類型作爲參數(Foo或Bar),並且會傳遞一個處理器,該處理器派生自處理器或處理器以處理事件。

如果有大量的事件需要處理,並且它總是使用同一個對象處理它們,那麼後一種方法當然效率會稍低一點,因爲它是通過一個v-表處理的。這部分取決於他們處理多長時間以及是否可以內聯功能。

+0

中指定的原因選擇了這個答案。您提出了關於未來處理器類的可擴展性的一個好的觀點。 – user334066 2012-02-09 00:18:25

相關問題