I have a source of some lines of text, each of which is a message, representing object of some type. I'm making a parser for these lines, which should take the text line as input and give the ready to use object as output. So I make the following hierarchy of classes:
class Message
{
public:
virtual ~Message(){};
};
class ObjectTypeA : public Message
{/*...*/};
class ObjectTypeB : public Message
{/*...*/};
class ObjectTypeC : public Message
{/*...*/};
and here's how it's used:
std::shared_ptr<Message> parseLine(std::string& line);
void doWork()
{
std::string line;
while(getLine(line))
{
std::shared_ptr<Message> object=parseLine(line);
if(dynamic_cast<ObjectTypeA*>(object.get()))
doSomethingA(*static_cast<ObjectTypeA*>(object.get()));
else if(dynamic_cast<ObjectTypeB*>(object.get()))
doCompletelyUnrelatedProcessing(*static_cast<ObjectTypeB*>(object.get()));
else if(dynamic_cast<ObjectTypeC*>(object.get()))
doSomethingEvenMoreDifferent(*static_cast<ObjectTypeC*>(object.get()));
}
}
Here the parser would be a library function, and the objects don't know in advance how they will be processed. So, I can't put the processing code to a virtual function of Message
implementations.
But many of the answers in this question say that if one needs to check type of the object, it's a sign of bad design. But I can't seem to see what's bad here. Is there any better way to organize the solution?