Skip to main content
gamedev.net
🔒 Locked

inheritance in c++

Started by YellowMaple Jan 20, 2006 at 5:43 PM 5 replies 1.1k views
Original Post
YellowMaple
YellowMaple
I have an interface class called CollidableObject, something like this:

class CollidableObject{
  public:
    virtual INTERSECTION isCollide(const CollidableObject &) = 0;
}
Now I currently have two derived classes called BoundingSphere and Ray2d. In the Ray2d isCollide function I assume (for now) that I am passed a BoundingSphere object and try to do this in the function:

INTERSECTION Ray2d::isCollide(const CollidableObject& co)
{
  ...
  BoundingSphere *b = co;
  float radius = b->getRadius();
  ...
}
But the compiler tells me that it "cannot convert from 'const CollidableObject' to 'BoundingCircle *'" I tried using casting i.e. BoundingSphere *b = (BoundingSphere) co; but it says no constructor could take the source type. Is there anyway to have a pointer of type derived class point to it's base class? I need to use the getRadius() among other things from the derived BoundingSphere class. Thanks!
rip-off
rip-off
try:

INTERSECTION Ray2d::isCollide(const CollidableObject& co){  ...  BoundingSphere *b = &co // use '&' operator  float radius = b->getRadius();  ...}


a reference is like a pointer, but it is not a pointer ( no implicit casting )
Colin Jeanne
Colin Jeanne
What you're trying to do is downcast. You can use the dynamic_cast operator to handle this. If the CollidableObject passed into your method is not actually a BoundingSphere, the dynamic_cast operator will return a null pointer (which you should check for).
YellowMaple
YellowMaple
Thanks for the tips guys.

I was just wondering what the consequences are of doing a build with RTTI and using dynamic_cast? is dynamic dynamic casting an expensive operation? does RTTI information use up a lot of memory? Please excuse me if these questions make no sense but I've never used dynamic casts before so it is quite new to me.

The double dispatch pattern is also not very familiar to me. But from what I read it seems like I would have to do something like

class BoundingSphere : public CollidableObject {  public:    INTERSECTION isCollide(const CollidableObject &);    INTERSECTION isCollide(const BoundingSphere &);    INTERSECTION isCollide(const Ray2d &);};INTERSECTION BoundingSphere::isCollide(const CollidableObject & co){  co.isCollide(*this);}INTERSECTION BoundingSphere::iscollide(const BoundingSphere &){  // Check if this bounding sphere collides with the bounding sphere in parameter}INTERSECTION BoundingSphere::isCollide(const Ray2d &){  // Check if this bounding sphere and the given ray inersect}


I've tried researching the double disspatch pattern but wasn't able to find too many articles that made sense to me. Does anyone know if the code above would (roughly) be the way to go with double dispatch?
_goat
_goat
With a CPU these days able to calculate 3 billion instructions a second, enabling RTTI (in most cases) will cause negligable (if noticable) slowdown. As is always said in these forums, you should first profile your code, and determine bottlenecks, before going for optimising. Considering the benefits RTTI provides, and considering that it is hard (for anyone) to write such well put-together engines that the bottleneck is the RTTI, I'd have to suggest enabling it and going with dynamic_cast.

I've got no idea on the actual speed of dynamic_cast though. It'll be in the millionths of a second, most likely.
SiCrane
SiCrane
Quote:
Original post by _goat
will cause negligable (if noticable) slowdown.

Pretty much by definition, if it's noticable, it's not negligible.

dynamic_cast generally works by performing a number of string comparisons for each attempted cast, depending on the compiler this may be a linear search or a binary search. The search space is generally the total number of base classes in the inheritance tree of the object being casted. Each string comparison is done on type identification tokens that are generally the length of the fully qualified name of the type being compared. So dynamic_cast is usually about O(n log m) or O(n * m) where m is the total number of elements in the inheritance hierarchy and n is the average length of the fully qualified names in the inheritance hierarchy. It also has fairly large constant terms as there are usually a rather large number of indirections in each comparison, which negatively impacts cache consistency, and string comparisons are often hell on branch prediction.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.