Jump to content
  • Advertisement
Sign in to follow this  
Valor Knight

Casting up to a derived class [solved]

This topic is 4291 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

This is my situation: Class A Class B : public A function( A &input ) { //I need to cast input (currently A) to a B class } I need to cast the input from a base class to the required class. Why I need to do this is because I have a component or something that has functions I need to access outside of the base class. The current situation is I have a window class and a MSWindow class. As I dont know if linux, ect uses HWND, I have a class derived from window, MSWindow, which has a GetHWND() function. I will also need to use this later on in a component manager. I know static_cast<> can cast down B to A. dynamic_cast<> can cast up (I think) But I was told never to use dynamic casting in a game. How can I cast my input to the correct class? Also is HWND used for linux/mac as well? trying for api independence and dont want a base class with a MS only handle. [Edited by - Valor Knight on October 22, 2006 6:59:09 PM]

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Quote:
Original post by Valor Knight
I know static_cast<> can cast down B to A. dynamic_cast<> can cast up (I think) But I was told never to use dynamic casting in a game. How can I cast my input to the correct class?


dynamic_cast is perfectly fine in games too.

Quote:
Original post by Valor Knight
Also is HWND used for linux/mac as well? trying for api independence and dont want a base class with a MS only handle.


No HWND is not used on those platforms. If you want a platform independent windowing API for all the three platforms you mentioned, I can recommend wxWidgets: http://www.wxwidgets.org.

Share this post


Link to post
Share on other sites
If you are 100% absolutely undoubtedly sure that you do have an object of type B, then you can use static_cast<B&>(input). If you can't guarantee that, use dynamic_cast<B&>(input), which will throw an std::bad_cast exception if you really didn't have a B (or derived). When casting pointers (i.e. dynamic_cast<B*>(&input)), you instead get a null pointer if the cast fails.

Quote:
But I was told never to use dynamic casting in a game.


That's bullshit. There is nothing else you can use here. The tools are there, use them when you need them, otherwise you'll waste time coming up with a solution that's likely to both be slower and less maintainable.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
HWND is windows only. But it's just a typedef'd type, like a DWORD is an unsigned long. You can make your variable of the base type and be ok as long as the other OS's use the same or smaller sized types for their IDs.

Or, wrap the code in #ifdef's/#endif's or other solutions mentioned on this site by others (I do the #ifdef way, personally like it better then other solutions I've seen so far).

Share this post


Link to post
Share on other sites
Quote:
Original post by Fruny
Quote:
But I was told never to use dynamic casting in a game.


That's bullshit. There is nothing else you can use here. The tools are there, use them when you need them, otherwise you'll waste time coming up with a solution that's likely to both be slower and less maintainable.


I'll mantain that a virtual functions are usable - and often more mantainable - "here" (where here is the problem you're trying to solve using upcasting). That said, there are situations where dynamic_cast is the superior solution, and it is definately usable in game code.

Use it the wrong way, and yes, your performance will tank. For example, you don't want to try and dynamic_cast individual pixels in a screen buffer array. That said, 99.999% of C++, if used the wrong way, will simply invoke undefined behavior and crash in a messy, hard to track down or predict way, so this is really more of a benifit to dynamic_cast<>s than anything else.



In this case, it smells a bit like design rot. On linux, the system should never get an MSWindow. On windows, the system should never not get one. As such, I'd expect this kind of thing to be checked and verified at compile time, not run time. Just a thought.

[Edited by - MaulingMonkey on October 21, 2006 8:39:39 PM]

Share this post


Link to post
Share on other sites
This is exactly one of the very few situations I've needed to use dynamic_cast, and it's perfectly fine as long as you know why you are using it. It can hint at a bad design, but I use it to get the HWND when I'm setting up DirectX.

Share this post


Link to post
Share on other sites
When creating platform-dependant classes I tend to take a different approach and not use inheritence at all. In your case if you have a class called PlatformWindow and derived classes MSPlatformWindow and LinuxPlatformWindow, what I do instead is this...


//------------------
// PlatformWindow.h

struct PlatformWindowHandle;

class PlatformWindow
{
public:
const PlatformWindowHandle& GetHandle() const { return *m_handle; }
private:
std::auto_ptr<PlatformWindowHandle> m_handle;
}

//------------------
// Win32Impl.h

struct PlatformWindowHandle
{
HWND hWnd;
};

//------------------
// LinuxImpl.h

struct PlatformWindowHandle
{
int handle;
};




You do something similar for each of your platform-dependant classes, and then have a single header that defines the various platform-dependant structs such as PlatformWindowHandle that contain your HWND. The important part here is that the PlatformWindowHandle type is not defined in the PlatformWindow header, and you only deal with pointers & references to it. This allows you to hide the platform-specific details while still providing access to platform-specific data, without having to rely on pointless inheritence (since you need to recompile for each platform, the desired platform-specific class is known at compile-time).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
@joanusdmentia:
That's a really good idea. Then just #ifdef around the headers you need.

Share this post


Link to post
Share on other sites
Thanks for the info on dynamic_cast. I will ignore what that person said about it. Thanks for the input


As for the HWND: I should have thought of this earlier but I just came up with. I dont know what I was thinking about the dervied classes (when I wrote it, it looked stupid to me):

#ifdef WIN32
typedef HWND WinHandle;
#endif

classWindow
{
WinHandle GetWindowHandle();
};

Share this post


Link to post
Share on other sites
There's also the question of why external code should ever need access to the HWND. In most cases, only member functions should need to use it.

[Edited by - Fruny on October 21, 2006 10:49:20 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!