Connecting Tech Pros Worldwide Forums | Help | Site Map

casting problems.

Richard E Collins
Guest
 
Posts: n/a
#1: Jul 22 '05
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
Guest
 
Posts: n/a
#2: Jul 22 '05

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


Richard E Collins
Guest
 
Posts: n/a
#3: Jul 22 '05

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]


Sharad Kala
Guest
 
Posts: n/a
#4: Jul 22 '05

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




Richard E Collins
Guest
 
Posts: n/a
#5: Jul 22 '05

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]


Nick Hounsome
Guest
 
Posts: n/a
#6: Jul 22 '05

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.


Closed Thread