Re: accessing subclass members via a base pointer?
On 2007-10-31 06:49, Just me wrote:
On Wed, 31 Oct 2007 05:11:31 +0000, Tim H wrote:
I think you're stuck. Why not make a virtual SerializeIt() method
instead?
Serialization is not a problem and that part works. The problem is
that deserialization is pretty much useless if I still have to do
an explicit cast from a base pointer type back to the correct
subclass in the heirarchy upon object reconstruction.
struct base {
virtual base* getPtr()=0;};
struct subclass: public base {
subclass* getPtr() { return this; }
const char* isA() { return "subclass"; }
};
getPtr() is not virtual so it is statically bound based on the type,
which is known at compile time.
If you look closely you will see that getPtr() is declared virtual in the
base class and the correct sublcass::getPtr() is being called. I verified
this by inserting an exit(0) in subclass::getPtr().
What Tim meant was that you are not allowed to change the return type of
a virtual function. However, returning a type that is a subtype of the
original function's is allowed, but that does not help you.
Since p is a "base" and getPtr() is not virtual, I would expect the
compiler to generate a call to base::getPtr(). Since base doesn't have
an isA() method in this code, I'd expect it to fail. Does it actually
compile, or does your real code have a base::isA() method?
see above and note that the compiler error was in the OP...the virtual
nature of getPtr() has been verified but the compiler wont recognize the
subclass* return value of getPtr() to allow access to subclass::isA().
What I'm seeing is weird because the epxression p->getPtr() should return
a subclass* and that return type should be compatible with subclass::isA().
No, the pointer p is of of type base*, that means that the function
called is base's getPtr() (but the code that is executed is one in
subclass) which means that the type of the pointer that is returned from
getPtr() have the type declared in base's getPtr(), namely base*.
With a pointer to base you can only call base's functions. Though if
they are virtual and the actual type of the object pointed to is a
derived type then the implementation in the derived type will be used.
But it is still the base's function that was called. What you can do is
make isA() a virtual function in base, and use the value returned to
dynamic_cast() the pointer to the correct subtype.
--
Erik Wikstr??m