Both can implement the base class method of rewriting, virtual method in the base class virtual, in the derived class with the Override keyword decoration, and the ordinary method is hidden in the base class without any modifiers, and in the derived class with the new keyword to rewrite, I would like to ask, they are also the method of rewriting, C # Why are there two ways to rewrite the method so that the design is not duplicated?
Not repeat, first if the virtual method inside the base class inherits the quilt class, after overriding with override, then there is only one method of the method name in the subclass. And the other common, is in the subclass directly through new to create a new method that is called overloading (polymorphic divided into overrides and overloads), at this time the subclass contains two of the same name method, one is inherited by the parent class, one is self-overloaded by new. Only the parent class inherits the hidden
What is the difference between abstract and virtual methods?
Abstract methods are only defined, no actual method body function, it can only appear in the abstract function, and must be overridden in the subclass, the virtual method has its own function body, has provided the function implementation, but allows to override or overwrite in the subclass.
The overridden virtual function of a subclass is overwritten.
2 overloading, overwriting, and hiding of member functions
The overloading of member functions (overload), overwrite (override), and hide are easy to confuse, and C + + programmers must make sense of the concept, or the error will be hard to find.
8.2.1 Overloading and overwriting
Features that are overloaded by member functions:
(1) The same range (in the same class);
(2) The function has the same name;
(3) different parameters (type, number);
(4) The virtual keyword is optional.
Overrides refer to a derived class function overriding a base class function, characterized by:
(1) different ranges (in the derived and base classes, respectively);
(2) The function has the same name;
(3) the same parameters;
(4) The base class function must have the virtual keyword.
In example 8-2-1, the function base::f (int) is overloaded with base::f (float), while base::g (void) is overridden by derived::g (void).
#include <iostream.h>
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) 42
Pb->f (3.14f); Base::f (float) 3.14
Pb->g (); Derived::g (void)
}
Example 8-2-1 overloading and overwriting of member functions
8.2.2 confusing hidden rules
It is not difficult to distinguish between overloading and overwriting, but the hidden rules of C + + increase the complexity of the problem abruptly. "Hide" here refers to a function of a derived class that masks a base class function with the same name as the following rule:
(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, regardless of the virtual keyword (Note that it is not 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).
Sample program 8-2-2 (a):
(1) The function derived::f (float) is covered with base::f (float).
(2) the function derived::g (int) hides base::g (float) instead of overloading.
(3) The function derived::h (float) hides the base::h (float) instead of the overlay.
#include <iostream.h>
Class Base
{
Public
Virtualvoid f (float x) {cout << "base::f (float)" << x << Endl;}
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
Virtualvoid f (float x) {cout << "derived::f (float)" << x << Endl;}
void g (int x) {cout << "derived::g (int)" << x << Endl;}
void h (float x) {cout << derived::h (float) << x << Endl;}
};
Example 8-2-2 (a) overloading, overwriting, and hiding of member functions
According to the authors, many C + + programmers are unaware of the "hidden" thing. Because the cognition is not deep enough, the occurrence of "concealment" is shadowy and often produces confusing results.
In Example 8-2-2 (b), BP and DP point to the same address, which is supposed to be the same, but that is not the case.
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
Pd->g (3.14f);//derived::g (int) 3 (surprise!)
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
}
Example 8-2-2 (b) overloading, overwriting, and hiding comparisons
8.2.3 Get rid of hidden
Hiding the rules caused a lot of trouble. In the example 8-2-3 program, the statement pd->f (10) is intended to call the function base::f (int), but base::f (int) is unfortunately hidden by the derived::f (char *). Because the number 10 cannot be implicitly converted to a string, an error occurs at compile time.
Class Base
{
Public
void f (int x);
};
Class Derived:public Base
{
Public
void f (char *str);
};
void Test (void)
{
Derived *pd = new Derived;
Pd->f (Ten);//Error
}
Example 8-2-3 error due to shadowing
From the example 8-2-3, it seems silly to hide the rules. But there are at least two reasons for the hidden rule to exist:
& #61557; The person writing the statement pd->f (10) may really want to call the Derived::f (char *) function, but he mistakenly writes the parameter incorrectly. With a hidden rule, the compiler can clearly point out the error, which is not necessarily a good thing. Otherwise, the compiler will silently will wrong and the programmer will find it hard to discover this error and shed the curse.
& #61557; If the class derived has multiple base classes (multiple inheritance), it is sometimes unclear which base classes define the function F. If there is no hidden rule, then pd->f (10) may invoke an unexpectedly base class function F. Although hiding rules doesn't seem to make sense, it does kill them.
Example 8-2-3, if the statement pd->f (10) must call the function base::f (int), modify the class derived as follows.
Class Derived:public Base
{
Public
void f (char *str);
void f (int x) {base::f (x);}
};
The difference between the rewriting of virtual methods and those of ordinary methods; What is the difference between abstract methods and virtual methods?