reinterpret_cast

Started by
2 comments, last by Aardvajk 17 years, 6 months ago
I have a class that has a template. The template is of a base class that I have many other classes deriving from. Only thing is in my template, when i call a function Add() it creates a "new" object and returns the pointer to it (in my template i store a vector of MY templated class so when i Add() it it creates a new one, adds it to the vector list and returns a pointer). Is there a way to somehow use reinterpret_cast to have a pointer to my child classes when i Add() it. here's an example and what i have so far

class cEnemy;
class cEnemy1 : public cEnemy;
class cEnemy2 : public cEnemy;
class cEnemy3 : public cEnemy;

class cLevel
{
public:
   tMyVector<cEnemy>    EnemyList;
...
};

cEnemy1 *newEnemy = EnemyList.Add() // does vector<cEnemy*>.push_back() 
// yes they are stored internally as pointers
// only thing is the Add() would return a cEnemy NOT a cEnemy1 or could do:
// cEnemy1 *newEnemy = reinterpret_cast<cEnemy1>(EnemyList.Add());
// to do it correctly?


-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
Advertisement
A reinterpret_cast from CEnemy to a derived class (CEnemy1 for instance) is not guaranteed to work - it depends on the inheritance hierarchy. Pointers to base members could be different to a pointer to a derived class. Off the top of my head there are two ways to solve this:
1) Use dynamic_cast, but that requires RTTI
2) Have a pure virtual function in the base class:
class Base{public:  virtual void *GetThisPointer (void) = 0;};

and in the derived class:
class Derived : public Base{private:  virtual void *GetThisPointer (void) { return this; }};

Then you can upcast by doing:
Base *obj = new Derived;Derived *obj2 = reinterpret_cast <Derived *> (obj->GetThisPointer ());

This is only safe if you know that obj is definately of type Derived. If obj was of type Derived2 then things can go a bit wrong.

Skizz

Skizz has solved your casting problem, but what you're doing doesn't look like it makes any sense... You should be adding derived instances to your array and accessing them via the base, but it appears you're adding base instances to your array and trying to force them to be derived instances...

Jans.

Jansic is quite correct.

A better approach would be for your EnemyList class to have an Add method a bit like this:

CEnemy *EnemyList::Add(CEnemy *E){    InternalRepList.push_back(E); return E; // or whatever}


Where you then use the list in code, you can do this:

EnemyList.Add(new CEnemy1());


Or, avoiding this particular need to cast at all:

CEnemy1 *E=new CEnemy1();EnemyList.Add(E);DoStuffWithCEnemy1(E);


This maintains the design that your EnemyList need only "know" about the CEnemy base class, not any of the derived classes.

I'd hope it goes without saying that if you are storing pointers in a std::vector like this, you need to manually delete them. The vector going out of scope or having std::vector::clear() called will only delete the pointers, not the objects pointed to.

void CEnemyList::Clear() // also called by ~CEnemyList{    for(unsigned I=0;I<InternalRepList.size();++I) delete InternalRepList;    InternalRepList.clear();}


HTH Paul

This topic is closed to new replies.

Advertisement