Reputation: 4106
I have 3 classes. One is a base, one is a parent and one is a child. The parent is instantiated at some point and assigned data. In some cases it is used directly but in others there is a need for functionality implemented in its child class.
What I would like to do is to cast the parent object into child object so its virtual functions would be used with parent's data:
class UndoBase : public QUndoCommand
{
public:
UndoBase() {}
virtual void undo() = 0;
virtual void redo() = 0;
};
class CommandParent : public UndoBase
{
public:
CommandParent() {}
virtual void undo()
virtual void redo()
protected:
someType data
};
class CommandChild : public CommandParent
{
public:
CommandChild() {}
virtual void undo() //overrides parent
virtual void redo() //overrides parent
};
I have tried this:
CommandParent *parent = new CommandParent;
//assign data
UndoBase *command = static_cast<CommandChild*>(parent);
command->redo();
And it worked (used the CommandChild implementation and CommandParent data) although I would swear it should be undefined behaviour (that could work too, I know). Since I doubt this is the right thing to do I would like to ask if this is ok or if there is other ways beside composition.
Upvotes: 0
Views: 161
Reputation: 10733
UndoBase *command = static_cast<CommandChild*>(parent);
This is all hell at every inch of this line. You are telling to static_cast to cast to CommandChild whereas you are storing it in UndoBase .
Also you are trying to cast CommandParent to CommandChild means Base to Derived where Base class has no knowledge of derived cast. Even if you write it properly.
CommandChild *child = static_cast<CommandChild*>(parent);
it would be erroneous.Apart from that always use dynamic_cast for these cases. It explicitly checks whether cast is possible or not.dynamic_cast will cast properly if cast is safe OR returns NULL (in case of pointers, for references it throws bad_cast exception ) if its not able to cast to target type.
Upvotes: 2
Reputation: 31
You have to create an new instance of CommandChild with the data from CommandParent using the copy constructor.
UndoBase *command = new CommandChild(*parent);
Upvotes: -1