Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the relationship between C++ polymorphism and virtual function, constructor and destructor

2025-03-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "what is the relationship between C++ polymorphism and virtual functions, constructors and destructors". The content of the explanation in this article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought. Let's study and learn the relationship between C++ polymorphism and virtual functions, constructors and destructors.

Polymorphisms and virtual functions

In object-oriented programming, polymorphism means "one interface, multiple implementations".

Polymorphism is divided into static polymorphism and dynamic polymorphism. Static polymorphism is realized by templating and overloading techniques and is determined at compile time. Dynamic polymorphism is implemented through virtual functions and inheritance relationships, performs dynamic binding and is determined at run time.

Run-time polymorphism in C++ refers to calling the corresponding function according to the actual type of the object. If the object type is a derived class, the function of the derived class is called; if the object type is the base class, the function of the base class is called.

C++ polymorphism is achieved through virtual functions, which allow subclasses to redefine member functions, while subclass redefining parent class methods are called overrides or override.

Virtual function:

A function declared with the virtual keyword is called a virtual function, which must be a member of the class.

The function of virtual function is to realize dynamic binding, that is, to dynamically select the appropriate member function during the running phase of the program.

According to the specific implementation, after the virtual function is defined in the base class, the virtual function can be redefined in the derived class of the base class, and the redefined function in the derived class should have the same number and type of formal parameters as the virtual function, in order to achieve a unified interface and different definition processes.

If the virtual function is not redefined in the derived class, it inherits the virtual function of its base class, and the derived class is also an abstract class and cannot instantiate the object.

Virtual function table:

When a class contains one or more virtual functions, the corresponding virtual function table vtbl of the class will be stored in the global data area (static zone). The compiler adds a virtual function table pointer vptr to each object of the class, which points to the virtual function table of its own class.

The size of the virtual function table is determined at compile time, and there is no need to dynamically allocate memory space for storage, so the non-virtual function table does not exist in the heap. According to the above characteristics, the virtual function table is similar to the static member variables in the class. Static member variables are also globally shared and determined in size, so the virtual function table, like static member variables, is stored in the global data area.

The virtual function table holds the address of the virtual function declared by the class object, that is, the element of the virtual function table is a pointer to the class member function. In other words, we can access the virtual function table through vptr, and then access the address of the declared virtual function, thus calling the corresponding virtual function.

The vptr of different objects of the same class actually points to the same virtual function table. The setting and reset of vptr is done automatically by each class's constructor, destructor, and copy assignment operator. In general, the creation of the virtual table and the initialization of the virtual table pointer will be done in the constructor.

The virtual function table of the base class and the virtual function table of the derived class are two independent arrays stored in different locations, that is, the hidden members of the base class and the hidden members of the derived class point to different addresses.

If the derived class does not redefine a virtual function An of the base class, the virtual function table vtbl of the derived class will save the original address of the virtual function An of the base class (in this case, the address of the virtual function A saved in the virtual function table of the derived class and the base class is the same).

If the derived class overrides a virtual function B of the base class, the virtual function table vtbl of the derived class will save the address of the new virtual function B. (at this time, the virtual function B actually has two versions, which are saved separately by the virtual function table of the base class and the derived class.

Pure virtual function:

A pure virtual function is a virtual function declared in the base class, which is not defined in the base class and requires any derived class to define its own implementation method. The way to implement a pure virtual function in the base class is to add "= 0" after the function prototype, that is, virtual void funtion1 () = 0

A class that contains pure virtual functions is an abstract class, cannot declare objects, but serves as a base class for derived classes. Unless all virtual functions of the base class are fully implemented in a derived class, a derived class is also an abstract class and cannot instantiate an object.

Abstract classes cannot define objects, but can be used as pointers or reference types.

Virtual functions cannot be declared:

Common functions that cannot be declared as virtual functions are ordinary functions (non-member functions), static member functions, inline member functions, constructors, and friend functions.

Ordinary functions (non-member functions) can only be overload, not override, and it is meaningless to declare them as virtual functions.

Static member functions have only one code for each class, and all objects share this code, and there is no need for dynamic binding.

Inline functions are expanded at compile time, which can reduce the cost of function calls, and virtual functions are dynamically bound at run time, so that inherited objects can accurately perform their own actions.

The purpose of the constructor is to initialize the object when the object is generated, and the purpose of the virtual function is to call different methods in different types of objects to produce different actions. the purpose of the constructor is to instantiate the object before it is generated.

Friend functions do not support inheritance, and there is no virtual function for functions that do not have inheritance properties.

Early binding and late binding:

When the C++ compiler compiles, it needs to determine the address of the function (non-virtual function) that each object calls. This is called early binding. When we assign the address of the Son class object to the pointer pFather, the C++ compiler performs a type conversion. At this time, the C++ compiler thinks that the pointer variable pFather holds the address of the Father object. When pFather- > Say () is executed in the main function, the Say function of the Father object is called.

From a memory perspective:

The result of the previous output is that the compiler has already determined the function address of the object call when compiling. To solve this problem, it is necessary to use late binding. When the compiler uses late binding, it will determine the type of the object and the correct calling function at run time. In order for the compiler to use late binding, it is necessary to use the virtual keyword when declaring the function in the base class. Once a function is declared as virtual in the base class, it is virtual in all derived classes and does not need to be explicitly declared as virtual.

The compiler provides a virtual table pointer (vptr) for each object, which points to the virtual table of the class to which the object belongs. When the program is running, the vptr is initialized according to the type of the object, so that vptr correctly points to the virtual table of the class to which it belongs, so that the correct function can be found when the virtual function is called. Because the object type that pFather actually points to is Son, the vtable of the Son class that vptr points to, when pFather- > Son () is called, the Say () function of the Son class is found according to the function address in the virtual table.

From a memory perspective:

在这里插入图片描述

Constructor and virtual function

The constructor cannot be a virtual function.

From the answer of Bjarne, the father of C++, we should know why C++ does not support that the constructor is a virtual function, in short, it is meaningless.

The function of a virtual function is to call the member function of the parent class through the pointer or reference of the subclass. The constructor is called on its own initiative when the object is created, and it is impossible to call it through a pointer or reference of a subclass.

The purpose of the constructor is to initialize the object when the object is generated, and the purpose of the virtual function is to call different methods in different types of objects to produce different actions. When the object has not been generated, there is no virtual function pointer and virtual function table in memory, so the virtual function is meaningless, and the constructor is to instantiate the object when the object is not generated, if the constructor is declared as a virtual function. There is no virtual function table in the memory space, and the constructor will become meaningless, so the constructor cannot be a virtual function.

Destructor and virtual function

When a derived class pointer points to a derived class object generated with the new operator, the delete derived class pointer executes the destructor of the derived class, followed by the destructor of the base class. Because when you instantiate a derived class object, you first instantiate the base class object.

When the base class pointer points to the derived class object generated by the new operator, the delete base class pointer, because the compiler has converted the type again, defaults to the address of the base class object. According to the memory relationship in the early binding, if the base class destructor is not declared as a virtual function, only the base class constructor will be executed. If the base class destructor is declared as a virtual function, the type conversion will be carried out. According to the memory relationship in late binding, both the base class object and the derived class object have corresponding virtual function table pointers, so the destructor of the derived class is called first (vptr points to its own destructor), and then the destructor of the base class is called (declaring that the derived class object first instantiates the base class object).

# includeusing namespace std;class Base {public: Base () {cout

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report