casting problems.

R

Richard E Collins

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?
 
S

Sharad Kala

Richard E Collins said:
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'. ?

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
 
R

Richard E Collins

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.
:)
 
S

Sharad Kala

Richard E Collins said:
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;

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
 
R

Richard E Collins

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. :)
 
N

Nick Hounsome

Richard E Collins said:
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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,431
Latest member
ElyseG3173

Latest Threads

Top