Archived

This topic is now archived and is closed to further replies.

dynamic_cast

This topic is 5129 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a factory which holds an array of pointers to base classes. The base class has a virtual Draw() function, and what I want is to loop through each item in the factory, cast it to an appropriate inherited class (the base class has a typeID which I use in a switch statement to cast the pointer to the approptiate type), then call the inherited classes'' Draw() function. It calls the Draw function for the inherited type, but the this pointer is 0. Before I use dynamic_cast, the pointer is a valid pointer to a base class. Does this mean you can''t use dynamic_cast to upcast? How can I get it working? Or have I got it completely wrong and is there a much better way to do factories with inheritance. Thanx. --------------------------------------- Let''s struggle for our dream of Game! http://andrewporritt.4t.com

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
This is exactly the problem that virtual functions are designed to solve.

Share this post


Link to post
Share on other sites
if the draw() function is virtual, you don''t need to cast.

"BaseObjectPointer->Draw()" will call the appropriate Draw() function from the derived class.

Share this post


Link to post
Share on other sites
I must be doing something wrong then, cos it's just calling the base class function :S

I have a CFactory class, which is a template class. I then have a CBody base class, and a CRock class derrived from it. In my CSolarSystem class, I have:


CFactory<CBody> m_Bodies; // Bodies in the system



I add a rock to it like this:


m_Bodies.Add(&CRock(Mass, Position, Direction, Speed, Size));


My factory's add function looks like:


int Add(const T * newObject)
{
m_nObjectCount++;

// Allocate space for the new object

m_pObjects = (T**)realloc(m_pObjects, m_nObjectCount * sizeof(newObject));

// Copy the object to the end of the array

m_pObjects[m_nObjectCount - 1] = new T;
*(m_pObjects[m_nObjectCount - 1]) = *newObject;

return m_nObjectCount - 1;
}


In my base class I have:


virtual void Draw(LPDIRECT3DDEVICE9 pD3D) {} // Draws the object



And in the derrived class I have:


void Draw(LPDIRECT3DDEVICE9 pD3D); // Draws the rock



My draw function for the CSolarSystem class is like this:


void CSolarSystem::Draw(LPDIRECT3DDEVICE9 pD3D)
{
int NumBodies (m_Bodies.GetCount());

for(int temp = 0; temp < NumBodies; temp++)
{
m_Bodies.GetObject(temp)->Draw(pD3D);
}
}


But it just calls the base class Draw function, not the derrived version.

---------------------------------------

Let's struggle for our dream of Game!

http://andrewporritt.4t.com

[edited by - f8k8 on November 29, 2003 7:24:40 AM]

Share this post


Link to post
Share on other sites
Anyone? I think it''s because it''s casting the pointers to the base class, and so it''s loosing the derrived classes'' information (like which Draw function to call)

---------------------------------------

Let''s struggle for our dream of Game!

http://andrewporritt.4t.com

Share this post


Link to post
Share on other sites
quote:

int Add(const T * newObject)
{
m_nObjectCount++;

// Allocate space for the new object
m_pObjects = (T**)realloc(m_pObjects, m_nObjectCount * sizeof(newObject));

// Copy the object to the end of the array
m_pObjects[m_nObjectCount - 1] = new T;
*(m_pObjects[m_nObjectCount - 1]) = *newObject;

return m_nObjectCount - 1;
}



This function, my good sir, is an abomination . Mixing new and realloc is a ... mistake ... that will cost you dearly.

At any rate, since T is CBody you'll always be creating CBody (base) objects and nothing else.

As f8k8 points out, you're throwing away all the derived class information, a problem known as slicing (look it up).

Here's a suggestion for you:


class CBody
{
virtual CBody* New() const = 0;
virtual CBody* Clone() const = 0;
virtual ~CBody() {}:
};

class CRock : public CBody
{
virtual CBody* New() const { return new CRock; }
virtual CBody* Clone() const { return new CRock(*this); }
};

template<class T> class CFactory
{
std::vector<T*> prototypes;
public:

~CFactory()
{
std::vector<T*>::iterator itor;
for( itor = prototypes.begin();
itor != prototypes.end();
++itor )
delete *itor;
}

size_t Add(const T& proto)
{
prototypes.push_back( proto.Clone() );
return prototypes.size()-1;
};
}:



[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on November 29, 2003 8:03:22 AM]

Share this post


Link to post
Share on other sites