6、 Inheritance and polymorphism of C + + – deeply grasp the most powerful mechanism of OOP


This part of the content can be directly seen in Chapter 15 of C + + primer. What is said here is basically repeated. The last section of Chapter 15 also has a comprehensive code case, including operator overloading, inheritance, polymorphism and so on. The notes of Chapter 15 can be seen in another of my essaysChapter 15 object oriented programming

The basic meaning of inheritance

Nature of inheritance (benefits):

  1. Code reuse;

  2. Provide a unified virtual function interface for all derived classes in the base class, let the derived classes override, and then you can use polymorphism.

Relationship between classes:

  • Combine a part of the relationship
  • Inherit a relationship

Summary: 1 Only members of the public object can be accessed externally, and protected and private members cannot be accessed directly; 2. In the integration structure, derived classes can inherit private members from the base class, but derived classes cannot be accessed directly; 3. What is the difference between protected and private? If a member defined in the base class wants to be accessed by a derived class, but does not want to be accessed externally, then the relevant member is defined as protected in the base class; If neither the derived class nor the external class intends to access, the related members are defined as private in the base class.

What is the default inheritance method?It depends on whether the derived class is defined by class or struct. If it is a derived class defined by class, the default inheritance method is private; If it is a derived class defined by struct, the default inheritance method is public.

Construction process of derived classes

How do derived classes initialize member variables inherited from the base class?

  • Constructors and methods that can be derived from base classes (but not from destructors and methods)
  • Initialize by calling the corresponding constructor of the base class

Overload, overwrite, hide

Overload relationship:

  • To overload a group of functions, they must be in the same scope, with the same function name and different parameter lists

​ Functions in base and derived classes cannot be overloaded because of different scopes. If an overloaded function is defined in the base class, it can be called directly in the derived class. However, if a function with the same name as the base class is defined in the derived class, it will only overload in the derived class when calling the derived class, and will not overload the function with the same name in the base class

Hide relationships:

  • In the inheritance structure, the members with the same name of the derived class will hide the members with the same name of the base class,

Type conversion of base and derived classes

Only the memory in the blue part can be accessed. The memory in the red part does not exist. Accessing the base class pointer will report illegal memory access

In the inheritance structure, top-down type conversion is performed. By default, only bottom-up type conversion is supported.

Coverage relationship:

The method, return value, function name and parameter list of the base class and the derived class are the same, and the method of the base class is a virtual function, then the method of the derived class is automatically processed into a virtual function, which is called the coverage relationship between them.

Virtual function, static binding and dynamic binding

Virtual function.RTTI (run time type information) type information of runtime.

Summary 1 If a virtual function is defined in a class, the compiler generates a unique vftable virtual function table for this class type in the compilation stage. The main contents stored in the virtual function table are RTTI pointer and virtual function address. When the program runs, each virtual function table will be loaded into memory Rodata area.

Summary 2 If a virtual function is defined in a class, when the object defined in this class runs, the beginning of the memory will store an additional vfptr virtual function pointer to the corresponding type of virtual function table vftable. For n objects defined by a type, their vfptr points to the same virtual function table.

In this example, the size of the object is 8 bytes

Summary 3 The number of virtual functions in a class does not affect the object memory size (vfptr), but the size of the virtual function table

class Base{
	Base(int data=10): ma(data){}
    //Virtual function
	virtual void show(){ cout<

Summary 4 If the method in the derived class and a method inherited from the base class have the same return value, function name and parameter list, and the method of the base class is a virtual virtual function, the method of the derived class will be automatically processed into a virtual function.

For the virtual function table in the derived class, if there are duplicate functions in the derived class and the base class, the method address in the original base class will be overwritten in the virtual function table of the derived class.

Dynamic binding occurs when there are virtual functions in the class.

Static binding will call the specific method address in the assembly code, while dynamic binding will call a register, which will find the address of the corresponding method in the virtual function table at runtime.

virtual destructor

Question 1: which functions cannot be implemented as virtual functions?

  • Virtual functional dependency:

    1. Virtual functions can generate addresses and store them in vftable
    2. The object must exist (vfptr – > vftable – > virtual function address). Only when the object exists can there be vfptr, vftable and virtual function address
  • A constructor cannot be a virtual function. The virtual function is called in the constructor, and dynamic binding will not occur. Any function called by the constructor is statically bound

  • Static member methods cannot be implemented as virtual functions

Question 2: virtual destructor

  • The object exists when the destructor is called.
  • The destructor of the base class is a virtual destructor, and the destructor of the derived class will be automatically defined as a virtual destructor

When must the destructor of a base class be implemented as a virtual function?

​ When the pointer (Reference) of the base class points to the new derived class object on the heap, delete Pb (pointer of the base class). When calling the destructor, dynamic binding must occur, otherwise the destructor of the derived class will not be called

Why use virtual destructors?

​ The code used to explain this problem:

// Created by 26685 on 2022-05-17 19:41.
// Description:ClassDerive. H learning inheritance and polymorphism

using namespace std;

class Base{
    Base(int data=10):ma(data){

If memory is opened on the heap to store derived classes, the destructor of derived classes will not be called. The code is as follows:

int main(){
    Base *pb=new Derive;
    delete pb;
    return 0;

The output result is only the destructor of the base class:

Pb here is of base type. You will find the destructor in the base class. At this time, the binding is static binding.

If the destructor of the base class is a virtual function, the destructor in the derived class will be automatically generated as a virtual destructor. Therefore, we should define the destructor as a virtual destructor.

virtual Base::~Base(){

The correct deconstruction will occur:

On virtual function and dynamic binding

Question: is the calling of virtual functions bound dynamically? A: No

Calling a virtual function in the constructor of a class is a static binding.

Calling a virtual function with the object itself is a static binding

Dynamic binding occurs when a pointer calls a virtual function:

Understanding what polymorphism is

Common questions in interview: how to explain polymorphism

Dynamic polymorphism:

Static polymorphism:

Function overloading

Understanding abstract classes

Classes with pure virtual functions are called abstract classes. Abstract classes can no longer instantiate objects, but can define pointers and reference variables

Virtual void function name () = 0;Define pure virtual function

What classes are generally designed as abstract classes?

Base class