By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,671 Members | 1,637 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,671 IT Pros & Developers. It's quick & easy.

Identifiying which derived class you have in code

P: n/a
I've seen various ways of doing this, but what I want is to be able to
take a base class pointer and know which derived class to cast to.

For example I am going to make a base light class, that has a position
and intensity.
A derived classes class may be a point light which also has a falloff
value.

The derived class has all the base class methods and data in common,
but has the additional falloff value get/set methods.

Now my rendering interface takes a base light class pointer, but the
body needs to know if it is a point light or not, so it can cast and
get that fall off value.

Ways I've seen this done:

1) dynamic cast and check for NULL;

Well, we could potentially be going through 10 dynamic casts or
more before we know what we have. I heard it was rather expensive to
do that.

2) Put a static const int identifier in every derived class and check
for each in a switch, then you know what to
cast to.

I don't know if this is really more efficient than 1. It also
requires keeping track of all these IDs and which are used already
when you make a new derived class.

3) Any other sugestions?

Sep 12 '08 #1
Share this Question
Share on Google+
6 Replies


P: n/a
On 12 Sep, 05:02, Christopher <cp...@austin.rr.comwrote:
I've seen various ways of doing this, but what I want is to be able to
take a base class pointer and know which derived class to cast to.

For example I am going to make a base light class, that has a position
and intensity.
A derived classes class may be a point light which also has a falloff
value.

The derived class has all the base class methods and data in common,
but has the additional falloff value get/set methods.

Now my rendering interface takes a base light class pointer, but the
body needs to know if it is a point light or not, so it can cast and
get that fall off value.

Ways I've seen this done:

1) dynamic cast and check for NULL;

* * Well, we could potentially be going through 10 dynamic casts or
more before we know what we have. I heard it *was rather expensive to
do that.

2) Put a static const int identifier in every derived class and check
for each in a switch, then you know what to
* * cast to.

* * I don't know if this is really more efficient than 1. It also
requires keeping track of all these IDs and which are used already
when you make a new derived class.

3) Any other sugestions?
Yes, you can always use typeid(), which yields a different type_info&
for each class. Then you can make a wrapper for the type_info&s and
put them all in a map<TypeInfoWrapper, function>.

This way you can lookup the typeid of an object in the map, and call a
different function depending on the type, Effectively doing log(n)
comparisons instead of n comparisons with dynamic_cast.

By now you will probably realize that you have pretty much implemented
a virtual function table. So the simpler solution would be to use the
virtual functions that is built into the language :) This is also
considered much better design, from an OO point of view.

DP
Sep 12 '08 #2

P: n/a
On Sep 12, 5:46 am, "Alf P. Steinbach" <al...@start.nowrote:
* Christopher:
I've seen various ways of doing this, but what I want is to
be able to take a base class pointer and know which derived
class to cast to.
For example I am going to make a base light class, that has
a position and intensity. A derived classes class may be a
point light which also has a falloff value.
The derived class has all the base class methods and data in
common, but has the additional falloff value get/set
methods.
Now my rendering interface takes a base light class pointer
Use a reference, unless you're planning on supporting
nullpointer argument.
, but the body needs to know if it is a point light or not,
so it can cast and get that fall off value.
Ways I've seen this done:
1) dynamic cast and check for NULL;
Well, we could potentially be going through 10 dynamic casts
or more before we know what we have. I heard it was rather
expensive to do that.
Very expensive. Each time you add a class, you have to go back
and modify the code. You can't get much more expensive than
that.
2) Put a static const int identifier in every derived class and check
for each in a switch, then you know what to cast to.
I don't know if this is really more efficient than 1.
It's not. Each time you add a class, you have to go back and
modify the code.
It also requires keeping track of all these IDs and which
are used already when you make a new derived class.
3) Any other sugestions?
As I understand it the problem is how to optimize the
rendering when the light is point with no fall off.
Just let the base class provide identification that it is a
point.
With that identification of point-ness in hand the rendering
code can branch to treatment as point or treatment as
fall-off.
For the 9 or 10 classes with fall-off, provide the fall-off
information through a common interface.
If this is the case, then the obvious design is to provide a
derived class (also abstract) with the additional functions.
Classes which support the added functionality derive from the
derived class, rather than directly from Light, and his
rendering code has one dynamic_cast, and an if on the results of
it, e.g.:

