I recently read
1. Reload, overwrite, and hide
1). Overload: "overload" occurs when a member function has the following features"
A. the same range (in the same class)
B. The function name is the same.
C. Different parameter types (implicit type conversion is not allowed)
D. Virtual keywords are optional
2). Overwrite (also called "inheritance"): Refers to a function of a derived class that overwrites a base class function. The features are as follows:
A. different scopes (located in the base class and derived class respectively)
B. The function name is the same.
C. The parameters are the same
D. Basic functions must have virtual keywords.
3). Hide: the function of the derived class shields the base class functions with the same name. The rules are as follows:
A. if the function of the derived class has the same name as the function of the base class, but the parameter is different, the function of the base class will be hidden no matter whether there is a virtual keyword. Be careful not to confuse the function with the overload)
B. If the function of the derived class has the same name as the function of the base class, and the parameters are the same, but the base class function does not have the virtual keyword, the function of the base class will be hidden (be careful not to confuse with overwriting)
2. See the following example code:
1 #include <iostream> 2 using std::cout; 3 using std::endl; 4 5 class Base 6 { 7 public: 8 virtual void f(float x){ cout << "Base::f(float) " << x << endl;} 9 void g(float x){ std::cout << "Base::g(float) " << x << std::endl;}10 void h(float x){ std::cout << "Base::h(float) " << x <<std::endl;}11 };12 13 class Derived : public Base14 {15 public:16 virtual void f(float x){ std::cout << "Derived::f(float) " << x << std::endl;}17 void g(int x){ std::cout << "Derived::g(int) " << x << std::endl;}18 void h(float x){ std::cout << "Derived::h(float) " << x << std::endl;}19 };20 21 void main(void)22 {23 Derived d;24 Base *pb = &d;25 Derived *pd = &d;26 27 pb->f(3.14f);//Derived::f(float) 3.1428 pd->f(3.14f);//Derived::f(float) 3.1429 30 pb->g(3.14f);//Base::g(float) 3.1431 pd->g(3.14f);//Derived::g(int) 332 33 pb->h(3.14f);//Base:h(float) 3.1434 pd->h(3.14f);//Derived::h(float) 3.1435 }
3. Explanation
In Rows 27 and 28, the derived: F (float X) of the derived class inherits (overwrites) The base: F (float X) method of the base class through the Virtual keyword, therefore, no matter whether a base class pointer or a derived class pointer is used, the final call is actually the derived: F (float X) method. This is what we generally expect.
In row 30, because the base: G () of the base class is not declared with the virtual keyword, it will not be overwritten by the derived: G () method of the derived class. Therefore, you can only access base: G (float X) when accessing through the base class pointer. The methods that can be accessed when 31 rows pass the pointer of the derived class are base: G (float X) and derived: G (int x), although the two methods have the same method name and different parameters (it seems) comply with the overload standard, however, they are classified into different "domains", so the overload will not occur. In this case, derived: G (int x) can only "hide" the base: G (float X.
Same as above, the method that can be accessed through the base class pointer in row 33rd is only base: H (float X). Because this method is not declared by the virtual keyword, it will not be derived :: H (float X) "replace", so base: H (float X) is called ). While the methods that can be accessed through the pointer of the derived class in row 34th also include base: H (float X) and derived: H (float X), which seems to conflict with each other, in this case, the "hide" rule of C ++ works, so the derived method derived: H (float X) "hides" the base class method base: H (float X ", so derived: H (float
X) is called.
4. Summary
The "overload", "inheritance", and "hidden" mechanisms of C ++ are more complex than generally imagined, and this highlights the importance of virtual keywords. Therefore, when a derived class exists, you must declare the methods that may be implemented in the base class using the virtual keyword. Unless in special cases, such as when you need to check the pointer type.
1 #include <iostream> 2 using std::cout; 3 using std::endl; 4 5 class Base 6 { 7 public: 8 void CheckType(void){ cout << "This's Base Ptr" << endl;} 9 };10 11 class Derived : public Base12 {13 public:14 void CheckType(void){ cout << "This;s Derived Ptr" << endl;}15 };16 17 void main(void)18 {19 Derived d;20 Base *pb = &d;21 Derived *pd = &d;22 23 pb->CheckType();//This's Base Ptr24 pd->CheckType();//This's Derived Ptr25 }26