473,326 Members | 2,095 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Identifiying which derived class you have in code

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
6 1244
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Abhijit Deshpande | last post by:
Is there any elegant way to acheive following: class Base { public: Base() {} virtual ~Base() {} virtual void Method() { cout << "Base::Method called"; return; } };
9
by: Banaticus Bart | last post by:
I wrote an abstract base class from which I've derived a few other classes. I'd like to create a base class array where each element is an instance of a derived object. I can create a base class...
24
by: Shao Zhang | last post by:
Hi, I am not sure if the virtual keyword for the derived classes are required given that the base class already declares it virtual. class A { public: virtual ~A();
9
by: justanotherguy63 | last post by:
Hi, I am designing an application where to preserve the hierachy and for code substitability, I need to pass an array of derived class object in place of an array of base class object. Since I...
3
by: J.J. Feminella | last post by:
(Please disregard the previous message; I accidentally sent it before it was completed.) I have source code similar to the following. public class Vehicle { protected string dataV; // ......
1
by: Mark McDonald | last post by:
This question kind of follows on from Mike Spass’ posting 10/11/2004; I don’t understand why you can’t declare an implicit operator to convert a base class to a derived class. The text...
9
by: Larry Woods | last post by:
I have a method in my base class that I want ALL derived classes to use. But, I find that I can create a "Shadow" method in my derived class that "overrides" the method in my base class. Can't...
10
by: Julia | last post by:
Hi Please can someone explain this behaviour: I have a MustInherit Base class and a Derived class that Inherits Base and Shadows a method in the base class. If I Dim a variable of type...
4
by: dbuchanan | last post by:
Is the following behavior normal? Both the 'Protected sub' in the inherited form and the 'Private Shadows sub' in the derived form fires. My interpretation of MSDN help on the topic "Shadows"...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.