首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在这种情况下应该使用C++模板吗?

在这种情况下应该使用C++模板吗?
EN

Stack Overflow用户
提问于 2009-03-25 00:09:52
回答 3查看 262关注 0票数 1

我有一个类,我的客户使用它来获取()一个包。该数据包包含一个std::vector,其类型直到在我的Interface类中内部生成数据包时才知道(在本例中,它取决于Packet::type变量)。

我想知道是否可以使用模板,因为Packet类只是一个泛型类,它的类型几乎可以是任何类型。

据我所知,它的问题在于,客户端在获得数据包并查看Packet::type成员之前,不知道它是什么类型的数据包。因此,这将不起作用,因为他不能声明Get()将返回(?)的变量。

在这种情况下,模板能被优雅地使用吗?

我能想到的一个替代方案是定义一个基类,并为每种类型创建一个子类。然后,Get()方法可以返回一个指向基类的指针。然后,客户端可以简单地查看Packet::type (packet->type)并将其转换为适当的子类。但这有点乱吗?有没有更优雅的解决方案?

下面的代码大致演示了这个场景:

代码语言:javascript
运行
复制
enum
{
  T_FLOAT,
  T_COMPLEX
} TYPE_ENUM;

// T can either be of type float or std::complex
template<typename T>
class Packet
{
public:
  TYPE_ENUM       type;
  std::vector<T>  data;
};

class Interface
{

public:
  // Method that client calls to obtain the packet
  Packet<>  Get()
  {
    return queue.pop(); // return current packet in queue
  }

private:
  Queue<Packet>   queue;
};
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-03-25 00:15:10

您可能希望创建一个基类,并保留已有的模板包类。将此基类称为PacketBase。您的数据包类将派生自新的PacketBase类。也就是说,在编译时生成的每个Packet<>类型都将从PacketBase派生。

代码语言:javascript
运行
复制
class PacketBase
{ 
};

// T can either be of type float or std::complex or ...
template<typename T>
class Packet : public PacketBase
{
public:
  std::vector<T>  data;

  //Put other members you need here
  //Note you don't need the type member that you had before. 
};

Interface::Get将返回一个PacketBase*。在这里,PacketBase只是用作包含任何Packet<>类型的泛型名称。队列将存储PacketBase*的集合。

代码语言:javascript
运行
复制
class Interface
{

public:
  // Method that client calls to obtain the packet
  PacketBase*  Get()
  {
    return queue.pop(); // return current packet in queue
  }

private:
  Queue<PacketBase*>   queue;
};

要弄清楚您拥有的是哪种类型的数据包,可以在dynamic_cast中使用RTTI。

代码语言:javascript
运行
复制
InterfaceObject o;
//fill the queue
PacketBase *pPacket = o.Get();
if(dynamic_cast<Packet<float> * >(pPacket) != NULL)
   ;//You have a Packet<float>
else if(dynamic_cast<Packet<std::complex> * >(pPacket) != NULL)
   ;//You have a Packet<std::complex>
//... for each Packet<> type you have

您还可以使用一些虚拟方法来增强您的PacketBase。然后你可以直接调用它们,而不是RTTI dynamic_cast的东西。

票数 3
EN

Stack Overflow用户

发布于 2009-03-25 00:16:08

模板都是关于编译时的类型解析...如果直到运行时才能确定类型,那么就不适合应用模板。

您需要让运行时切换到您所描述的最终数据包类型。

票数 8
EN

Stack Overflow用户

发布于 2009-03-25 00:17:00

对数据包类型的操作使用抽象基类和虚拟方法。您不应该需要强制转换packet类。一个模板化的类集合是有问题的--你在其中添加和删除项目时会遇到麻烦。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/679759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档