Make writing a habit together! This is the 10th day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

1. The background

The core technical foundation of C++ polymorphism is the virtual function, which allows us to call different implementations of the same method using the same base class pointer. We Android use Java development process, method rewriting technology to automatically achieve polymorphism, C++ point of view may be more cumbersome, this article from the perspective of Java programmers to elaborate C++ virtual function and development process some criteria.

2. What is virtual function

In Java we implement two classes of inheritance structure:

class Base{
	public void action(a){
		System.out.pritln("in Base"); }}class Sub extend Base{
	public void action(a){
		System.out.println("in Sub"); }}public static void main(String[] args){
	Base b = new Base();
	b.action();
	b = new Sub();
	b.action();
}
Copy the code

Java overrides automatically call the corresponding method of the actual class, but C++ does not.

class Base{
public:
  void action();
}
void Base::action(){
		std::cout>>("in Base");
}
class Sub:public Base{
public:
  void action();
}
void Sub::action(){
		std::cout>>("in Sub");
	}
static void main(){
	Base *b = new Base();
	b->action();
	b = new Sub();
	b->action();
}
Copy the code

The printed result is:

in Base
in Base
Copy the code

Even if B points to Sub object, but the print is still Base method, there is no automatic binding, after writing used to Java immediately panic, how to break. This is where our hero of the day is called “virtual function”. Add virtual before the method declaration to make it a virtual function. We add virtual to the Base action method declaration to print the result:

in Base
in Sub
Copy the code

The call is currently resolved at run time only if a virtual function is dropped on a pointer or reference, and only in that case can the object’s dynamic type be different from its static type.

3. Pay attention to virtual functions

  1. The base class causes its member functions to perform dynamic binding by prefixing their declarations with the keyword virtual. If a function is declared virtual by a base class, that function is implicitly virtual in a derived class. A derived class may, but is not forced to, use the virtual keyword before functions it overrides.
  2. If we want a class to be a base class, the class must already be defined, not just declared. Because a derived class contains and can use members that it inherits from the base class, a derived class of course needs to know what they are in order to use those members. A class cannot derive itself.
  3. If there is one or more virtual functions in the base class, we can use dynamic_cast to request a cast, and the safety check for the cast is performed at runtime. Similarly, if we know that a conversion from a base class to a derived class is safe, we can use static_cast to force the compiler to override the check.
  4. If we do not use a function, we do not need to provide a definition for that function, but we must provide a definition for every virtual function, whether it is used or not, because even the compiler cannot determine which virtual function will be used.
  5. The return type of a virtual function in a derived class must match that of the base class function. The exception to this rule is when the virtual function return type of a class is a pointer or reference to the class itself. If the Impl is derived from Base, the virtual function of the Base class can returnBase*, and the corresponding function of a derived class can returnImpl*, such a return type requires that the Impl to Base conversion be accessible.
  6. We can specify a function as final, and any subsequent attempts to override the function will raise an error if it has already been specified as final.
  7. If the virtual function uses default arguments, it is desirable that the default arguments defined in the accumulation and derived classes match.
  8. If we do not want to dynamically bind calls to virtual functions, we can use scoped operations to force execution of a particular version of the virtual function. In general, only code in member functions (or friends) needs to use scoped operations to circumvent the virtual function mechanism. In Java, a subclass calls the method whose parent class is overridden directlysuper.xxx()To enforce the use of a version of a virtual function in C++, you must use the corresponding version of the class addition: :Scope, as inBase::action(). C++ has the advantage of making it harder to call overridden methods of a parent class in Java.
  9. If a derived class virtual function needs to call its base class version but does not use the scope operator, the call will be resolved at run time as a call to the derived class version itself, resulting in infinite recursion.

4. To summarize

As the direction of Android C++ series of articles, not only introduces C++ related knowledge, Android main development language is Java, the article will try to compare Java and C++ implementation of some differences, as well as some advantages and disadvantages of comparison. This article introduces the basic virtual functions of C++ polymorphism and compares them with the Java version.