PointLight* pointLight
= dynamic_cast< PointLight* >( light ) ;
if ( pointLight != NULL ) {
// implementation using the PointLight interface...
} else {
// implementation using the original Light interface...
}
This interface can be present also in the base class, but the
rendering code can, based on identification of point-ness,
choose to use more efficient way then.
As always, remember to measure.
It might be that this attempt at optimization will have
little, no or even negative effect (such is difficult to
predict, measurement is needed).
It's rather obvious that maintaining code with 10 or more
dynamic_cast's is very expensive. I don't think you need to
measure that.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 12 '08 #3

P: n/a
On 12 Sep, 05:02, Christopher <cp...@austin.rr.comwrote:
I've seen various ways of doing this, but what I want is to be able to
take a base class pointer and know which derived class to cast to.
....
3) Any other sugestions?
What about the visitor pattern?

Rune
Sep 12 '08 #4

P: n/a
On Sep 12, 4:35 pm, "Alf P. Steinbach" <al...@start.nowrote:
* James Kanze:
On Sep 12, 5:46 am, "Alf P. Steinbach" <al...@start.nowrote:
* Christopher:
As always, remember to measure.
It might be that this attempt at optimization will have
little, no or even negative effect (such is difficult to
predict, measurement is needed).
It's rather obvious that maintaining code with 10 or more
dynamic_cast's is very expensive. I don't think you need to
measure that.
The alternative to optimization isn't another and extremely
silly attempt at optimization, it's simply to not optimize
(manually), i.e. using a common interface for everything
regardless of whether there is a special case.
Whether using another, derived interface optimized development
times or not depends on the case at hand. If the added
functionality is non-trivial, I find it much clearer to have a
separate interface to access it. Having done that, it really
doesn't matter whether you provide a special function in the
base class to return a (possibly null) pointer to this
interface, or use dynamic_cast. But dynamic_cast is already
implemented, so is probably more cost-effective.
And then, relative to no optimization a check for special case
will cause branching, and it will most probably cause slightly
(microscopically) larger code size, which can influence
caching, and with your proposed way of checking (dynamic cast)
instead of my proposed way of checking, the check itself will
likely be "expensive" relative to the code it guides.
Thus, the only way to be sure about the effect is to measure.
But you can't measure except by implementing both, and that's
definitely more expensive than choosing which ever seems most
reasonable, and just using it.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 12 '08 #5

P: n/a
On Sep 13, 1:08 am, "Alf P. Steinbach" <al...@start.nowrote:
* James Kanze:
He needs to implement the general case anyway.
Optimization is an add-on.
It would be un-smart to start with complex optimized version.
OK. I think I finally understand what you mean, that even
defining and supporting the additional interface (and way of
doing the calculation) is an optimization, and so shouldn't be
done until the basic version is working, and shown to be too
slow. You may be right---I don't know enough about the
application domain to judge.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 13 '08 #6

P: n/a
On 12 Sep, 04:02, Christopher <cp...@austin.rr.comwrote:
I've seen various ways of doing this, but what I want is to be able to
take a base class pointer and know which derived class to cast to.

For example I am going to make a base light class, that has a position
and intensity.
A derived classes class may be a point light which also has a falloff
value.

The derived class has all the base class methods and data in common,
but has the additional falloff value get/set methods.

Now my rendering interface takes a base light class pointer, but the
body needs to know if it is a point light or not, so it can cast and
get that fall off value.

Ways I've seen this done:

1) dynamic cast and check for NULL;

* * Well, we could potentially be going through 10 dynamic casts or
more before we know what we have. I heard it *was rather expensive to
do that.

2) Put a static const int identifier in every derived class and check
for each in a switch, then you know what to
* * cast to.

* * I don't know if this is really more efficient than 1. It also
requires keeping track of all these IDs and which are used already
when you make a new derived class.

3) Any other sugestions?
I'd suggest trying to do it using virtual functions.

You have to decide - are your derived classes doing things which are
totally different from your base class? Or are they doing the same
sort of thing, though maybe in different and more exotic ways? If your
answer is "totally different", can you, by looking at things more
abstractly, arrange things so that they are instead "same sort of
thing"? If you can get the problem into this form, then straight-
forward virtual functions could be the answer.

For example, with your light sources. Could you perhaps have a
function in the base class, called setfalloff, which does nothing for
most classes but sets the falloff value in the point source class? Or,
more generally, have a setparameters function which allows each class
to set the values it needs to set, somehow? Do you actually need a
getfalloff function, or do you just need a workoutlightatplace
function which will take into account the falloff value for a point
source and will take other things into account for other sources?

You may need to sit down and do quite a bit of thinking before you
start the coding, but it might run faster and be more maintainable as
a result.

Hope that helps.
Paul.
Sep 13 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.