Archived

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

linking with libraries that use dynamic_cast

This topic is 5174 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 library that uses dynamic_cast, and a program that uses that library but does not use dynamic_cast itself. In order to get them to link properly, I seem to have to enable runtime type info in BOTH. Is there a way to build this such that only the library using dynamic_cast needs to be linked with runtime type info? Thanks~

Share this post


Link to post
Share on other sites
In order for dynamic_cast to work, it needs some information in an object''s vtable. Now, if the library is going to use dynamic_cast on a pointer that you pass into it, then that object needs the RTTI info present. Hence, you need RTTI enabled in your program.

Also, and I may be wrong here, the type info may alter the layout of an object''s vtable, in which case anything you link together must have the same RTTI settings.

Share this post


Link to post
Share on other sites
oh, I see.. I was hoping that I could enable RTTI for only a few types - I have maybe 30 classes in this project and only use dynamic_cast on 3 of them, so it seems like a pretty big waste. Oh well, thanks for the info.

Share this post


Link to post
Share on other sites
quote:
Original post by dmikesell
It''s also a sure sign that your inheritance hierarchy is broken...



I have a GraphicsDevice interface, and a Drawable interface. I''m implementing both with DirectX, so I subclass each to D3D implementations.

The top level interface functions obviously use abstract types, but it does not make sense for the D3D implementations to accept abstract types, as they will only work with other D3D implementations. dynamic_cast allows me to check that the objects being passed are of the correct type while maintaining the top level abstract interfaces. I think this makes a lot of sense. Though one might argue that Java has already been written.. ;x

Share this post


Link to post
Share on other sites
Doesn''t fly in my book.

I''d make a RendererFactory that returns the appropriate derived classes based on a string you pass in. That way you have to try VERY hard to screw up.

Share this post


Link to post
Share on other sites
quote:
Original post by daerid
Ummm... I don''t see how enabling RTTI is a sign that your class hierarchy is broken.

It''s just a sign that blindly following (and parroting) back "rules" like these is foolish.

Share this post


Link to post
Share on other sites
The power of inheritance is the ability to work with abstractions. You lose that ability if you can't use your base classes generically. If your code contains stuff like this:


void process(GenericObject * obj)
{
if (obj->type() == TYPE_A) {
// process a type A object

} else if { obj->type() == TYPE B) {
// process a type B object

} ...


it can become brittle and hard to maintain. I'm sure it has some uses in rare circumstances, but all too often I've seen it used pretty much like the above example.

--
Dave Mikesell
d.mikesell@computer.org
http://davemikesell.com

[edited by - dmikesell on October 13, 2003 8:52:33 AM]

Share this post


Link to post
Share on other sites
quote:

I have a GraphicsDevice interface, and a Drawable interface. I''m implementing both with DirectX, so I subclass each to D3D implementations.

The top level interface functions obviously use abstract types, but it does not make sense for the D3D implementations to accept abstract types, as they will only work with other D3D implementations.



Can you give an example of the Drawable interface function signatures and the D3D implementation function signatures?

--
Dave Mikesell
d.mikesell@computer.org
http://davemikesell.com

Share this post


Link to post
Share on other sites
If you just want to make sure that your D3D renderer doesn''t try to use objects from an OpenGL one, then the obvious solution would be to add a pure virtual function to the interface classes that just returns a value indicating whether this object uses GL or D3D. Then, just check the return value of this function in each call to the renderer functions.

Share this post


Link to post
Share on other sites
quote:

If you just want to make sure that your D3D renderer doesn''t try to use objects from an OpenGL one, then the obvious solution would be to add a pure virtual function to the interface classes that just returns a value indicating whether this object uses GL or D3D. Then, just check the return value of this function in each call to the renderer functions.


Every call, every frame? If each renderer accepts different kinds of objects, why put them in the same hierarchy? Just have two renderers and use whichever one the user picks at runtime.


--
Dave Mikesell
d.mikesell@computer.org
http://davemikesell.com

Share this post


Link to post
Share on other sites
quote:
Original post by dmikesell
quote:

If you just want to make sure that your D3D renderer doesn''t try to use objects from an OpenGL one, then the obvious solution would be to add a pure virtual function to the interface classes that just returns a value indicating whether this object uses GL or D3D. Then, just check the return value of this function in each call to the renderer functions.


Every call, every frame? If each renderer accepts different kinds of objects, why put them in the same hierarchy? Just have two renderers and use whichever one the user picks at runtime.



"Just use whichever one the user picks at runtime?" That involves duplicating every bit of graphics related code in my entire program.

If I derive them both from the same interface, I can save a ton of time on coding because I can use the same functions for MOST operations. Some operations, however (for example, those that take D3D or OGL specific parameters) must be duplicated because of the nature of the APIs being wrapped.

It''s probably possible to abstract every single thing in both APIs so that they look exactly the same and I can use them as such; however, I doubt the effort it would take to do that (not to mention the performance loss of not being able to optimize) is worth the academic cleanliness of the resulting hypothetical code. Instead, I make a couple dynamic_cast calls and get the benefits of direct access for all of the DX implementations while keeping the benefits of the abstraction for the rest of the engine.

Share this post


Link to post
Share on other sites
Oh, and I would like to add:

A lot of people suggest that I just add a datamember or make a function that returns different things based on a string I pass in or add a virtual function that can indicate what type the object is. I really don''t like doing that. I think a large part of it is just that I think it''s really ugly, and that part is irrational - but also, doing that is just implementing your own RTTI and doing a worse job of it than the compiler would do. The benefit is that you only have it for the classes you want it for instead of all of them, but still.. you end up having to trust the user to provide the right info. I''d rather trust the compiler, so I use dynamic_cast.

Share this post


Link to post
Share on other sites
quote:
Original post by dmikesell

Can you give an example of the Drawable interface function signatures and the D3D implementation function signatures?



I don''t have the code here (and it''s 3 AM (!)) but I''ll post it later.

Share this post


Link to post
Share on other sites