Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ - converting a base class pointer to a derived class pointer

#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.

like image 438
Andy Autida Avatar asked Sep 18 '13 13:09

Andy Autida


People also ask

How a base class pointer can be converted to derived class member?

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.

Can you cast from base class to derived?

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.

Can a derived class pointer point to a base class object?

Derived class pointer cannot point to base class.

Can you cast a base class to a derived class in C++?

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.


2 Answers

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); 
like image 80
Abrixas2 Avatar answered Sep 25 '22 02:09

Abrixas2


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.

like image 27
Luka Rahne Avatar answered Sep 23 '22 02:09

Luka Rahne