[英]C++ inheritance calling functions from child on a variable of the parent class
在C ++中,我有一个基类包,然后有很多孩子APIPacket,DataIOPacket等。现在我想存储一个传入的数据包,因为我不知道我在变量中存储它的类型:
Packet packet;
packet = DataIOPacket();
但是现在DataIOPacket有一个函数getAnalogData(); 我做不到:
packet.getAnalogData();
由于数据包没有此功能。 在java中我认为这是可能的,因为存储在数据包中的对象的实际类型不会丢失(这是正确的吗?)。 但是在C ++中,我的DataIOPacket缩小为Packed并丢失了尚未在Packet中声明的函数。
您可以在Packet中为每个孩子的每个功能创建一个虚拟功能。 但对我来说,这意味着Packet中的许多功能在大多数情况下都不应该被调用。 在APIPacket上调用getAnalogData()是没有用的。
这个问题怎么解决了? 我找不到答案,但我觉得很多人都必须遇到它。
您可以通过类型转换回DataIOPacket和APIPacket来做一些事情,但这似乎也不是一个干净的解决方案。
是否有可能解决我问题的库?
RGDS,
罗埃尔
这在java和c ++中也是可能的。 你需要做一个dynamic_cast来检查类型。
Packet* packet;
packet = new DataIOPacket();
DataIOPacket dio* = dynamic_cast<DataIOPacket*>(packet);
if (dio != 0)
{
dio->DoSomeChildMethodStuff();
}
在C ++中,我的
DataIOPacket
被缩小为一个Packet
并丢失了尚未在Packet
声明的功能
之所以发生这种情况,是因为您将DataIOPacket
类型的对象分配给Packet
类型的对象,这会导致此对象被切片 (请参阅什么是对象切片? )。
您实际需要的是一种如何在运行时找到您正在使用的对象是否已创建为DataIOPacket
实例的DataIOPacket
。 换句话说,您正在寻找运行时类型识别(RTTI) 。
要避免切片 ,您需要有一个引用或指向该对象的指针。 然后将在运行时标识此对象的类型:
Packet* packet;
packet = new DataIOPacket();
now packet
是指向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
的实例DataIOPacket
在其上调用getAnalogData
方法。
好吧我想像有些人建议的那样,不得不进行动态演员表明我的结构是错误的。 所以我要改变每种类型的数据包获得它自己的存储空间的事情。 我将数据包存储在我读取的位置,然后将它们传递给执行所有处理的主线程。 确实你保持这种类型更有意义。 我的主线程不想弄清楚数据包的类型,因为它有不同的方式来处理不同的数据包。 如果你需要我在我的问题中描述的行为,我认为动态演员是要走的路。 但在这样做之前,你应该问自己是否应该改变结构。 并且使用动态强制转换不会对对象起作用,因为它们正在进行切片。 它只适用于指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.