What is function hiding?
... is a form of name hiding. A simple example:
void foo(int);
namespace X
{
void foo();
void bar()
{
foo(42); // will not find `::foo`
// because `X::foo` hides it
}
}
This also applies to the name lookup in a base class:
class Base
{
public:
void foo(int);
};
class Derived : public Base
{
public:
void foo();
void bar()
{
foo(42); // will not find `Base::foo`
// because `Derived::foo` hides it
}
};
What is function overriding?
This is linked to the concept of virtual functions. [class.virtual]/2
If a virtual member function vf
is declared in a class Base
and in a class Derived
, derived directly or indirectly from Base
, a member function vf
with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as Base::vf
is declared, then Derived::vf
is also virtual (whether or not it is so declared) and it overrides Base::vf
.
class Base
{
private:
virtual void vf(int) const &&;
virtual void vf2(int);
virtual Base* vf3(int);
};
class Derived : public Base
{
public: // accessibility doesn't matter!
void vf(int) const &&; // overrides `Base::vf(int) const &&`
void vf2(/*int*/); // does NOT override `Base::vf2`
Derived* vf3(int); // DOES override `Base::vf3` (covariant return type)
};
The final overrider becomes relevant when calling a virtual function: [class.virtual]/2
A virtual member function C::vf
of a class object S
is a final overrider unless the most derived class of which S
is a base class subobject (if any) declares or inherits another member function that overrides vf
.
I.e. if you have an object of type S
, the final overrider is the first overrider you see when traversing the class hierarchy of S
back to its base classes. The important point is that the dynamic type of the function-call expression is used in order to determine the final overrider:
Base* p = new Derived;
p -> vf(42); // dynamic type of `*p` is `Derived`
Base& b = *p;
b . vf(42); // dynamic type of `b` is `Derived`
What is the difference between overriding and hiding?
Essentially, the functions in the base class are always hidden by functions of the same name in a derived class; no matter if the function in the derived class overrides a base class' virtual function or not:
class Base
{
private:
virtual void vf(int);
virtual void vf2(int);
};
class Derived : public Base
{
public:
void vf(); // doesn't override, but hides `Base::vf(int)`
void vf2(int); // overrides and hides `Base::vf2(int)`
};
To find a function name, the static type of an expression is used:
Derived d;
d.vf(42); // `vf` is found as `Derived::vf()`, this call is ill-formed
// (too many arguments)
How do they relate to function overloads?
As "function hiding" is a form of name hiding, all overloads are affected if the name of a function is hidden:
class Base
{
private:
virtual void vf(int);
virtual void vf(double);
};
class Derived : public Base
{
public:
void vf(); // hides `Base::vf(int)` and `Base::vf(double)`
};
For function overriding, only the function in the base class with the same arguments will be overriden; you can of course overload a virtual function:
class Base
{
private:
virtual void vf(int);
virtual void vf(double);
void vf(char); // will be hidden by overrides in a derived class
};
class Derived : public Base
{
public:
void vf(int); // overrides `Base::vf(int)`
void vf(double); // overrides `Base::vf(double)`
};