470,572 Members | 2,478 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,572 developers. It's quick & easy.

about dynamic_cast<>()

Hi, there !

When I use dynamic_cast for a single object, I do something like:

void foo(Base *base)
{
if ( dynamic_cast<Derived *>( base ) != NULL ) {
((Derived *) base)->do_something()
}
}

I know it's better to avoid abuse of dynamic_cast, user virtual
functions, and so on.

However, I think it would be more practical to be able to write
something like:
if ( istypeof<Derived>( base ) ) {
}

I find the dynamic_cast style (actually, all '*_cast<>"), to take too
much characters to be written, and this is specially annoying in
formatting, for example.

Is there somehting like this within the proposals for the new
standard ?
(or maybe there is already something like this in the current
standard)

Regards,

Baltasar
Nov 29 '07 #1
13 1926
ba*******@gmail.com wrote:
When I use dynamic_cast for a single object, I do something like:

void foo(Base *base)
{
if ( dynamic_cast<Derived *>( base ) != NULL ) {
((Derived *) base)->do_something()
}
A better (idiomatic) way would be

if (Derived *derived = dynamic_cast<Derived*>(base)) {
derived->do_something();
}

Of course the best way would be to have 'do_something' declared
'virtual' and overridden in 'Derived', so that you don't need to
find out what real type the object was. You'd just write

base->do_something();
}

I know it's better to avoid abuse of dynamic_cast, user virtual
functions, and so on.
Oh... Good. So you probably also know the usual joke mentioned in
such a situation:

Patient: "Doctor, if I do *this*, it hurts."
Doctor: "Don't do that."
However, I think it would be more practical to be able to write
something like:
if ( istypeof<Derived>( base ) ) {
}
....and then what? And how is it more practical?
I find the dynamic_cast style (actually, all '*_cast<>"), to take too
much characters to be written, and this is specially annoying in
formatting, for example.
So, you're trying to avoid carpal tunnel syndrome, is that it?

As you say, if you abuse 'dynamic_cast' or for some reason design
your classes wrong, you will be stuck with much more typing. Just
imagine that 'do_something' is virtual. What a pleasure it is to
simply omit all the 'if' and 'dynamic_cast' and such...
Is there somehting like this within the proposals for the new
standard ?
Nope.
(or maybe there is already something like this in the current
standard)
Nope.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 29 '07 #2
ba*******@gmail.com wrote:
Hi, there !

When I use dynamic_cast for a single object, I do something like:

void foo(Base *base)
{
if ( dynamic_cast<Derived *>( base ) != NULL ) {
((Derived *) base)->do_something()
}
}

I know it's better to avoid abuse of dynamic_cast, user virtual
functions, and so on.

However, I think it would be more practical to be able to write
something like:
if ( istypeof<Derived>( base ) ) {
}

I find the dynamic_cast style (actually, all '*_cast<>"), to take too
much characters to be written, and this is specially annoying in
formatting, for example.
How much of a different does it make when you type "if
(istypeof<Derived>(base))" instead of "if (dynamic_cast<Derived*>(base))"? You
only saved 5 characters! I think that one of the best things that could happen
to the software industry is the automatic complition feature of modern compilers
(it made code much more readable). Why don't you use this feature?

BTW, in your examples, you have to cast the pointer twice: once for checking the
if-condition, and once for actually using the casted pointer. That is not how it
is intended to be (a proper code checking tool would complain about the C-style
cast, anyway). Your code should look like this:

void foo(Base *base)
{
Derived* derived = dynamic_cast<Derived *>( base );
if ( derived ) {
derived->do_something();
}
}

or if you are someone who doesn't want to type too much:

void foo(Base *base)
{
if ( Derived* derived = dynamic_cast<Derived *>( base )) {
derived->do_something();
}
}

Regards,
Stuart
Nov 29 '07 #3
ba*******@gmail.com wrote:
Hi, there !

When I use dynamic_cast for a single object, I do something like:

void foo(Base *base)
{
if ( dynamic_cast<Derived *>( base ) != NULL ) {
((Derived *) base)->do_something()
}
}
Why the C-style cast? I would prefer

void foo ( Base* base ) {
Derived* ptr = dynamic_cast< Derived* >( base );
if ( ptr != 0 ) {
ptr->do_something();
}
}

In think, you could even do this:

void foo ( Base* base ) {
if ( Derived* ptr = dynamic_cast< Derived* >( base ) ) {
ptr->do_something();
}
}

I know it's better to avoid abuse of dynamic_cast, user virtual
functions, and so on.

However, I think it would be more practical to be able to write
something like:
if ( istypeof<Derived>( base ) ) {
}

I find the dynamic_cast style (actually, all '*_cast<>"), to take too
much characters to be written, and this is specially annoying in
formatting, for example.
That, I think, is intentional: the casts stick and look ugly so that they
are not taken lightly.

Moreover, you can easily implement that istypeof() function yourself. So
what's stoping you?

Is there somehting like this within the proposals for the new
standard ?
I sure don't hope so, and I am not aware of anything.
(or maybe there is already something like this in the current
standard)
Nothing that I was aware of.
Best

Kai-Uwe Bux
Nov 29 '07 #4
ba*******@gmail.com wrote:
I find [...] to take too much characters to be written
That has *never* been a good principle in programming. It's, IMO, a
very common beginner mistake (ie. to try to minimize writing effort).
Nov 29 '07 #5
ba*******@gmail.com wrote:
I find the dynamic_cast style (actually, all '*_cast<>"), to take too
much characters to be written, and this is specially annoying in
formatting, for example.
You could use something like:

#define with_type(ty, x, y) \
if (ty x = dynamic_cast<ty>(y))
Don't know if that would be more to your taste.
Simple example follows:

----------------------------------------------------------------------
#include <iostream>

#define with_type(ty, x, y) \
if (ty x = dynamic_cast<ty>(y))

struct bar {
int x;
bar(int x_ = 0): x(x_) {}
virtual ~bar() {}
};

struct foo: public bar {
};

int main()
{
bar *a = new foo;

with_type(foo*, b, a) {
std::cout << b->x << '\n';
}

return 0;
}
----------------------------------------------------------------------

(Yes, I'm a Lispnik.)
Nov 29 '07 #6
Juha Nieminen wrote:
That has *never* been a good principle in programming. It's, IMO, a
very common beginner mistake (ie. to try to minimize writing effort).
Concise code is usually more readable (unless it degenerates into
p***-style linenoise).
Nov 29 '07 #7
On 2007-11-29 08:24:52 -0500, Kai-Uwe Bux <jk********@gmx.netsaid:
ba*******@gmail.com wrote:
>Hi, there !

When I use dynamic_cast for a single object, I do something like:

void foo(Base *base)
{
if ( dynamic_cast<Derived *>( base ) != NULL ) {
((Derived *) base)->do_something()
}
}

Why the C-style cast? I would prefer

void foo ( Base* base ) {
Derived* ptr = dynamic_cast< Derived* >( base );
if ( ptr != 0 ) {
ptr->do_something();
}
}

In think, you could even do this:

void foo ( Base* base ) {
if ( Derived* ptr = dynamic_cast< Derived* >( base ) ) {
ptr->do_something();
}
}
Just to emphasize: the C-style cast can produce the wrong result. For
example, if Base is a virtual base of Derived, dynamic_cast produces
the correct pointer value and the C-style cast is simply wrong. So
either of these code examples would be much better than the original
version. And the second of these two is the motivating example for
allowing declarations in conditionals. It restricts the scope of ptr to
the block controlled by the if statement.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Nov 29 '07 #8
On Nov 29, 1:18 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
baltas...@gmail.com wrote:
When I use dynamic_cast for a single object, I do something like:
void foo(Base *base)
{
if ( dynamic_cast<Derived *>( base ) != NULL ) {
((Derived *) base)->do_something()
}

A better (idiomatic) way would be

if (Derived *derived = dynamic_cast<Derived*>(base)) {
derived->do_something();
}
Indeed. To the OP, the rationale behind the use of
dynamic_cast in the idiomatic way that Victor illustrates,
as opposed to the language providing some sort of istypeof
operator, is to allow the test ("is base of type Derived* ?")
and the conversion ("alright then, give me it as a Derived*")
to happen in a single statement. This is not only more elegant,
it is less error-prone, and something that I sorely miss when
labouring in Java, VB.NET and their ilk.
Nov 29 '07 #9

Hi again !

Thank you all for your [funny] answers.
Moreover, you can easily implement that istypeof() function yourself. So
what's stopping you?
Prudence.

Regards,

Baltasar
Nov 29 '07 #10
On Nov 29, 2:58 pm, Matthias Buelow <m...@incubus.dewrote:
Juha Nieminen wrote:
That has *never* been a good principle in programming. It's, IMO, a
very common beginner mistake (ie. to try to minimize writing effort).
Concise code is usually more readable (unless it degenerates into
p***-style linenoise).
It depends. Replacing all of your variable names with one or
two character names will NOT improve readability. Exotic
overuse of complex expressions will not improve readability.
Avoiding named variables in favor of overly complex flow control
(break or return in the middle of a loop, for example) will not
improve readability.
--
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
Nov 30 '07 #11
On 2007-11-30 04:01:07 -0500, James Kanze <ja*********@gmail.comsaid:
On Nov 29, 2:58 pm, Matthias Buelow <m...@incubus.dewrote:
>Juha Nieminen wrote:
>>That has *never* been a good principle in programming. It's, IMO, a
very common beginner mistake (ie. to try to minimize writing effort).
>Concise code is usually more readable (unless it degenerates into
p***-style linenoise).

It depends. Replacing all of your variable names with one or
two character names will NOT improve readability.
It depends on what the names were to begin with. It's hard to
distinguish at a glance between long names that differ by only a few
characters, because the differences are lost in the noise. Short names
don't have so much noise. And, of course, the code that uses them
doesn't run off the edge of the screen. <g>

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Nov 30 '07 #12
Matthias Buelow wrote:
Juha Nieminen wrote:
> That has *never* been a good principle in programming. It's, IMO, a
very common beginner mistake (ie. to try to minimize writing effort).

Concise code is usually more readable
It depends on what you mean by "concise code".

There's a difference between an algorithm which has been cleanly
implemented in a concise way, and using artificially concise code (eg.
short variable names) just to save typing.

The former, when well done, can indeed improve readability. The latter
usually degrades it. Artificially shortening code just to save typing,
for no other good reason, does not make the code easier to read, but all
the contrary. Usually it makes the code more obfuscated.
Nov 30 '07 #13
Pete Becker wrote:
On 2007-11-30 04:01:07 -0500, James Kanze <ja*********@gmail.comsaid:
On Nov 29, 2:58 pm, Matthias Buelow <m...@incubus.dewrote:
Juha Nieminen wrote:
That has *never* been a good principle in programming. It's, IMO, a
very common beginner mistake (ie. to try to minimize writing effort).
Concise code is usually more readable (unless it degenerates into
p***-style linenoise).
It depends. Replacing all of your variable names with one or
two character names will NOT improve readability.
It depends on what the names were to begin with. It's hard to
distinguish at a glance between long names that differ by only a few
characters, because the differences are lost in the noise. Short names
don't have so much noise. And, of course, the code that uses them
doesn't run off the edge of the screen. <g>
I was, of course, talking in general. Replacing all of the
names in a program with a1, a2, ... etc. is a classical
obfuscation trick. Of course, for obfuscation, replacing them
all with twenty character long names randomly generated using
only O, 0, l and 1 is even better (and don't forget to write 0
and 1 00000000000000000000 and 000000000000001---not to be
confused with O0000000000000000000 and O00000000000001).

And of course, for things like local index variables, anything
but i, j, k... is obfuscation.

If you take well written code, however, and force all of the
names down to 2 characters, you will definitely end up with
shorter code, but it will be significantly less readable.

--
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
Nov 30 '07 #14

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.