#include <iostream> using namespace std; class Base { public: Base() {}; ~Base() {}; }; template<class T> class Derived: public Base { T _val; public: Derived() {} Derived(T val): _val(val) {} T raw() {return _val;} }; int main() { Base * b = new Derived<int>(1); Derived<int> * d = b; cout << d->raw() << endl; return 0; }
I have some polymorphism problem right now and the code above summarizes everything. I created a Base class pointer and I put the pointer of a new derived template class in it. Then I created a new pointer for the derived template class and I want it to have the reference the base class pointer points to. Even though Base pointer (b) points to a Derived, the reference cannot be passed to Derived class pointer (d) because there's no known conversion from Base * to Derived<int> *
(as what the compiler says).
So is there a trick or an alternative way to be able to do it? Thanks in advance.
Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.
Likewise, a reference to base class can be converted to a reference to derived class using static_cast . If the source type is polymorphic, dynamic_cast can be used to perform a base to derived conversion.
Derived class pointer cannot point to base class.
If you have a base class object, there is no way to "cast" it to a derived class object. In that case you would need to create a derived class object.
You must change the base type to be polymorphic:
class Base { public: Base() {}; virtual ~Base(){}; };
To cast from some supertype to some derived type, you should use dynamic_cast
:
Base *b = new Derived<int>(1); Derived<int> *d = dynamic_cast<Derived<int> *>(b);
Using dynamic_cast
here checks that the typecast is possible. If there is no need to do that check (because the cast cannot fail), you can also use static_cast
:
Base *b = new Derived<int>(1); Derived<int> *d = static_cast<Derived<int> *>(b);
Try this:
Derived<int> * d = static_cast<Derived<int>* >(b);
downside it is, that you can cast class that is instance of Base() and then d->raw() will be undefined (segmentation fault likley). If that can be case, use dynamic_cast and have at least one function ob base virtual (having destructors virtual is essential when working with polmorphism).
Virtual functions are under the hood implemented using pointer on virtual table. This pointer can be also used to identify true type of class. This is used by dynamic_cast to check if this conversion can be done and brings small extra overhead when casted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With