casting problems.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Richard E Collins

    casting problems.

    I coded up a nice little base class that I wanted to inherit of anytime I
    wanted a class to become part of a linked list. It all worked except from
    one problem. The GetNext function returned a pointer to the next object but
    this pointer was of the bass calls type and when I cast it the overall class
    type the pointer did not change as so was now invalid. The only way I got
    round it was to a have a void pointer that all the derived classes set to
    their this and returned it in the GetNext function. This works but just
    feels like a hack.

    What I need to know is....

    class a
    {
    int data;
    public:
    cool functions.
    }

    class b : public a
    {
    int more_data;
    public:
    more funcs
    };

    if a have a pointer to 'a' when 'a' is really a 'b' how can I cast it to
    'b'. ?

    Is going to be a runtime op and not a compile time one?



  • Sharad Kala

    #2
    Re: casting problems.


    "Richard E Collins" <richard@collin s1969.fsnet.co. uk> wrote in message
    news:c1ceo7$jv1 $1@news7.svr.po l.co.uk...[color=blue]
    > I coded up a nice little base class that I wanted to inherit of anytime I
    > wanted a class to become part of a linked list. It all worked except from
    > one problem. The GetNext function returned a pointer to the next object but
    > this pointer was of the bass calls type and when I cast it the overall class
    > type the pointer did not change as so was now invalid. The only way I got
    > round it was to a have a void pointer that all the derived classes set to
    > their this and returned it in the GetNext function. This works but just
    > feels like a hack.
    >
    > What I need to know is....
    >
    > class a
    > {
    > int data;
    > public:
    > cool functions.
    > }
    >
    > class b : public a
    > {
    > int more_data;
    > public:
    > more funcs
    > };
    >
    > if a have a pointer to 'a' when 'a' is really a 'b' how can I cast it to
    > 'b'. ?[/color]

    You mean a is polymorphic. Use dynamic_cast.

    #include <iostream>
    using namespace std;
    class a{
    int i;
    virtual f(){}
    };
    class b: public a{
    };

    int main (){
    a* aptr = new b;
    b* bptr = dynamic_cast<b* >(aptr);
    if (bptr){
    std::cout << "Fine downcasting!";
    }
    else
    {
    std::cout << "Not fine downcasting!";
    }
    }

    This is a run time operation.

    -Sharad


    Comment

    • Richard E Collins

      #3
      Re: casting problems.

      I think I had tried that, but then I randomly tried all the cast operators,
      been coding for over ten years but never have stretched my C++ skills.

      What's all this bit about? Is it needed to make it work?

      #include <iostream>
      using namespace std;


      Thanks for your help mate.
      :-)


      "Sharad Kala" <no.spam_sharad k_ind@yahoo.com > wrote in message
      news:c1cfid$1gm ufl$1@ID-221354.news.uni-berlin.de...[color=blue]
      >
      > "Richard E Collins" <richard@collin s1969.fsnet.co. uk> wrote in message
      > news:c1ceo7$jv1 $1@news7.svr.po l.co.uk...[color=green]
      > > I coded up a nice little base class that I wanted to inherit of anytime[/color][/color]
      I[color=blue][color=green]
      > > wanted a class to become part of a linked list. It all worked except[/color][/color]
      from[color=blue][color=green]
      > > one problem. The GetNext function returned a pointer to the next object[/color][/color]
      but[color=blue][color=green]
      > > this pointer was of the bass calls type and when I cast it the overall[/color][/color]
      class[color=blue][color=green]
      > > type the pointer did not change as so was now invalid. The only way I[/color][/color]
      got[color=blue][color=green]
      > > round it was to a have a void pointer that all the derived classes set[/color][/color]
      to[color=blue][color=green]
      > > their this and returned it in the GetNext function. This works but just
      > > feels like a hack.
      > >
      > > What I need to know is....
      > >
      > > class a
      > > {
      > > int data;
      > > public:
      > > cool functions.
      > > }
      > >
      > > class b : public a
      > > {
      > > int more_data;
      > > public:
      > > more funcs
      > > };
      > >
      > > if a have a pointer to 'a' when 'a' is really a 'b' how can I cast it to
      > > 'b'. ?[/color]
      >
      > You mean a is polymorphic. Use dynamic_cast.
      >
      > #include <iostream>
      > using namespace std;
      > class a{
      > int i;
      > virtual f(){}
      > };
      > class b: public a{
      > };
      >
      > int main (){
      > a* aptr = new b;
      > b* bptr = dynamic_cast<b* >(aptr);
      > if (bptr){
      > std::cout << "Fine downcasting!";
      > }
      > else
      > {
      > std::cout << "Not fine downcasting!";
      > }
      > }
      >
      > This is a run time operation.
      >
      > -Sharad
      >
      >[/color]


      Comment

      • Sharad Kala

        #4
        Re: casting problems.


        "Richard E Collins" <richard@collin s1969.fsnet.co. uk> wrote in message
        news:c1cger$tp4 $1@newsg3.svr.p ol.co.uk...[color=blue]
        > I think I had tried that, but then I randomly tried all the cast operators,
        > been coding for over ten years but never have stretched my C++ skills.
        >
        > What's all this bit about? Is it needed to make it work?
        >
        > #include <iostream>
        > using namespace std;[/color]

        I have used the cout object in the demo code I posted.
        Now that is defined in header <iostream> (no .h)
        Note that iostream.h is deprecated and non-standard.
        So you know why I need to write #include <iostream>.

        Also everything in these standard headers is wrapped up inside the std
        namespce.
        Since I was lazy enough to type std::cout everytime so I wrote
        using namespace std :-)

        Got your answers ?

        -Sharad




        Comment

        • Richard E Collins

          #5
          Re: casting problems.

          Trying it all now, thank you very much. I've just noticed that the compiler
          has the runtime type checking turned off which may explain when I tried
          dynamic_cast last time it didn't work. Mind you I was shooting in the dark
          then so it may of failed for other reasons.

          Again, thanks for you help. :-)

          "Sharad Kala" <no.spam_sharad k_ind@yahoo.com > wrote in message
          news:c1cgth$1g2 4na$1@ID-221354.news.uni-berlin.de...[color=blue]
          >
          > "Richard E Collins" <richard@collin s1969.fsnet.co. uk> wrote in message
          > news:c1cger$tp4 $1@newsg3.svr.p ol.co.uk...[color=green]
          > > I think I had tried that, but then I randomly tried all the cast[/color][/color]
          operators,[color=blue][color=green]
          > > been coding for over ten years but never have stretched my C++ skills.
          > >
          > > What's all this bit about? Is it needed to make it work?
          > >
          > > #include <iostream>
          > > using namespace std;[/color]
          >
          > I have used the cout object in the demo code I posted.
          > Now that is defined in header <iostream> (no .h)
          > Note that iostream.h is deprecated and non-standard.
          > So you know why I need to write #include <iostream>.
          >
          > Also everything in these standard headers is wrapped up inside the std
          > namespce.
          > Since I was lazy enough to type std::cout everytime so I wrote
          > using namespace std :-)
          >
          > Got your answers ?
          >
          > -Sharad
          >
          >
          >
          >[/color]


          Comment

          • Nick Hounsome

            #6
            Re: casting problems.


            "Richard E Collins" <richard@collin s1969.fsnet.co. uk> wrote in message
            news:c1ceo7$jv1 $1@news7.svr.po l.co.uk...[color=blue]
            > I coded up a nice little base class that I wanted to inherit of anytime I
            > wanted a class to become part of a linked list. It all worked except from
            > one problem. The GetNext function returned a pointer to the next object[/color]
            but[color=blue]
            > this pointer was of the bass calls type and when I cast it the overall[/color]
            class[color=blue]
            > type the pointer did not change as so was now invalid. The only way I got
            > round it was to a have a void pointer that all the derived classes set to
            > their this and returned it in the GetNext function. This works but just
            > feels like a hack.[/color]

            There is a common way of doing this sort of thing: define a template base
            class
            parameterized by its own derived class:

            in outline:

            template <class D>
            struct Link
            {
            D* next;
            D* prev;
            D* ptr() { return static_cast<D*> (this); }
            Link(): next( static_cast<D*> (this) ), prev(static_cas t<D*>(this)) {}
            void unlink()
            {
            next->prev = prev;
            prev->next = next;
            next = prev = ptr();
            }
            void append(D& p)
            {
            p.unlink();
            p.next = next; p.prev = ptr();
            next = next.prev = p;
            }
            .....
            };

            struct X : public Link<X>
            {
            ....
            };

            X a,b;
            a.append(b);

            There are a few cases where this wont work but none are likely to come up in
            practice.


            Comment

            Working...