31, C++ virtual function, heavy virtual function, interface

The core idea of object-oriented programming is data abstraction, inheritance and dynamic bindingBy data abstraction, the interface between classes can be separated from implementation.Using inheritance makes it easier to define new classes that are similar but not identical to other classes.Using dynamic binding, you can ignore the differences between similar classes to a certain extent and use their objects in a unified way.

The function of virtual function is to realize polymorphism. Polymorphism is to separate the interface from the implementation, using a common approach, but using different strategies for individual differences. The pure virtual function is a special virtual function. Virtual functions are linked to polymorphism and polymorphism to inheritance. So BenThe article is on the level of inheritance. Without inheritance, there is nothing to talk about.

I. virtual function

1 . Definition

In C++, the base class must distinguish its two member functions:One is a function that a base class wants its derived class to override; the other is a function that a base class wants its derived class to inherit directly without changing.For the former, the base class defines the function as a virtual function by preceding it with the virtual keyword.

class Base{ // base class
public: 
  virtual int func(int n) const; 
}; 
  
class Derive_Class : public Base{ //Derived Class
public: 
  int func(int n) const; // Default is also a virtual function.
}; 

When we overlay a function in a derived class, we can add the virtual keyword before the function. This is not necessary, however, because once a function is declared to be a virtual function, it is a virtual function in all derived classes. Beyond any constructorNon static functionCan be virtual functions. Derived classes often (but not always) cover their inherited virtual functions.If a derived class does not overwrite a virtual function in its base class, the virtual function behaves like other normal members, and the derived class inherits its version directly from the base class.

2 . Dynamic binding

Dynamic binding occurs when we call a virtual function using a reference (or pointer) to a base class. Because we don’t know which version of the virtual function is called until runtime, either the version in the base class or the version in the derived class, depending on the judgmentIt is the real type of the object that is referenced (or pointer). Unlike non-virtual functions that bind at compile time, virtual functions select the version of the function at run time, so dynamic binding is also called run-time binding.

3 . Static type and dynamic type

Static type refers to the type when a variable is declared or the type generated by an expression, which is always known at compile time; dynamic type refers to the type of object in memory represented by a variable or expression, which is not known until run time.When and only if a virtual function is called through a pointer or reference to a base class, the call is resolved at run time, and only in this case can the dynamic type of the object be different from the static type. If the expression is neither a reference nor a pointer, its dynamic type is always consistent with the static type.

4 . finalAnd override

If a function is defined in a derived class with the same name as the virtual function in the base class but different from the list of parameters, the compiler will consider it a newly defined function of the derived class.If our intention is to cover the virtual function, this error is hard to find. By adding the override keyword at the end of the virtual function in the derived class, the intention is clearer. If we mark a function with override, but the function does not cover the existing virtual function,The compiler will report errors.

class Base{ // base classPublic:Virtual int func (int a, int b) const;};Class Derive_Class: public Base{PublIc:Int func (int a) const override; / / error, not covering virtual function};

If we define a class, we do not want it to be inherited. Or if you want a function not to be overwritten, you can specify a class or function as final, and any subsequent attempt to inherit or overwrite that class will cause an error.  

class Base final { /*  */ };   // Base classes cannot be inherited
class Derive_Class : public Base { /* */ };   // Report errors
  
void func(int) const final;  // No subsequent classes are allowed to cover func (int).

5 . Mechanism to avoid virtual functions

In some cases, instead of dynamically binding virtual function calls, we want to force them to perform a particular version of the virtual function. You can use the scope operator to achieve this purpose.

// Force the function version defined in the base class, regardless of the dynamic type of baseP.Int a = baseP-> Base:: func (42);

 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 into a call to the derived class version itself, resulting in infinite recursion.


Two, pure virtual function

1 . Definition

To facilitate the use of polymorphic properties, we often need to define virtual functions in the base class.In many cases, the virtual function can not be given meaningful implementation in the base class.In order to let the virtual function do nothing in the base class, the concept of “pure virtual function” is introduced, so that the function does not need to be defined.We can describe a virtual function as a pure virtual function by writing = 0 at the body position (before the semicolon of the statement is declared). Among them, =0 can only appear in the virtual function declaration statement within the class:

class Base{ // Abstract Base Class
public: 
  virtual int func(int n) const =0; //Pure virtual function};

Note that we can also provide definitions for pure virtual functions, but the body of the function must be defined outside the class.

2 . Abstract Base Class

Classes that contain (or directly inherit without overwriting) pure virtual functions are called abstract base classes. The abstract base class is responsible for defining interfaces, and subsequent classes can cover the interface.If the derived class does not redefine the pure virtual function, but only inherits the pure virtual function of the base class, then the derived class is still an abstract base class. Because abstract base classes contain pure virtual functions (not defined), we cannot create an object of an abstract base class, but we can declare a pointer to the abstract base class orQuote.

Base base;  // Errors cannot instantiate abstract base classes.

Summary:

①.Virtual functions must be implemented without compiler error reporting.

②.The parent class and the subclass have their own version of the virtual function. Dynamic binding at run time by polymorphic methods.

③.The specified virtual function version can be forced by the scope operator.

④.The pure virtual function is declared as follows: virtual void funtion () =0; pure virtual functions need not be defined. A class containing pure virtual functions is an abstract base class.An abstract base class cannot create an object, but can declare a pointer or reference to an abstract base class.

⑤.After the derived class implements a pure virtual function, the pure virtual function becomes a virtual function in the derived class, and its subclasses can cover the function again.

⑥.A destructor should usually be a virtual function, which ensures that the correct version of the destructor is called at the time of the destructor.

Leave a Reply

Your email address will not be published. Required fields are marked *