11

In C++ we can convert child class pointer to parent, but is there any way to convert it back: from parent, which was obtained from child, give child class back?

I mean:

class Parent { ... }; class Child : public Parent { ... }; int main(int argc, char const *argv[]) { Child* child = new Child(); Parent* parent = child; Child* old_child = parent; // how to do this?? return 0; } 

Thank you for your answers.

8
  • 3
    Child* old_child = dynamic_cast<Child*>(parent); Commented Jul 20, 2014 at 13:42
  • 3
    Yes. static_cast<> and dynamic_cast<> can be used to do this. Commented Jul 20, 2014 at 13:42
  • @david.pfx I've bothered marking this as duplicate, so just applied the link as a commentary. Commented Jul 20, 2014 at 14:10
  • 1
    Needing to do this usually indicates bad design. You should have a virtual function callable from a parent pointer. Commented Jul 20, 2014 at 14:52
  • Child* old_child = child; Commented Jul 20, 2014 at 15:37

4 Answers 4

18

"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<Child*>(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 Derived> class Parent { void someFunc() { static_cast<Derived*>(this)->doSomething(); } }; class Child : public Parent<Child> { 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
Sign up to request clarification or add additional context in comments.

3 Comments

The result of the dynamic_cast can be ... iff the base class is a true polymorphic type, aka has at least one virtual function or base. Otherwise it degrades to static_cast (It will be strength-reduced to static_cast when provably correct in any case).
@Deduplicator THX! Better now?
Yes, +1. BTW: Using = default; instead of {} for the dtor body might be slightly longer but does not prevent the class from being trivial, with all attendent benefits (though it needs a slightly more modern compiler).
2

You need to cast the object back to child. This is done like this:

 Child * old_child = static_cast<Child*>(parent); 

and

 Child * old_child = dynamic_cast<Child*>(parent); 

1 Comment

Would you mind to explain a bit more about the differences and actual behavior of these two cast methods.
2
int main() { Parent parent; Child child; // upcast - implicit type cast allowed Parent *pParent = &child; // downcast - explicit type case required Child *pChild = (Child *) &parent; } 

You should use the dynamic_cast to do this safely:

Child *p = dynamic_cast<Child *>(pParent) 

EDIT

With dynamic_cast returns a null pointer if the type is not apart of the base class, also casting to a reference throws a bad_cast exception. dynamic_cast is particularly useful if you do not know what the object type will be.

On the other hand static_cast:

Child *p = static_cast<Child *>(pParent) 

This assumes that you want to reverse an explicit conversion and perform no runtime checks. This allows for flexibility but must be used with caution.

The regular downcast shown above:

Child *pChild = (Child *) &parent; 

Is a C-style down cast (like a static_cast), which may also cast to a private base class (not sure about, multiple inheritance), while static_cast would cause a compile-time error. Things like numeric conversions is a good example to use this on.

1 Comment

updated answer to explain a bit about the safety issues
0

Above answers are good, conceptually you can think like this,

Your Car object which is derived from Vehicle class. You can refer Car as Vehicle, and can convert to Car as it originally belonged to Car. But it will be a problem if your Vehicle object actually representing Bike and trying to convert to Car. Thats why you need safe casting.

class Vehicle { ... }; class Car : public Vehicle { ... }; class Bike : public Vehicle { ... }; int main(int argc, char const *argv[]) { Vehicle* vehicle = new Car(); Car* old_car = dynamic_cast<Car *>(vehicle); if(old_car) { // OK Vehicle is Car, use it } vehicle = new Bike(); old_car = dynamic_cast<Car *>(vehicle); if(old_car) { // No Vehicle isn't Car, this code won't execute } return 0; } 

1 Comment

In which way this answer adds any value compared to the other answers, besides replacing Parent/Child with a Vehicle/Car metaphor?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.