Then I have a question again. something like this:
#include <iostream>
using namespace std;
class Base
{
public:
void foo()
{
cout<<"Base."<<endl;
}
};
class Derive:public Base
{
public:
void foo()
{
cout<<"Derive."<<endl;
}
};
int main()
{
Derive d;
Base *pb=&d; //attention here
pb->foo(); //ateention here
system("pause");
return 0;
}
And the output is "Base.". Then the function rules are't work, I am confused about this, could you help me? Thanks.
Since
foo
is not virtual, the function called is based on the static type (i.e., the type the pointer is declared to point at) rather than the dynamic type (the type of object to which the pointer currently refers).There are also some trickier cases to consider. One point (on which some of the other answers are actually somewhat misleading) is that it's not really just the function name that matters, but the entire function signature. For example:
Here
foo
is qualified asvirtual
in both the base and (seemingly redundantly the) derived classes, but the callb->foo()
still prints outbase::foo
.The
const
added to the signature ofderived::foo
means it no longer matches the signature ofbase::foo
, so instead of overriding the virtual function, we still end up with two separate functions with the same name, soderived::foo
hidesbase::foo
, but doesn't override it. Despite thevirtual
qualification, we get static binding, sob->foo();
invokes the base function rather than the derived, even thoughb
points to an object of thederived
type.As Tony D pointed out in a comment, C++11 added a new wrinkle to the language to help ensure against this happening. When you want to override a base class function, you can add the identifier
override
to the function in the derived class:With this, if there's a difference in function signature (as in the cases shown here), the compiler will produce an error message alerting you to the fact that
derived::foo
is marked asoverride
, but doesn't actually override a function from the base class. This was, however, added in C++11, so if you're using an older compiler this feature may not be implemented (though thankfully, compilers that don't implement it are quickly fading into oblivion).Correcting the signature in the base class to:
...will let the code compile, and produce the correct results.