Sign in to follow this  
BloodLust666

reinterpret_cast

Recommended Posts

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?


Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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[I];
InternalRepList.clear();
}


HTH Paul

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this