How do you find out if object foo is class CBar?

G

George Styles

Hi,

I have a base object, CBase, and 2 sub-objects CSub1 and CSub2.

Given that I have a pointer to CBase, can I find out (easily in a portable
way) if the object is CSub1 or CSub2. (or neither, but in my app its always
1 or the other)

In Delphi, you would use the IS operation, eg

if myObject IS CSub1 then
.....

Can someone tell me the C++ equivelent please?

thanks

George
 
H

Hendrik Belitz

George said:
Hi,

I have a base object, CBase, and 2 sub-objects CSub1 and CSub2.

Given that I have a pointer to CBase, can I find out (easily in a portable
way) if the object is CSub1 or CSub2. (or neither, but in my app its
always 1 or the other)

In Delphi, you would use the IS operation, eg

if myObject IS CSub1 then
.....

Can someone tell me the C++ equivelent please?

thanks

George

Try

if ( typeid( myObject ) == typeid ( CSub1* ) )
....
else if ( typeid( myObject ) == typeid ( CSub2* ) )
....
 
Y

Yannick Le goc

George said:
Hi,

I have a base object, CBase, and 2 sub-objects CSub1 and CSub2.

Given that I have a pointer to CBase, can I find out (easily in a portable
way) if the object is CSub1 or CSub2. (or neither, but in my app its always
1 or the other)

In Delphi, you would use the IS operation, eg

if myObject IS CSub1 then
.....

Can someone tell me the C++ equivelent please?

thanks

George
#include <typeinfo>

// if myObject is of type CBase *, use *myObject
if (typeid(*myObject) == typeid(CSub1))
{
...
}

is the equivalent of IS. If you can resolve this problem by a common
virtual method call, it is better.

Yannick
 
D

David Harmon

Given that I have a pointer to CBase, can I find out (easily in a portable
way) if the object is CSub1 or CSub2. (or neither, but in my app its always
1 or the other)

Don't do that. It's a bad idea. Yes, you can "if(typeid==", but don't.

Instead, you call the appropriate virtual function and the object does
the right thing.
 
G

George Styles

Thanks for your replies...

i went with the virtual function - i dont know why I didnt think of that...
i guess with Delphi IS is so neat (and supported) its better to use IS than
clutter up your objects with loads of extra virtual methods.

George
 
S

Sharad Kala

George Styles said:
Thanks for your replies...

i went with the virtual function - i dont know why I didnt think of that...

The language provides you with virtual functions so that you do
Object-Oriented-Programming (OOP).
Writing code with if/else to determine the derived class is programming the C
way (Procedural way).
So you know why you chose virtual functions now :)

Best wishes,
Sharad
 
G

George Styles

I chose virtual functions because in C++ they are far less 'ugly' than the
TYPEINFO thing...

I disagree (in a friendly way...) with you about using IS being
anti-object-oriented though!

But I agree that in C++, virtual functions are the way to go...

Although I ended up with a function that was call IsCBar which returned
false by default, but true in the specific overridden version in CBar... i
dont think this is any more object oriented than using IS

BTW the reason I am doing this is because I have a registerObject function,
which builds up 2 lists, one holding all the objects, and one holding just
the CBar objects (i am writing a keyboard input method for pocketPC and the
CBar special ones are special keys like Shift and Ctrl which stay down when
tapped)

thanks

g
 
R

red floyd

George said:
I chose virtual functions because in C++ they are far less 'ugly' than the
TYPEINFO thing...

I disagree (in a friendly way...) with you about using IS being
anti-object-oriented though!

1. Please don't top post.

Now, as to IS...

You have a hierarchy {class bodies redacted}:

class base { };
class d1 : public base { };
class d2 : public base { };


You have tons of code scattered around that say:

if anObject IS base
anObject.do_base();
else if anObject IS d1
anObject.do_d1();
else if anObject IS d2
anObject.do_d2();

Great.

Now what happens when you add

class d3 : public base { }; ???

You have to go through and find and modify ALL those if statements. The
client code has to have knowledge of your class hierarchy. Whereas if
you use virtual functions (and I believe Delphi has the OVERRIDE keyword
to do the same thing), then you have { class bodies and public/privates
redacted } :

class base: { virtual void do_thing(); };
class d1 : public base { void do_thing(); };
class d2 : public base { void do_thing(); };

And your client code now becomes

anObject.do_thing();

(Note to gurus, you can assume anObject is a base&).

Now, if you add d3

class d3 : public base { void do_thing(); };

Then your client code requires ZERO changes. It is more "object
oriented" because you have an object, and you tell it what to do
(do_thing), and it "knows" how to do the right thing.

I know that the gurus here could probably describe it better....
 
O

Old Wolf

I have a base object, CBase, and 2 sub-objects CSub1 and CSub2.
Given that I have a pointer to CBase, can I find out (easily in a portable
way) if the object is CSub1 or CSub2. (or neither, but in my app its always
1 or the other)

In Delphi, you would use the IS operation, eg

if myObject IS CSub1 then

if (dynamic_cast<CSub1 *>(myPtr)) { /* ... */ }

I renamed your variable - I filed calling a pointer "myObject" confusing.

NOTE: this will succeed if myPtr points to a CSub1, or any class
derived from CSub1. If it has to be exactly a CSub1 then you will
have to use the typeid() suggested by other posters.
 
S

Sharad Kala

George Styles said:
I chose virtual functions because in C++ they are far less 'ugly' than the
TYPEINFO thing...

I disagree (in a friendly way...) with you about using IS being
anti-object-oriented though!

But I agree that in C++, virtual functions are the way to go...

Good..you agree somewhere with me :)
Although I ended up with a function that was call IsCBar which returned
false by default, but true in the specific overridden version in CBar... i
dont think this is any more object oriented than using IS

BTW the reason I am doing this is because I have a registerObject function,
which builds up 2 lists, one holding all the objects, and one holding just
the CBar objects (i am writing a keyboard input method for pocketPC and the
CBar special ones are special keys like Shift and Ctrl which stay down when
tapped)

As already posted by red floyd, the reason to use virtual functions is so that
your old code calls your new code.
Using if/else as he has pointed out means that you need to modify your code as
and when new classes get introduced.

Let me quote Scott Meyers now (hopefully you will agree with a guru like Scott)
<Quote from EC++>
Anytime you find yourself writing code of the form, "if the object is of type
T1, then do something, but if it's of type T2, then do something else," slap
yourself. That isn't The C++ Way. Yes, it's a reasonable strategy in C, in
Pascal, even in Smalltalk, but not in C++. In C++, you use virtual functions.
</Quote from EC++>

I am referring to Item No. 39 from his book "Effective C++".
btw, it's a very informative + humorous book..pls. don't take the "slap thing"
in a derogatory manner :)

Best wishes,
Sharad
 
J

Jamie Burns

In terms of performance, which is faster:

if (dynamic_cast<CSub1*>(myPtr)) { /* ... */ }

or:

if (typeid(myPtr) == typeid(CSub1*)) { /* ... */ }

?

Jamie Burns.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top