Dynamic Type Check?

L

lallous

Brian Genisio said:
I know I have done this in Java, but is there a way to do it in C++?

Type B and C inherit from type A.

In a function, I want to check an instance of A (which can also be B or
C), to see what it is, and move on... something like:

A something;
if( A.typeof(B) )
{
B somethingB = static_cast<B>(something);
// Do things with the B members
}
else if ( A.typeof(C) )
{
C somethingC = static_cast<C>(something);
// Do things with the C members
}
else
{
// Do things with the A members
}

I know I can accomplish something similar with virtual functions
(polymorphism), but can the above be done in any way?

Just curious.
Brian

Refer to the 'typeid' operator.
 
B

Brian Genisio

I know I have done this in Java, but is there a way to do it in C++?

Type B and C inherit from type A.

In a function, I want to check an instance of A (which can also be B or
C), to see what it is, and move on... something like:

A something;
if( A.typeof(B) )
{
B somethingB = static_cast<B>(something);
// Do things with the B members
}
else if ( A.typeof(C) )
{
C somethingC = static_cast<C>(something);
// Do things with the C members
}
else
{
// Do things with the A members
}

I know I can accomplish something similar with virtual functions
(polymorphism), but can the above be done in any way?

Just curious.
Brian
 
K

Karl Heinz Buchegger

Brian said:
I know I have done this in Java, but is there a way to do it in C++?

Type B and C inherit from type A.

In a function, I want to check an instance of A (which can also be B or
C), to see what it is, and move on... something like:

A something;
if( A.typeof(B) )
{
B somethingB = static_cast<B>(something);
// Do things with the B members
}
else if ( A.typeof(C) )
{
C somethingC = static_cast<C>(something);
// Do things with the C members
}
else
{
// Do things with the A members
}

I know I can accomplish something similar with virtual functions
(polymorphism), but can the above be done in any way?

Not the way you do it now.
'something' is an A object and it will always be an A object
no metter what you do with it (an A is not a B or a C).

In order to do what you want to do, then you must at least have
a pointer or a reference.

void foo( A& pSome)
{
// Here I have a pointer to an A
// but it could also be a B or a C object

if( dynamic_cast< B* >( pSome ) != 0 ) {
// it is a B object
B* = dynamic_cast< B* >( pSome );
// do something with it
}
else if( dynamic_cast< C* >( pSome ) != 0 ) {
// it is a C object
C* = dynamic_cast< C* >( pSome );
// do something with it
}
}

But its much better to use polymorphism to do what you want
to do with the object.
 
N

Nick Hounsome

Karl Heinz Buchegger said:
Not the way you do it now.
'something' is an A object and it will always be an A object
no metter what you do with it (an A is not a B or a C).

In order to do what you want to do, then you must at least have
a pointer or a reference.

