Sign in to follow this  

Pointer Casting

This topic is 4092 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 should probably be in for beginners however since its not game related I thought it better to post here. I currently have an interface hierarchy that looks something like the following: root > i_plugina .....> i_pluginb > i_pluginba .................> i_pluginbb My registry module loads plugins (dll files) and gets a pointer to a low level interface (so i_pluginxx) which is cast up to a root pointer and stored. I want to pass these pointers to other plugins who then cast the pointer to the appropriate type for usage. so dll provides i_pluginba registry stores this as root plugin x requests i_pluginba by name and receives a root pointer plugin x casts root pointer to i_pluginba, uses the plugin However I am not sure what casts to use, the compiler suggests reinterpret_cast<i_pluginba*>(root pointer) however dynamic_cast<i_pluginba*>(root pointer) also compiles correctly. I have heard that casting down the hierarchy can be very dangerous however I cannot provide low level interfaces for all of the plugins, the registry is only aware of a few top level ones and the root type. So the real question is which cast do I use and will this be safe if I know the type of pointer it was originally cast from? Thanks

Share this post


Link to post
Share on other sites
0) No, probably not FB material. But for future reference, FB isn't games-specific.

1) The 'i_' tag usually indicates an interface. Usually, interfaces are more likely to be bases than derived classes. You might be doing something a bit strange.

2) Why does plugin x need to *know* it has a plugin_ba? If it's calling an API that gives back a root, it should normally be because it only requires the root-like behaviour of the received plugin (even if it happens to be a plugin_ba).

3) Assuming you can't get around that (and it's common enough that you can't; I imagine that working with DLLs makes it considerably trickier), dynamic_cast is indeed appropriate. The compiler typically suggests reinterpret_cast for things because it's the easiest suggestion to make (it will more or less always compile, but isn't necessarily safe).

4) Casting down the hierarchy is not "safe" in the sense that Bad Things(TM) can happen when the thing isn't actually of the type you "know" it to be. With static_cast or reinterpret_cast (or a C-style cast), that typically produces undefined behaviour. With dynamic_cast, it produces a null pointer. So all you have to do is *check* for a null pointer:


root* thing = callAPI();
if (plugin_ba* ba = dynamic_cast<plugin_ba*>(thing)) {
ba->doSomething();
} else {
// it's not a plugin_ba; handle the error
}


You can also dynamic_cast references. Because there is no such thing as a "null reference", dynamic_cast will instead throw an exception (std::bad_cast) in cases where a reference cast is found at runtime to be invalid.

Share this post


Link to post
Share on other sites
Much appreciated, that looks to answer my question about both safety and the casting.

The system I am building is similar to eclipse (but with a c++ code base rather than java), the core modules that I construct can easily know about each other however the user constructed modules I need to handle could be almost anything however are all derived from my root interface.

The root interface provides almost no functionality other than name, author etc and an initialise method to let the loaded plugin know about the registry, however the plugins need to be able to convert these root pointers into actual class pointers so that they can use the functionality of the low level classes.

The plugins were all tagged at i_ as each class provides an interface to itself (abstract base class with purely virtual methods) to allow replacement of underlying usage and easy intergration of new modules (just be aware of the existance of the interface not the specific dll implementing it).

So basically the modules I build need to work on only the root pointers for storage / passing but the low level ones need to convert to proper interfaces... much conversion and confusion all round!

Share this post


Link to post
Share on other sites

This topic is 4092 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.

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