Re: virtual functions and dynamic binding
Mike Stevenson wrote:
Hi. I'm in the process of re-learning all the C++ I forgot from
college, and I'm starting to get into some virgin (or at least only a
couple times) territory. I have some questions about casting a pointer
from a base class to a derived class. For example:
class Base{
public:
Base() {}
virtual ~Base() {}
void func1(int);
virtual void func2(int);
protected:
int foo;
};
class Deriv : public Base{
public:
virtual void func2(int);
void func3(int);
protected:
int bar;
};
So let's say I make a pointer thus: Base *ptr = new Deriv;. As I
understand it (please correct me if I'm wrong), ptr will use Base::func1
and have access to foo. Since it's defined as virtual, it knows to use
Deriv::func2. What I'm confused about is that ptr will not be able to
use func3 or access bar, saying that class Base does not contain those
things. I guess what I don't understand is, why bother casting the
pointer do the derived type when it can't access all its members?
What's the advantage over using Deriv *ptr = new Deriv?
You are not casting to the derived type in you example code. You are
assigning a derived type to a pointer of the base type - essentially
casting to the base type.
The advantage is genericness and polymorphism.
You are correct that the ptr to a base does not resolve any names
contained in the devired type even if the ptr is actually to a derived
type. The compiler doesn't really know what the pointer is actually
pointing at, it only knows the static naming of the ptr type. The
names are resolved at compile time and the linkage to the function is
created then. Virtual functions link to a virtual function translator
of some sort (usually a ptr table) and so are called in an indirect
fassion...but the name has to exist in the scope of the call or the
linkage cannot happen.
Calling func2 would work because the base class has a name called func2
and the linkage will be virtual. That function could then call any of
the functions it has access to because as far is it is conserned the
pointer is to a derived type (this is a pointer to your type no matter
what type of pointer was used to call you). So a call to ptr->func2()
could result in calls to functions not existing in the base even though
you couldn't call them directly without a downcast.
The issues surrounding this are well described in "Exceptional C++".
You may consider buying that book.