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
};
4

4 回答 4

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>出于同样的原因,您将需要做同样的事情

注意: 通常你会想要放弃模板而简单地使用继承,因为模板最终并不是绝对必要的。当然,这取决于情况,但偶尔查看模板代码并思考“我可以撕掉模板吗?”总是好的。

于 2012-11-12T17:49:06.153 回答
0

Without seeing the full template of ProtocolDecoder I can't sure for sure whether this will work for your application, but I would pull the interface into its own class. Then your HandleMessages() class just has a pointer/reference to the interface and doesn't care about the template.

Program to an interface, not an implementation: What does it mean to "program to an interface"?

于 2012-11-12T17:56:33.933 回答
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
};
于 2012-11-12T17:57:03.373 回答
0

补充一点已经说过的其他事情:我认为在这里做出决定的主要问题是模板是在编译时决定的,而您需要多态性或类似的东西才能在运行时做出类似的选择。

于 2012-11-12T18:08:23.487 回答