about dynamic_cast<>()

B

baltasarq

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
 
V

Victor Bazarov

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
 
S

Stuart Redmann

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
 
K

Kai-Uwe Bux

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
 
J

Juha Nieminen

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).
 
M

Matthias Buelow

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;
}
 
M

Matthias Buelow

Juha said:
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).
 
P

Pete Becker

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.
 
T

tragomaskhalos

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.
 
B

baltasarq

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
 
J

James Kanze

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.
 
P

Pete Becker

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>
 
J

Juha Nieminen

Matthias said:
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.
 
J

James Kanze

Pete said:
On 2007-11-30 04:01:07 -0500, James Kanze <[email protected]> said:
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.
 

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
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top