2012-11-12 95 views
0

下面的HandleMessages類具有類型爲ProtocolDecoder *的成員變量。當ProtocolDecoder不是模板類時,這很好。現在我改變了,但現在代碼不能編譯。如何指定其類爲模板的成員變量(組合)

在運行時有一個工廠函數可以創建所需的解碼器。

如果我不能有一個m_Decoder成員,那我該如何達到同樣的效果?

如果我嘗試聲明成員爲ProtocolDecoder * m_Decoder;

我得到編譯器錯誤:錯誤 C2059:語法錯誤:「<」

,看看參考類模板實例「LogPlayer」正在編制

template <typename T> 
class ProtocolDecoder 
{ 
public: 
    virtual const char* ProtocolName() = 0; 
    virtual ProtoWrapper<T>* DecodeMsg(const unsigned char* msg, int length) = 0; 
... 
}; 

class ABCDecoder : public ProtocolDecoder<ABC_msg> 
{ 
public: 
    virtual const char* ProtocolName() {return "ABC"; } 

    virtual ProtoWrapper<ABC_msg>* DecodeMsg(const unsigned char* msg, int length); 
}; 

//lots of different decoders derived from ProtocolHandler 

class HandleMessages 
{ 
public: 
void Process() {} 

private: 
//ProtocolDecoder<T>*  m_Decoder; //Want a Protocol member variable - but don't know type until runtime 
}; 
+0

但重點是它直到運行時才知道哪種類型的m_Decoder應該是。 –

+0

@ user619818:對不起,我誤讀了。沒關係! –

回答

1

不能使用模板對象在不指定模板參數的情況下,僅當所有參數具有值時才存在模板類型。

所以雖然ProtocolDecoder<int>*是一個真正的類型,ProtocolDecoder<T>*不是。你可能想要在這裏做一個抽象基類,所有的模板類派生自。然後,您可以簡單地將它們上傳到基本類型並以這種方式存儲它們。

因此,例如,

class BaseProtocolDecoder 
{ 
public: 
    virtual const char* ProtocolName() = 0; 
    virtual BaseProtoWrapper* DecodeMsg(const unsigned char* msg, int length) = 0; 
... 
}; 

template <typename T> 
class ProtocolDecoder : BaseProtocolDecoder 
{ 
public: 
    const char* ProtocolName(); 
    BaseProtoWrapper* DecodeMsg(const unsigned char* msg, int length); 
... 
}; 

template<> 
ProtocolDecoder<ABC_msg> 
{ 
public: 
    const char* ProtocolName() {return "ABC"; } 

    BaseProtoWrapper* DecodeMsg(const unsigned char* msg, int length); 
}; 

你需要做同樣的事情ProtoWrapper<T>,出於同樣的原因

注: 通常你會希望溝模板和簡單的使用的傳承,因爲模板最終不是絕對必要的。當然,這取決於具體情況,但偶爾查看模板代碼總是很好,並且認爲「我可以撕掉模板嗎?」

+0

從上面的代碼是true,但我確實需要真實代碼的模板。 –

0

沒有看到ProtocolDecoder的完整模板,我無法確定這是否適用於您的應用程序,但我會將接口拉入自己的類。然後你的HandleMessages()類只有一個指向接口的指針/引用,並且不關心模板。

計劃到接口,而不是實現:What does it mean to "program to an interface"?

0
class BaseWrapper 
{ 
}; 

template <class T> 
class ProtoWrapper: public BaseWrapper 
{ 
}; 

class BaseDecoder 
{ 
    virtual const char* ProtocolName() = 0; 
    virtual BaseWrapper* DecodeMsg(const unsigned char* msg, int length) = 0; 
}; 

template <typename T> 
class ProtocolDecoder: public BaseDecoder 
{ 
public: 
... // template specific code 
}; 

class ABCDecoder : public ProtocolDecoder<ABC_msg> 
{ 
public: 
    virtual const char* ProtocolName() {return "ABC"; } 

    virtual ProtoWrapper<ABC_msg>* DecodeMsg(const unsigned char* msg, int length); 
}; 

class HandleMessages 
{ 
public: 
void Process() {} 

private: 
BaseDecoder*  m_Decoder; //Want a Protocol member variable - but don't know type until runtime 
}; 
0

要一點點添加到已經說其他的東西:我認爲應該在這裏做決定的主要問題是,模板決定在編譯時,當你需要多態性或類似的東西在運行時做出這樣的選擇。

相關問題