Casting from base to derived class in base constructor

Discussion in 'C++' started by pastbin@gmail.com, Feb 6, 2008.

  1. Guest

    Dear members,

    The following code compiles and runs fine on MSVC++ 2005 Express
    edition.
    Warning level at maximum and nothing wrong is reported.

    This is a minimal code I wrote in order to test something for my
    personal needs.
    I'm not sure if the code is "legal" because I'm downcasting in a
    constructor of a base class
    to call a member of another base class of a different branch in the
    hierarchy.

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

    template<typename Derived>
    struct aspect
    {
    aspect() { // constructor
    Derived* derived = static_cast<Derived*>(this); // downcast
    derived->handler_member(); // call a member of a base class of
    derived
    }
    };

    template<typename Derived>
    struct handler
    {
    void handler_member() {
    std::cout << "handler";
    }
    };

    template<typename Derived, template<class> class Handler>
    struct win : public Handler<Derived>
    {
    };

    struct my_win : public win<my_win, handler>
    , public aspect<my_win>
    {
    void dummy() {
    std::cout << "ok";
    }
    };

    int main() {
    my_win w; // print "handler" as expected
    w.dummy(); // print "ok" as expected
    return 0;
    }
    //------------

    Isn't this code somewhat esoteric ?

    Thank you

    mark
     
    , Feb 6, 2008
    #1
    1. Advertising

  2. James Kanze Guest

    On Feb 6, 11:59 am, wrote:

    > The following code compiles and runs fine on MSVC++ 2005
    > Express edition. Warning level at maximum and nothing wrong
    > is reported.


    > This is a minimal code I wrote in order to test something for
    > my personal needs. I'm not sure if the code is "legal"
    > because I'm downcasting in a constructor of a base class to
    > call a member of another base class of a different branch in
    > the hierarchy.


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


    > template<typename Derived>
    > struct aspect
    > {
    > aspect() { // constructor
    > Derived* derived = static_cast<Derived*>(this); // downcast
    > derived->handler_member(); // call a member of a base class of derived


    This is undefined behavior. The cast itself is undefined
    behavior, to begin with (but I can't really imagine an
    implementation where it would fail). The call to the function
    is undefined behavior, and may in fact cause problems in all but
    the simplest cases.

    Don't do it.

    > }
    > };


    > template<typename Derived>
    > struct handler
    > {
    > void handler_member() {
    > std::cout << "handler";
    > }
    > };


    > template<typename Derived, template<class> class Handler>
    > struct win : public Handler<Derived>
    > {
    > };
    >
    > struct my_win : public win<my_win, handler>
    > , public aspect<my_win>
    > {
    > void dummy() {
    > std::cout << "ok";
    > }
    > };


    > int main() {
    > my_win w; // print "handler" as expected
    > w.dummy(); // print "ok" as expected
    > return 0;}


    > //------------


    > Isn't this code somewhat esoteric ?


    More than esoteric, it's undefined behavior, and even if it
    happens to work, it is fragile and unmaintainable.

    Please explain what you are trying to do. There's likely a
    clean solution for it.

    --
    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, Feb 7, 2008
    #2
    1. Advertising

  3. Guest

    On Feb 7, 9:58 am, James Kanze <> wrote:
    >
    > More than esoteric, it's undefined behavior, and even if it
    > happens to work, it is fragile and unmaintainable.
    >
    > Please explain what you are trying to do. There's likely a
    > clean solution for it.
    >


    Thank you for the reply.
    The code:

    Derived* derived = static_cast<Derived*>(this);

    is undefined behavior because we are in a base constructor ?
    Isn't it ?

    What I'm trying to do is close to "delegate to a sister class":
    http://www.parashift.com/c -faq-lite/multiple-inheritance.html#faq-25.10
    But at construction time if possible..

    Using templates I was in hope of avoiding virtual functions.

    Thank you

    mark
     
    , Feb 7, 2008
    #3
    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. mrstephengross
    Replies:
    5
    Views:
    598
    Larry I Smith
    May 18, 2005
  2. ali
    Replies:
    4
    Views:
    579
    David Harmon
    Mar 5, 2007
  3. Replies:
    1
    Views:
    397
    myork
    May 23, 2007
  4. Replies:
    1
    Views:
    389
    Victor Bazarov
    May 23, 2007
  5. Rahul
    Replies:
    16
    Views:
    1,209
    terminator
    Nov 7, 2007
Loading...

Share This Page