I have a problem in virtual function: Here is some code as an example:
class A
{
public : virtual void print(void)
{
cout<< "A::print()"<<endl;
}
};
class B : public A
{
public : virtual void print(void)
{
cout<<"B::print()"<<endl;
}
};
class C : public A
{
public : void print(void)
{
cout<<"C::print()"<<endl;
}
};
int main(void)
{
A a,*pa,*pb,*pc;
B b;
C c;
pa=&a;
pb=&b;
pc=&c;
pa->print();
pb->print();
pc->print();
a=b;
a.print();
return 0;
}
the result: A::print() B::print() C::print() A::print()
I know it's a Polymorphism ,and know have a table called virtual-function-table,but I don't know how it is to achieve,And
a=b;
a.print();
the result is: A::print() not B::print(),why it hasn't polymorphism. thank you!
To learn more about virtual method table please see wiki. But in general case the table keeps the information methods' addresses. So, class A in the table will have one record says that method print is in address X. When you do pa=&b class B simply replace the table to its one in such a way that address of method print will point to address Y.
But when you do a=b you copy object. In this case polymorphism doesn't work.
When you do
a = b;
youb
object is sliced i.e. only theA
part of it gets copied. Polymorphism only works through pointers and references. Search "object slicing" to learn about the subject.It will print
A::print()
becausea=b
causes object-slicing, which meansa
gets only the a-subobject ofb
. Read this :Note that runtime-polymorphism can be achieved only through pointer and reference types. In the above code,
a
is neither pointer, nor reference type:Because
a
is not a pointer. It is an instance ofA
, and the assignmenta=b;
copies the instance ofb
toa
. But the function call is on an instance ofA
.The object
a
is still of typeA
. The assignment only copies data fromb
, it doesn't makea
aB
object.This is called object slicing.
After a call to any member function on a object of type
A
, you still haveA
object (except an explicit destructor call, which leaves nothing at all).The assignment of a class instance is just a call to a particular member function called "
operator=
". There is nothing special with "operator=
" here, except its name is standard. You could use another name for assignment:Just as you could write
add(a,b)
instead ofa+b
, buta+b
is more readable.An explicit call to a function never changes the type of the variable it is called on:
The declared type of
a
isA
, and cannot be changed to something else: this is an invariant ofa
.This is also true for pointers: a variable of type pointer to
A
will always have the type pointer toA
:But
p
might point to an object of typeB
, so, at runtime, the dynamic type of*p
will beB
; but the dynamic type ofp
is alwaysA*
.