I. Virtual Methods
C ++ does not allow the cdog object to inherit the attributes (data) and functions (methods) of the base class. However, C ++ also extends its polymorphism. That is, you can assign a value to the pointer of the base class.
Canimal * panimal = new cdlog;
Then, you can use this pointer to call any methods of the canimal class. This can be done by virtual functions.
# Include <iostream> <br/> # include <string> <br/> using namespace STD; <br/> class canimal <br/>{< br/> public: <br/> canimal () {cout <"Animal constructor" <Endl ;}< br/> virtual ~ Canimal () {cout <"Animal destructor" <Endl ;}< br/> virtual void speek () const {cout <"Animal speek" <Endl ;} <br/> void move () const {cout <"animal move one TESP" <Endl ;}< br/>}; <br/> class cdog: public canimal <br/>{< br/> Public: <br/> cdog () {cout <"Dog constructor" <Endl ;}< br/> virtual ~ Cdog () {cout <"Dog destructor" <Endl ;}< br/> virtual void speek () const {cout <"Dog speek" <Endl ;} <br/> void move () const {cout <"dog move one TESP" <Endl ;}< br/>}; <br/> int main () <br/>{< br/> canimal * PDOG = new cdog; <br/> PDOG-> speek (); <br/> PDOG-> move (); <br/> Delete PDOG; <br/> return 0; <br/>}
[Root @ local ~ Work] #./A. Out
Animal Constructor
Dog Constructor
Dog speek
Animal move one TESP
Dog destructor
Animal destructor
Ii. Working Principles of virtual functions
When creating a derived object, first call the constructors of the base class, and then call the constructors of the derived class. This section describes the scenario where the cdog object is created. Note that the canimal and cdog parts are adjacent to each other in the memory.
After a virtual method is created for a class, the class must be traced to the virtual method. Many compilers have created virtual function tables. Each class has a virtual function table, and each class object has a pointer (vptr or V-pointer) that executes the virtual function table ). The vptr of each object points to v-talbe. For each virtual method, V-table contains a pointer to it. When the canimal part of the cdog is created, the vptr is initialized to the correct part of the V-table. For example
When the cdog constructor is called, add the cdog part of the object and adjust the vptr pointer to point it to the virtual method covered in the cdog class. For example
When the canimal pointer is used, vptr points to the correct function based on the actual type of the object pointed to by the canimal pointer. In this way, when the function speak is called, the correct function is called.
3. Use a base class pointer to access a derived class
If only the derived class has this method, and the base class does not have the corresponding virtual method, the canimal pointer cannot be used to access this method. However, the canimal pointer can be forcibly converted to a cdog pointer, but canimal is not a cdog, which is not safe.
Iv. Removal
Only when calling through pointers or references can the magic of virtual functions be realized. Passing objects by value cannot exert the magic of virtual methods.
5. Create a virtual destructor
What happens when the pointer to the object in the derived class is deleted? If the Destructor is a virtual function, the correct operation is performed: The destructor of the derived class is called. The destructor of the derived class automatically calls the destructor of the base class, therefore, the entire object will be correctly destroyed.
Empirical rules: if any function in the class is a virtual function, the Destructor should also be a virtual function.
Vi. Virtual replication Constructor
The constructor cannot be a virtual function. Therefore, technically, there is no virtual replication constructor. However, sometimes a program needs to create a copy of a derived class object by passing a pointer to the base class object. A common solution is to create a clone method in the base class and set it to a virtual method. The clone method creates a copy of the current Class Object and returns the copy.
Because each derived class overwrites the clone method, it creates a copy of the derived class object.
# Include <iostream> <br/> # include <string> <br/> using namespace STD; <br/> class canimal <br/>{< br/> public: <br/> canimal () {cout <"Animal constructor" <Endl ;}< br/> canimal (const canimal & ranimal) {cout <"Animal copy constructor" <Endl ;}< br/> virtual ~ Canimal () {cout <"Animal destructor" <Endl ;}< br/> virtual void speek () const {cout <"Animal speek" <Endl ;} <br/> virtual canimal * clone () {return New canimal (* This) ;}< br/>}; <br/> class cdog: public canimal <br/>{< br/> Public: <br/> cdog () {cout <"Dog constructor" <Endl ;} <br/> cdog (const cdog & rdog) {cout <"Dog copy constructor" <Endl ;}< br/> virtual ~ Cdog () {cout <"Dog destructor" <Endl ;}< br/> virtual void speek () const {cout <"Dog speek" <Endl ;} <br/> void move () const {cout <"dog move one step" <Endl ;}< br/> virtual canimal * clone () {return New cdog (* This) ;}< br/>}; <br/> int main () <br/>{< br/> canimal * PDOG = new cdog; <br/> PDOG-> speek (); <br/> canimal * P = PDOG-> clone (); <br/> P-> speek (); <br/> Delete PDOG; <br/> Delete P; <br/> return 0; <br/>}
[Root @ local ~ Work] #./A. Out
Animal Constructor
Dog Constructor
Dog speek
Animal Constructor
Dog copy constructor
Dog speek
Dog destructor
Animal destructor
Dog destructor
Animal destructor
VII. Cost of Using Virtual Methods
Because the class containing the virtual method must maintain a V-table, using the virtual method will incur some overhead.