how to static_cast<MyClass* &>(p) ???

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Wenjie

    how to static_cast<MyClass* &>(p) ???

    Hello,


    I have a class B to mediate/isolate between
    implementation and their users (like used in
    an abstract factory class pattern):
    // B.h
    class B {
    static B* getImpl();
    static void update(B*& previous, B*& current);
    };

    // I.h
    class I: public B {
    static I* instance();
    static void update(I*& previous, I*& current);
    };

    // B.cpp
    B* B::getImpl()
    {
    return I::instance();
    }

    void B::update(B*& previous, B*& current)
    {
    return I::update((I*&) previous, (I*&)current);
    }

    I try to use static_cast<I*& >(previous) for (I*&) previous
    but failed to compile for the above member function.

    Do you think static_cast<I*> (previous) is OK for the cast?

    Secondly, do you have a better pattern to achieve the
    isolation as well as the task routing?


    Thanks and best regards!
    Wenjie
  • Gianni Mariani

    #2
    Re: how to static_cast&lt; MyClass* &amp;&gt;(p) ???

    Wenjie wrote:[color=blue]
    > Hello,
    >
    >
    > I have a class B to mediate/isolate between
    > implementation and their users (like used in
    > an abstract factory class pattern):
    > // B.h
    > class B {
    > static B* getImpl();
    > static void update(B*& previous, B*& current);
    > };
    >
    > // I.h
    > class I: public B {
    > static I* instance();
    > static void update(I*& previous, I*& current);
    > };
    >
    > // B.cpp
    > B* B::getImpl()
    > {
    > return I::instance();
    > }
    >
    > void B::update(B*& previous, B*& current)
    > {
    > return I::update((I*&) previous, (I*&)current);
    > }
    >
    > I try to use static_cast<I*& >(previous) for (I*&) previous
    > but failed to compile for the above member function.
    >
    > Do you think static_cast<I*> (previous) is OK for the cast?[/color]

    Let's re-write this a little.

    void B::update(B*& previous, B*& current)
    {
    I * l_prev = previous; // down cast - bad news
    I * l_curr = current; // down cast - bad news

    I::update( l_prev, l_curr );

    previous = l_prev; // up casting OK
    current = l_curr; // up casting OK
    }

    Basically, your original version is using a B* pointer and saying it's
    really an I* pointer. VERY dangerous. You can convert pointers
    [color=blue]
    >
    > Secondly, do you have a better pattern to achieve the
    > isolation as well as the task routing?
    >[/color]

    What are you really trying to do ?

    One suggestion:

    class I: public B {

    // Create this method instead.

    static void update(B*& previous, B*& current);


    Comment

    • Victor Bazarov

      #3
      Re: how to static_cast&lt; MyClass* &amp;&gt;(p) ???

      "Wenjie" <gokkog@yahoo.c om> wrote...[color=blue]
      > I have a class B to mediate/isolate between
      > implementation and their users (like used in
      > an abstract factory class pattern):
      > // B.h
      > class B {
      > static B* getImpl();
      > static void update(B*& previous, B*& current);
      > };
      >
      > // I.h
      > class I: public B {
      > static I* instance();
      > static void update(I*& previous, I*& current);
      > };
      >
      > // B.cpp
      > B* B::getImpl()
      > {
      > return I::instance();
      > }
      >
      > void B::update(B*& previous, B*& current)
      > {
      > return I::update((I*&) previous, (I*&)current);
      > }
      >
      > I try to use static_cast<I*& >(previous) for (I*&) previous
      > but failed to compile for the above member function.[/color]

      B* and I* are unrelated types. A reference to one cannot be
      converted to a reference to the other. Why do you need those
      references to pointers anyway? Can't you just have B& or B*?
      They would be convertable to I& or I* using static_cast.
      [color=blue]
      >
      > Do you think static_cast<I*> (previous) is OK for the cast?[/color]

      I think your design is utterly flawed. "B" should not know
      that there exists "I" who derives from it. Making the base
      class aware of any derived classes is against all applicable
      principles of OOP.

      Having said that, I think you should employ polymorphism here.
      What does 'update' function do? Can it be converted to become
      a member? Example:

      class B {
      virtual void update_(B* current) {} // default - nothing
      public:
      static void update(B* previous, B* current);
      };

      class I : public B {
      void update_(B* current); // real 'I' implementation of
      // update functionality -- hidden
      };

      void B::update(B* previous, B* current) {
      previous->update_(curren t); // virtual call
      }

      Of course, 'update_' can try converting 'current' into 'I*'
      if it needs to, using static_cast or, better yet, dynamic_cast.
      And it could call any local static function if necessary.
      [color=blue]
      > Secondly, do you have a better pattern to achieve the
      > isolation as well as the task routing?[/color]

      I don't. Try the book of patterns.

      Victor


      Comment

      • Wenjie

        #4
        Re: how to static_cast&lt; MyClass* &amp;&gt;(p) ???

        "Victor Bazarov" <v.Abazarov@att Abi.com> wrote in message[color=blue][color=green]
        > >
        > > I try to use static_cast<I*& >(previous) for (I*&) previous
        > > but failed to compile for the above member function.[/color]
        >
        > B* and I* are unrelated types. A reference to one cannot be
        > converted to a reference to the other. Why do you need those
        > references to pointers anyway? Can't you just have B& or B*?
        > They would be convertable to I& or I* using static_cast.[/color]

        Doesn't "I" inherited from "B"? I maintain a linked list of
        "I" in "I" but with the 'interface' of "B". The reference is
        to let the call update() to update the pointers of the calling
        block, which is a hash table in user codes block with those
        linked lists. I did try B* but failed (I will examine the
        exact difficulty later).
        [color=blue]
        >[color=green]
        > >
        > > Do you think static_cast<I*> (previous) is OK for the cast?[/color]
        >
        > I think your design is utterly flawed. "B" should not know
        > that there exists "I" who derives from it. Making the base
        > class aware of any derived classes is against all applicable
        > principles of OOP.
        >
        > Having said that, I think you should employ polymorphism here.
        > What does 'update' function do? Can it be converted to become
        > a member? Example:
        >
        > class B {
        > virtual void update_(B* current) {} // default - nothing
        > public:
        > static void update(B* previous, B* current);
        > };
        >
        > class I : public B {
        > void update_(B* current); // real 'I' implementation of
        > // update functionality -- hidden
        > };
        >
        > void B::update(B* previous, B* current) {
        > previous->update_(curren t); // virtual call
        > }
        >
        > Of course, 'update_' can try converting 'current' into 'I*'
        > if it needs to, using static_cast or, better yet, dynamic_cast.
        > And it could call any local static function if necessary.
        >[color=green]
        > > Secondly, do you have a better pattern to achieve the
        > > isolation as well as the task routing?[/color]
        >
        > I don't. Try the book of patterns.
        >
        > Victor[/color]

        Comment

        • Victor Bazarov

          #5
          Re: how to static_cast&lt; MyClass* &amp;&gt;(p) ???

          "Wenjie" <gokkog@yahoo.c om> wrote...[color=blue]
          > "Victor Bazarov" <v.Abazarov@att Abi.com> wrote in message[color=green][color=darkred]
          > > >
          > > > I try to use static_cast<I*& >(previous) for (I*&) previous
          > > > but failed to compile for the above member function.[/color]
          > >
          > > B* and I* are unrelated types. A reference to one cannot be
          > > converted to a reference to the other. Why do you need those
          > > references to pointers anyway? Can't you just have B& or B*?
          > > They would be convertable to I& or I* using static_cast.[/color]
          >
          > Doesn't "I" inherited from "B"? I maintain a linked list of
          > "I" in "I" but with the 'interface' of "B". The reference is
          > to let the call update() to update the pointers of the calling
          > block, which is a hash table in user codes block with those
          > linked lists. I did try B* but failed (I will examine the
          > exact difficulty later).[/color]

          "I" inherits from "B". But "I*" does not inherit from "B*".

          With the existing relationship between I and B conversions
          work: from I& to B& (implicitly), from I* to B* (implicitly),
          from B& to I& (explicitly, use 'static_cast'), from B* to I*
          (explicitly, use 'static_cast'). But no other conversions
          exist.

          struct B {};
          struct I : B {};

          int foo(B*) { return 1; }
          int boo(B&) { return 2; }
          int bar(B*&) { return 3; }

          int main() {
          I i;
          foo(&i); // fine. I* to B* conversion
          boo(i); // fine. I& to B& conversion
          I *pi = &i;
          bar(pi); // error. Cannot initialise B*& with I*
          }

          Victor


          Comment

          Working...