C ++ inheritance inheritance functions from a child of a parent class variable

In C ++, I have a base class package, and then a lot of children are APIPacket, DataIOPacket, etc. Now I want to save the incoming package, and since I do not know the type, I store it in a variable:

Packet packet; packet = DataIOPacket(); 

But now DataIOPacket has a getAnalogData () function; I cant:

 packet.getAnalogData(); 

Since the package does not have this feature. In java, I think this is possible, since the actual type of the object stored in the package is not lost (is this correct?). But in C ++, my DataIOPacket narrows in Packed and loses its functions that were not declared in the package.

You can make a virtual function in a package for each function in each child. But for me, this would mean a lot of functions in the package, which in most cases should not be called. Do not use the getAnalogData () call in APIPacket.

How is this problem resolved? I can’t find the answer, but I feel that many people should meet it.

You can do something with type casting in DataIOPacket and APIPacket, but it really doesn't seem like a clean solution.

Are there any libraries that solve my problem?

Rgds,

Roel

+4
source share
3 answers

This is possible in java and in C ++ too. you need to do dynamic_cast to check the type.

  Packet* packet; packet = new DataIOPacket(); DataIOPacket dio* = dynamic_cast<DataIOPacket*>(packet); if (dio != 0) { dio->DoSomeChildMethodStuff(); } 
+4
source

in C ++ my DataIOPacket tapers to Packet and loses functions that were not declared in Packet

This happens because you assign an object of type DataIOPacket object of type Packet , which leads to the fact that this object is sliced ​​(see What is cropping of objects? ).

What you are really looking for is a way that you could find out at runtime whether the object you are working with was created as an instance of a DataIOPacket . In other words, you are looking for Runtime Type Identification (RTTI) .

To avoid slicing, you need to have a link or pointer to an object. The type of this object will be identified at runtime:

 Packet* packet; packet = new DataIOPacket(); 

now Packet is a pointer to an object of type DataIOPacket (runtime), but the pointer type is Packet* (compilation time). To call a method specific to the DataIOPacket class for this object, the compiler needs to know that this pointer points to an object of the type that this method provides. The correct way to reset a pointer to a polymorphic type is to use dynamic_cast , which returns NULL if this object cannot be passed to this type:

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

Please note that this is also possible for objects with automatic storage duration:

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

In this case, the Packet type is the decisive factor that decides whether dynamic_cast succeed or not. The object must be created as an instance of DataIOPacket to call the getAnalogData method on it.

+1
source

Well, I realized that some people have suggested that having a dynamic throw suggests that my structure is erroneous. Therefore, I am going to change the fact that each type of package gets its own storage space. I store the packages in which I read them, and then they are transferred to the main thread, which does all the processing. Indeed, it makes sense that you save the type. My main thread does not want to determine what type of packages it has, since it has a different way of handling different packages. If you ever need the behavior that I described in my question, I think dynamic casting is the way to go. But before you do this, you should really ask yourself if you should change the structure. And the use of dynamic casting will not work on objects, since they are cut. It only works with pointers.

0
source

Source: https://habr.com/ru/post/1469297/


All Articles