4

在 C++ 中,我有一个基类 Packet,然后是很多子类 APIPacket、DataIOPacket 等。现在我想存储一个传入的数据包,因为我不知道类型,所以我将它存储在一个变量中:

Packet packet;
packet = DataIOPacket();

但是现在 DataIOPacket 有一个函数 getAnalogData(); 我不能这样做:

packet.getAnalogData();

由于包没有这个功能。在java中我认为这是可能的,因为存储在数据包中的对象的实际类型没有丢失(这是正确的吗?)。但是在 C++ 中,我的 DataIOPacket 被缩小为 Packed 并丢失了尚未在 Packet 中声明的功能。

您可以在 Packet 中为每个孩子的每个功能创建一个虚拟功能。但对我来说,这意味着 Packet 中有很多函数在大多数情况下不应该被调用。在 APIPacket 上调用 getAnalogData() 没有用。

这个问题是如何解决的?我找不到答案,但我觉得很多人必须遇到它。

您可以通过类型转换回 DataIOPacket 和 APIPacket 来做一些事情,但这似乎也不是一个干净的解决方案。

是否有图书馆可以解决我的问题?

Rgds,

罗尔

4

3 回答 3

4

这在 java 和 c++ 中也是可能的。你需要做一个 dynamic_cast 来检查类型。

 Packet* packet;
packet = new DataIOPacket();

      DataIOPacket dio* = dynamic_cast<DataIOPacket*>(packet); 
            if (dio != 0)
            {
             dio->DoSomeChildMethodStuff();
            }
于 2013-03-14T16:51:33.027 回答
1

在 C++ 中,我DataIOPacket被缩小为 aPacket并丢失了尚未在其中声明的函数Packet

发生这种情况是因为您将 type 的对象分配给 typeDataIOPacket的对象Packet,这导致该对象被切片(请参阅什么是对象切片?)。

您实际上正在寻找的是一种如何在运行时找出您正在使用的对象是否已创建为DataIOPacket. 换句话说,您正在寻找Run-Time Type Identification (RTTI)

为避免切片,您需要有一个对象的引用或指针。然后将在运行时识别此对象的类型:

Packet* packet;
packet = new DataIOPacket();

nowpacket是指向对象类型DataIOPacket运行时)的指针,但指针的类型是Packet*编译时)。为了DataIOPacket在这个对象上调用特定于类的方法,编译器需要知道这个指针指向提供该方法的类型的对象。向下转换指向多态类型的指针的正确方法是使用,如果该对象无法转换为该类型dynamic_cast,则返回:NULL

Packet* packet;
packet = new DataIOPacket();
DataIOPacket* dataIOPacket = dynamic_cast<DataIOPacket*>(packet);
if (dataIOPacket)
    dataIOPacket->getAnalogData();

请注意,这也适用于具有自动存储持续时间的对象:

DataIOPacket packet;
Packet* pPacket = &packet;

DataIOPacket* dataIOPacket = dynamic_cast<DataIOPacket*>(pPacket);
if (dataIOPacket)
    dataIOPacket->getAnalogData();

在这种情况下,类型是决定是否成功packet的关键因素。dynamic_cast必须将对象创建为的实例DataIOPacket才能调用其getAnalogData上的方法。

于 2013-03-14T17:08:52.483 回答
0

好的,我像某些人建议的那样发现,必须进行动态转换表明我的结构是错误的。所以我要改变每种类型的数据包都有自己的存储空间。我将数据包存储在读取它们的位置,然后将它们传递到执行所有处理的主线程。实际上,保留类型更有意义。我的主线程不想弄清楚数据包的类型,因为它有不同的方式来处理不同的数据包。如果您需要我在问题中描述的行为,我认为动态演员是要走的路。但在这样做之前,你应该真正问问自己是否不应该改变结构。并且使用动态转换对对象不起作用,因为它们正在进行切片。它仅适用于指针。

于 2013-03-14T21:05:08.527 回答