void foo( A& pSome)
{
// Here I have a pointer to an A
// but it could also be a B or a C object

if( dynamic_cast< B* >( pSome ) != 0 ) {
// it is a B object
B* = dynamic_cast< B* >( pSome );
// do something with it
}

This is more simply (and efficiently) written:

if( B* bp = dynamic_cast<B*>(pSome) )
{
}
 
L

lilburne

Nick said:
This is more simply (and efficiently) written:

if( B* bp = dynamic_cast<B*>(pSome) )
{
}

To those of us that believe that an if-statement, variable declariation,
dynamic_cast, and assignment, all on one line is an obfuscation too far,
not a simplification. Got proof that it is any more efficient?
 
H

Howard

lilburne said:
To those of us that believe that an if-statement, variable declariation,
dynamic_cast, and assignment, all on one line is an obfuscation too far,
not a simplification. Got proof that it is any more efficient?
I believe he said it was more "efficiently written", not that it was more
efficient. Which means it took fewer keystrokes, I would assume. It might
also be more efficient, though, since it only calls dynamic_cast once.
Surely there is some overhead to that? But I'm with you that it's too much
to put into one line of code.

My compiler usually warns me when I do an assignment in an if statement,
just in case I meant to use == instead of =, and since in my release builds
I treat warnings as errors, I would not be able to compile it. (However, I
haven't actually tested to see if it would warn me in this specific case,
with that declaration preceding the =. Maybe I'll try and see.)

-Howard
 
H

Howard

"> a pointer or a reference.
void foo( A& pSome)
{
// Here I have a pointer to an A
// but it could also be a B or a C object

if( dynamic_cast< B* >( pSome ) != 0 ) {
// it is a B object
B* = dynamic_cast< B* >( pSome );

I think you're missing a variable name here....?
// do something with it
}
else if( dynamic_cast< C* >( pSome ) != 0 ) {
// it is a C object
C* = dynamic_cast< C* >( pSome );

....and here
// do something with it
}
}

But its much better to use polymorphism to do what you want
to do with the object.

Absolutely!

-Howard
 
D

David Harmon

In a function, I want to check an instance of A (which can also be B or
C), to see what it is, and move on... something like: ....
I know I can accomplish something similar with virtual functions
(polymorphism), but can the above be done in any way?

I think you should use the virtual functions. Both in C++ and Java.
Doing a "if" test on object type puts the decision making in the wrong
place, making your designs fragile and non-extendable.
 
J

Jeff Flinn

lilburne said:
To those of us that believe that an if-statement, variable declariation,
dynamic_cast, and assignment, all on one line is an obfuscation too far,
not a simplification. Got proof that it is any more efficient?

The latter construct conveys much more intent and is safer than the former.
In fact this usage is the exact reason that declaration/initializations were
allowed within the if clause. The scope of bp is now limited to the if else
block and is guaranteed to have a non-zero value within the if block. See
Alexandrscu's "Modern C++ Design" where this idiom is put to good effect in
dual dispatch implementations.

I would doubt most compilers could optimize away the extraneous dynamic
cast, the compare to null and the temporary bool created in the former
construct.

Jeff F
 
D

David Harmon

You got a bit over-pessimistic. Please read the Standard, A.5
"Statements". See the definition of "condition". The code is
perfectly legal.

Wow, you're right. That corrects a long-standing misunderstanding
on my part.

But, perhaps partly from being used to it now, I would not want to write
my code that way. Put the variable declaration or assignment on one
line, and the "if" test on the next. There is no logic that can be
accomplished by putting them together and that cannot be accomplished by
two statements, unlike the frequently encountered "for" loop example.

Also, there is no difference in efficiency with any reasonable compiler.
 
V

Victor Bazarov

David Harmon said:
Wow, you're right. That corrects a long-standing misunderstanding
on my part.

But, perhaps partly from being used to it now, I would not want to write
my code that way. Put the variable declaration or assignment on one
line, and the "if" test on the next. There is no logic that can be
accomplished by putting them together and that cannot be accomplished by
two statements, unlike the frequently encountered "for" loop example.

Also, there is no difference in efficiency with any reasonable compiler.

All fine. However, if you can avoid littering the scope with extra
variables, you should. If the pointer in question is not needed
after the 'if' (in case of 'else' or simply beyond the controlled
statement), then declaring it in the condition makes all the sense
in the world.

Victor
 
J

Jeff Schwab

lilburne said:
To those of us that believe that an if-statement, variable declariation,
dynamic_cast, and assignment, all on one line is an obfuscation too far,
not a simplification. Got proof that it is any more efficient?

I take exception (no pun) to the name-calling; an obfuscation? Btw,
this style is recommended by Bjourne in TC++PL. Please see pages 135
and 774.
 
N

Nick Hounsome

Howard said:
I believe he said it was more "efficiently written", not that it was more
efficient. Which means it took fewer keystrokes, I would assume. It might
also be more efficient, though, since it only calls dynamic_cast once.
Surely there is some overhead to that? But I'm with you that it's too much
to put into one line of code.

I think that many would disagree - I find this style very convenient
particularly
if you are testing the object against a number of derived classes (yes I
know
it screams out for virtual functions but we've all had to deal with it now
and again)
where the alternative is:

A* ap = dynamic_cast<A*>(p);
if( ap )
{
}
else
{
B* bp = dynamic_cast<B*>(p);
if( bp )
{
}
else
{
etcetc.
}
}
My compiler usually warns me when I do an assignment in an if statement,
just in case I meant to use == instead of =, and since in my release
builds

It's not an assignment so your compiler should not warn you.
I suppose you could write:

if( B* bp(dynamic_cast<B*>(pSome))

but I find that more confusing because of all the brackets.
I treat warnings as errors, I would not be able to compile it. (However, I
haven't actually tested to see if it would warn me in this specific case,
with that declaration preceding the =. Maybe I'll try and see.)

-Howard

The only other circumstance where this is regularly useful is for streams:

if( ifstream ifs("myfile")) {
 
L

lilburne

Victor said:
All fine. However, if you can avoid littering the scope with extra
variables, you should. If the pointer in question is not needed
after the 'if' (in case of 'else' or simply beyond the controlled
statement), then declaring it in the condition makes all the sense
in the world.

I'm pretty sure that some of the compilers I use don't yet
support the syntax, and that those that do won't limit the
scope (at least they don't in for-statements). Perhaps in
years to come they'll all comply. As of now the only way to
ensure scope limitation across compilers is to inclose the
code in another level of braces.

OTOH if you need to limit the scope of a variable perhaps
the function is too large. It seems that clarity is being
sacrificed on the altar of micro-optimisation.
 
V

Victor Bazarov

lilburne said:
I'm pretty sure that some of the compilers I use don't yet
support the syntax, and that those that do won't limit the
scope (at least they don't in for-statements). Perhaps in
years to come they'll all comply. As of now the only way to
ensure scope limitation across compilers is to inclose the
code in another level of braces.

OTOH if you need to limit the scope of a variable perhaps
the function is too large. It seems that clarity is being
sacrificed on the altar of micro-optimisation.

One man's clarity is another man's murkiness.

Victor
 

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

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,416
Latest member
LionelQ387

Latest Threads

Top