• Advertisement
Sign in to follow this  

inheritance in c++

This topic is 4380 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 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!

Share this post


Link to post
Share on other sites
Advertisement
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 )

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
consider using double dispatch.

it might or might not be useful, but it will avoid dynamic casting; dynamic casting can become problematic with large numbers of class types or when you don't want to carry around RTTI information to support dynamic cast.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


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

  • Advertisement