I write quite a lot of code which processes message protocols. Quite often a message protocol will have a generic message frame which can be deserialised from a serial port or socket; the frame contains a message type, and the message payload must be processed based on the message type.
Normally I write a polymorphic set of classes with accessor methods and a constructor which takes a reference to the message frame.
It occurs to me though that instead of constructing an accessor class based on a reference to the message frame, I could just derive the accessor classes directly from the message frame, and then reinterpret_cast from the message frame to the appropriate accessor class. This makes the code more concise and saves some bytes and processor cycles.
See the (extremely contrived and condensed) example below. Obviously for production code this would all need to be properly encapsulated, the cast made a member of the derived class, better separation of concerns imposed, and some validation added. This has all been removed for the sake of putting together a concise example.
#include <iostream>
#include <cstring>
#include <vector>
struct GenericMessage
{
GenericMessage(const char* body):body_(body, body+strlen(body)){}
std::vector<char> body_;
};
struct MessageType1:public GenericMessage
{
int GetFoo()const
{
return body_[2];
}
int GetBar()const
{
return body_[3];
}
};
int main()
{
GenericMessage myGenericMessage("1234");
MessageType1* myMgessageType1 = reinterpret_cast<MessageType1*>(&myGenericMessage);
std::cout << "Foo:" << myMgessageType1->GetFoo() << std::endl;
std::cout << "Bar:" << myMgessageType1->GetBar() << std::endl;
return 0;
}
I've never see this done anywhere. Is there any downside to casting from base to derived in this way, given that derived has no additional data members?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…