"but is there any way to convert it back: from parent, which was obtained from child, give child class back?"
Yes, as mentioned in the other answers, there are two ways to do this.
Child * old_child = dynamic_cast(parent);
The result of the dynamic_cast<> can be checked at runtime, thus you can determine if the parent
object really represents a Child
instance:
if(!old_child) {
// parent is not a Child instance
}
Also note to get this working properly, the classes in question need to have a vtable, that RTTI can actually determine their relation. The simplest form to achieve this, is giving the Parent
class a virtual destructor function
class Parent {
public:
virtual ~Parent() {}
// or
// virtual ~Parent() = default;
// as suggested for latest standards
};
NOTE:
If this should apply to a general design decision, I would strongly disregard it. Use pure virtual interfaces instead, that are guaranteed to be implemented, or not.
The second way of static_cast<> can be used in environments, where you well know that parent
actually is a child. The simplest form of this is the CRTP, where Parent
takes the inheriting class as a template parameter
template
class Parent {
void someFunc() {
static_cast(this)->doSomething();
}
};
class Child : public Parent {
public:
void doSomething();
};
The validity of an instatiation of Parent<>
and static_cast<>
will be checked at compile time.
NOTE:
Another advantage is that you can use an interface for derived that makes use of
- static class members of
Derived
typedef
's provided by Derived
- ... more class traits, that can be checked at compile time