Connecting Tech Pros Worldwide Help | Site Map

casting problems.

 
LinkBack Thread Tools Search this Thread
  #1  
Old July 22nd, 2005, 06:47 AM
Richard E Collins
Guest
 
Posts: n/a
Default 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?




  #2  
Old July 22nd, 2005, 06:47 AM
Sharad Kala
Guest
 
Posts: n/a
Default Re: casting problems.


"Richard E Collins" <richard@collins1969.fsnet.co.uk> wrote in message
news:c1ceo7$jv1$1@news7.svr.pol.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


  #3  
Old July 22nd, 2005, 06:47 AM
Richard E Collins
Guest
 
Posts: n/a
Default 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_sharadk_ind@yahoo.com> wrote in message
news:c1cfid$1gmufl$1@ID-221354.news.uni-berlin.de...[color=blue]
>
> "Richard E Collins" <richard@collins1969.fsnet.co.uk> wrote in message
> news:c1ceo7$jv1$1@news7.svr.pol.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]


  #4  
Old July 22nd, 2005, 06:47 AM
Sharad Kala
Guest
 
Posts: n/a
Default Re: casting problems.


"Richard E Collins" <richard@collins1969.fsnet.co.uk> wrote in message
news:c1cger$tp4$1@newsg3.svr.pol.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




  #5  
Old July 22nd, 2005, 06:47 AM
Richard E Collins
Guest
 
Posts: n/a
Default 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_sharadk_ind@yahoo.com> wrote in message
news:c1cgth$1g24na$1@ID-221354.news.uni-berlin.de...[color=blue]
>
> "Richard E Collins" <richard@collins1969.fsnet.co.uk> wrote in message
> news:c1cger$tp4$1@newsg3.svr.pol.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]


  #6  
Old July 22nd, 2005, 06:48 AM
Nick Hounsome
Guest
 
Posts: n/a
Default Re: casting problems.


"Richard E Collins" <richard@collins1969.fsnet.co.uk> wrote in message
news:c1ceo7$jv1$1@news7.svr.pol.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_cast<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.


 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,989 network members.