about dynamic_cast<>()

Discussion in 'C++' started by baltasarq@gmail.com, Nov 29, 2007.

  1. Guest

    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, 2007
    #1
    1. Advertising

  2. 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
    Victor Bazarov, Nov 29, 2007
    #2
    1. Advertising

  3. 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
    Stuart Redmann, Nov 29, 2007
    #3
  4. Kai-Uwe Bux Guest

    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
    Kai-Uwe Bux, Nov 29, 2007
    #4
  5. 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).
    Juha Nieminen, Nov 29, 2007
    #5
  6. 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.)
    Matthias Buelow, Nov 29, 2007
    #6
  7. 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).
    Matthias Buelow, Nov 29, 2007
    #7
  8. Pete Becker Guest

    On 2007-11-29 08:24:52 -0500, Kai-Uwe Bux <> said:

    > 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)
    Pete Becker, Nov 29, 2007
    #8
  9. On Nov 29, 1:18 pm, "Victor Bazarov" <> wrote:
    > 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.
    tragomaskhalos, Nov 29, 2007
    #9
  10. Guest

    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, 2007
    #10
  11. James Kanze Guest

    On Nov 29, 2:58 pm, 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 (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:
    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
    James Kanze, Nov 30, 2007
    #11
  12. Pete Becker Guest

    On 2007-11-30 04:01:07 -0500, James Kanze <> said:

    > On Nov 29, 2:58 pm, 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 (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)
    Pete Becker, Nov 30, 2007
    #12
  13. 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.
    Juha Nieminen, Nov 30, 2007
    #13
  14. James Kanze Guest

    Pete Becker wrote:
    > On 2007-11-30 04:01:07 -0500, James Kanze <> said:


    > > On Nov 29, 2:58 pm, 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 (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:
    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
    James Kanze, Nov 30, 2007
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. alg

    dynamic_cast<>

    alg, Jul 14, 2003, in forum: C++
    Replies:
    3
    Views:
    474
    Rolf Magnus
    Jul 14, 2003
  2. Dan Noland

    dynamic_cast and references

    Dan Noland, Jul 29, 2003, in forum: C++
    Replies:
    0
    Views:
    492
    Dan Noland
    Jul 29, 2003
  3. Yuming Ma
    Replies:
    1
    Views:
    696
    Jeff Schwab
    Dec 17, 2003
  4. Andreas Sch.

    typeid and dynamic_cast, gcc 3.3

    Andreas Sch., Jan 23, 2004, in forum: C++
    Replies:
    18
    Views:
    1,874
    Janusz Szpilewski
    Jan 29, 2004
  5. Jamie Burns
    Replies:
    11
    Views:
    8,946
    Nick Hounsome
    Jan 29, 2004
Loading...

Share This Page