Overloading, overwriting, and hiding
Common denominator: Function names are the same.
(1) Overloading: must be within a domain, function names are the same but function parameters are different. The effect of overloading is that the same function behaves differently.
Overloading is completely a compile-time (or static) concept. If a function with the same name is declared, the compiler will handle the call of these functions at compile time.
Determines which function to call, and the runtime does not involve the additional overhead or decision of calling an overloaded function. Also, overloads are used only for functions and not for classes.
Function Overloading Features: (1) the same range (in the same Class), (2) The function name is the same, (3) the parameters are different; (4) The virtual keyword is optional
Analysis: Because the function parameters are different, it can be easily understood as: two overloaded functions are different functions, the caller can explicitly call different functions according to different parameters.
So what happens to the compiler if there are two of these functions?
Example:
class A
{
public:
void Func (int a, int b=0) {printf ("This is func1/n");}
void Func (int a) {printf ("This is func2/n");}
};
int main ()
{
A;
A.func (5);
return 0;
}
Of course, for such two functions, the caller does not know which function should be called, so the compiler directly error.
(2) Overwrite: Also known as redefinition (redefinition). Derived classes want to overwrite the inherited behavior so that the objects of the derived class exhibit their own behavior rather than the behavior of the base class object.
Overridden Properties: (1) different ranges (functions are in derived and base classes), (2) function names are the same, (3) parameters are the same; (4) base class functions must have virtual
Key word.
We found that the virtual function is used here, in fact, the function of virtual function is to achieve coverage.
Analysis: Since it is linked to virtual functions, this is an attribute of polymorphism support (valid only if the base class pointer or reference indirectly points to the derived class subtype).
Only member functions declared as virtual in a base class can be overridden in a derived class, and it is not possible to overwrite a function that is not declared as virtual in the base class. However, only the base class
of a function before adding virtual key, the derived class cannot be interpreted as allowing the function to be overwritten, the designer of the base class should declare the overridden function as a virtual function.
and explicitly state in the document that the derived class can override the function. In short, the overlay function is a virtual function, or vice versa.
Overrides are the concept of the runtime, which selects a function from a set of overridden functions at run time. Only dynamic binding can use the override mechanism. By covering to make
Use the correct method that the object implements, not the method used to invoke the interface. Overrides are based on a single function, and methods of the derived class override the same name declared in the base class
method, overrides are applied only to methods in the class, and cannot be applied to free functions. Overrides imply an inheritance relationship, and there is no overwrite without inheritance.
Example:
Class Base
{
Public
void f (int x) {cout << base::f (int) << x << Endl;}
void f (float x) {cout << base::f (float) << x << Endl;}
virtual void g (void) {cout << "base::g (void)" << Endl;}
};
Class Derived:public Base
{
Public:
virtual void g (void) { cout << "derived::g (void)" << Endl;}
};
void Main (void)
{
Derived D;
Base *PB = &d;
Pb->f (42); //base::f (int)-
Pb->f (3.14f); Base::f (float) 3.14
Pb->g (); Derived::g (void), or polymorphic
}
The function base::f (int) is overloaded with base::f (float), and base::g (void) is overridden by derived::g (void).
(3) Hide: Refers to a member function of a derived class that hides a member function of a base class function. Hidden means, although not visible now, but does not mean that there is no, but temporarily hidden
It hides, so if you assign an object of a subclass to a pointer to a base class, when you call the corresponding member function with that pointer, the derived
The class hides the corresponding base class's member functions.
Hidden rules:
(1) If the function of the derived class has the same name as the function of the base class, but the parameters are different. At this point, the function of the base class is hidden, whether or not the virtual keyword is present.
(Note not to be confused with overloading)
(2) If the function of the derived class has the same name as the function of the base class, and the parameters are the same, the base class function does not have the virtual keyword. At this point, the function of the base class is hidden.
(Be careful not to confuse the overlay)
Analysis: The hidden word can be understood as follows: When invoking a class's member function, the compiler will look up the definition of the function along the inheritance chain of the class, if
Find it then stop looking, so if a derived class and a base class have a function with the same name (regardless of whether the argument is the same), the compiler
Finally, the function in the derived class is chosen, then we say that the member function of the derived class "hides" the member function of the base class, which means that it blocks the compilation
The device continues to look up the definition of the function.
Example (1):
Class Base
{
Public
virtual void F (float x) {cout << base::f (float) << x << Endl;}
virtual void G (float x) {cout << base::g (float) << x << Endl;}
void h (float x) {cout << base::h (float) << x << Endl;}
};
Class Derived:public Base
{
Public
virtual void F (float x) {cout << derived::f (float) << x << Endl;}
virtual void g (int x) {cout << "derived::g (int)" << x << Endl;}
void h (float x) {cout << derived::h (float) << x << Endl;}
};
In this example (1), the (a) function derived::f (float) covers the base::f (float).
(b) the function derived::g (int) hides base::g (float) instead of overloading.
(c) The function derived::h (float) hides base::h (float) instead of overwriting.
Summary: Overloading and hiding: the same point: (1) the same function name (2) parameters are different (3) The virtual keyword is optional.
Overloaded functions, the virtual keyword is optional.
Different points: (1) The range is different. Overloaded functions are in the same scope (the same class), hidden functions in the base class and derived classes.
Overwrite and hide: Same point: (1) Same scope: function is the same as the base class and the derived class (2) function name (3) parameter
Different points: (1) virtual keyword. The base class is hidden if it does not have the virtual keyword. While overriding, the base class must have the virtual keyword.
That is, the overridden function is polymorphic and is a function that exists in the VTBL to form an "overlay" relationship, while the hidden function
Are general functions that do not support polymorphism and have been identified in the compilation phase.
Example (2):
void Main (void)
{
Derived D;
Base *PB = &d;
Derived *PD = &d;
Good:behavior depends solely on type of the object
Pb->f (3.14f); Derived::f (float) 3.14
Pd->f (3.14f); Derived::f (float) 3.14
Bad:behavior depends on type of the pointer
Pb->g (3.14f); Base::g (float) 3.14 (surprise!)
Pd->g (3.14f); Derived::g (int) 3
Bad:behavior depends on type of the pointer
Pb->h (3.14f); Base::h (float) 3.14 (surprise!)
Pd->h (3.14f); Derived::h (float) 3.14
}
In the example (2), it is very confusing, BP and DP point to the same address, it should be said that the results of the operation should be the same, but it is not true. So we're still going to
Try to get rid of the hidden.
Analysis: Where surprise! occurs, it is also related to the dynamic and static binding of the function. The F function is a virtual function, but the H function is not. Inside a class declared as a virtual function,
Contains a vptr pointer and a so-called virtual function table (VTBL). When the program is compiled, the function pointer (pointer variable to the function) F, g, H is
It is determined, but the vptr pointer differs depending on the offset, and the change is dynamically determined at run time. In other words, the address of the function is not
variable, but vptr variable. Code base *PB = &d; only modifies the base class PB vptr pointer with the vptr of the derived class object D, but when the base
When a class member is established, the F,G,H function pointer cannot be changed.
When the function is declared as virtual, the polymorphic mechanism is activated, and when the program is run, it looks for the function pointer according to the actual type of the type to VTBL.
To invoke the correct function to execute. The type of the H function pointer is confirmed at compile time, so it cannot be changed while the program is running, which can occur
The "hidden" phenomenon in subclasses.
Note: One more thing to avoid, the static member function for static, is the method of the class, not the method of the object,
So the static method must never be overwritten or hidden.
C + +: Overloading, overwriting, and hiding