The difference between c++ virtual function and pure virtual function

  • 2020-04-02 00:50:07
  • OfStack

Virtual function is a very important concept in the object-oriented C++ language. Because it fully embodies the inheritance and polymorphism in object-oriented thinking, it is widely used in C++ language. For example, in Microsoft's MFC library, you will find that many functions have virtual keywords, that is, they are virtual functions. No wonder some people even call virtual functions the essence of the C++ language.
So, what is a virtual function? Let's take a look at Microsoft's explanation:
A virtual function is a member function in a class that you wish to override, and when you use a base class pointer or reference to an inherited class object, you call a virtual function that actually calls the inherited class version. This definition is not very clear. An example is also given in MSDN, but it is not a good example to illustrate the problem. We wrote this example ourselves:

#include "stdio.h" 
#include "conio.h" 
class Parent
{     
public: 
    char data[20];     
    void Function1(); 
    virtual void Function2(); //Here Function2 is declared to be a virtual function & PI; & have spent & have spent & have spent
}parent; 
void Parent::Function1() 
{ 
    printf("This is parent,function1n"); 
} 
void Parent::Function2() 
{ 
    printf("This is parent,function2n"); 
} 
class Child: public Parent 
{ 
    void Function1(); 
    void Function2(); 

} child; 
void Child::Function1() 
{ 
    printf("This is child,function1n"); 
} 
void Child::Function2() 
{ 
    printf("This is child,function2n"); 
} 
int main(int argc, char* argv[]) 
{     
    Parent *p; //Defines a base class pointer & NBSP; & have spent & have spent & have spent

    if ( _getch()=='c' ) //If you type in a lowercase c
        p=&child; //Points to an inherited class object
    else 
        p=&parent; //Otherwise point to the base class object

    p->Function1(); //The entry address for Parent::Function1() is given directly at compile time. & have spent & have spent & have spent
    p->Function2(); //Notice here, which Function2 is being performed?

    return 0; 
}

Compile and run with any version of Visual c ++ or Borland c ++, enter a lowercase c and get the following results:
This is the parent, once function1
This is the child, function2
Why do we have the first row? Because we are in a Parent class pointer function call Fuction1 (), while in fact the pointer points to the Child classes of objects, but the fact that the compiler will not know about, until the time of running the program can be based on user input and judge the pointer to the object), it can only according to call the Parent class of functions to understand and compilation, and so we see the results of the first line.

What about the second row? Notice that the Function2() function is decorated by the virtual keyword in the base class, that is, it is a virtual function. The most critical feature of virtual functions is "dynamic alignment," which determines at run time which object the pointer is pointing to and automatically calls the corresponding function. If we enter any non-c character while running the above program, the result is as follows:
This is the parent, once function1
This is the parent of function2

Notice on the second line that the result changes. The program only calls a Function2() function, but automatically decides whether to call Function2 in the base class or the inherited class based on the user's input, which is what virtual functions do. We know, in MFC, a lot of classes are you need to inherit, many of their member functions are to overload, such as writing MFC should use the program most commonly used CView::OnDraw(CDC*) function, you must overload use. By defining it as a virtual function (actually, in MFC, OnDraw is not only a virtual function, but also a pure virtual function), you can ensure that the user's own OnDraw is invoked at all times. The important use of virtual functions can be seen here.
-----------------------------------------------------------
Let's go down here
The size of derived classes in C++ is a matter of the concepts of virtual and pure virtual functions, and the reasons for the differences and separations
First: emphasize a concept
Defining a function as a virtual function does not mean that the function is not implemented, but that it is defined as a virtual function to allow the subclass to call the function with a pointer to the base class
A function is defined as a pure virtual function, which means that the function is not implemented. It is defined to implement an interface, to serve as a specification, and the programmer who inherits the class must implement the function.
Effects on inheritance:
Ordinary classes (no virtual functions, pure virtual functions) can be inherited and work reasonably well
There are the following questions about this question:
Are pure virtual functions meant to implement interfaces? What are interfaces for?
I don't get it. Why should I define it in advance? The future is hard to predict, just wait for the day I need to use a function in the class, not to add a function?
About instantiating a class:
It is impossible to generate a class object with a pure virtual function. Such as:

class CA 
{ 
public: 
    virtual void fun() = 0; //The fun function is a pure virtual function
    virtual void fun1(); 
}; 
class CB 
{ 
public: 
    virtual void fun(); 
    virtual void fun1(); 
}; 
//CA, CB class implementation
... 
void main() 
{ 
    CA a; //No, because there are pure virtual functions in class CA
    CB b; //Yes, because there are no pure virtual functions in class CB

    ... 
}

---------------------------------------------------------------
The use of virtual functions in the middle of polymorphism:
Polymorphism is generally achieved by a pointer to a base class.
Dog mydogwangwang;
Mydogwangwang. Born ();
Must be returning "dog"
then
Horse myhorsepipi;
Myhorsepipi. Born ();
Must be returning to "horse"
Is it polymorphic?
/////////////////////////////////////////////////
One thing you must understand is that the parent class's pointer is used to call the subclass at runtime:
For example, a function might look like this:

void animal::fun1(animal *maybedog_maybehorse) 
{ 
     maybedog_maybehorse->born(); 
} 

The parameter maybedog_maybehorse does not know whether the dog or horse class is passed in at compile time, so it is set to the animal class, and the function is determined at runtime.
In other words, the superclass pointer USES virtual functions to determine which function is running at which time.

//With a virtual function
#include <iostream.h> 
class animal 
{ 
public: 
    animal(); 
    ~animal(); 
    void fun1(animal *maybedog_maybehorse); 
    virtual void born(); 
}; 
void animal::fun1(animal *maybedog_maybehorse) 
{ 
    maybedog_maybehorse->born(); 
} 
animal::animal() 
{ 
} 
animal::~animal() 
{ 
} 
void animal::born() 
{ 
    cout<< "animal"; 
} 
class dog: public animal 
{ 
public: 
    dog(); 
    ~dog(); 
    virtual void born(); 
}; 
dog::dog() 
{ 
} 
dog::~dog() 
{ 
} 
void dog::born()
{ 
    cout<<"dog"; 
} 
class horse:public animal 
{ 
public: 
    horse(); 
    ~horse(); 
    virtual void born(); 
}; 
horse::horse() 
{ 
} 
horse::~horse() 
{ 
} 
void horse::born()
{ 
    cout<<"horse"; 
} 
void main() 
{ 
    animal a; 
    dog b; 
    horse c;     
    a.fun1(&c); 
} 
//output: horse 
// Don't With a virtual function
#include <iostream.h> 
class animal 
{ 
public: 
    animal(); 
    ~animal(); 
    void fun1(animal *maybedog_maybehorse); 
    void born();     
}; 
void animal::fun1(animal *maybedog_maybehorse) 
{ 
    maybedog_maybehorse->born(); 
} 
animal::animal() 
{ 
} 
animal::~animal() 
{ 
} 
void animal::born() 
{ 
    cout<< "animal"; 
} 
class dog: public animal 
{ 
public: 
    dog(); 
    ~dog(); 
    void born(); 
}; 
dog::dog() 
{ 
} 
dog::~dog() 
{ 
} 
void dog::born()
{ 
    cout<<"dog"; 
} 
class horse:public animal 
{ 
public: 
    horse(); 
    ~horse(); 
    void born(); 
}; 
horse::horse() 
{ 
} 
horse::~horse() 
{ 
} 
void horse::born()
{ 
    cout<<"horse"; 
} 
void main() 
{ 
    animal a; 
    dog b; 
    horse c;     
    a.fun1(&c); 
} 
//output: animal

---------------------------------------------------------------
Classes with pure virtual functions are abstract classes that cannot generate objects but can only be derived. The pure virtual function of its derived class is not overridden, so its derived class is still an abstract class.
---------------------------------------------------------------
Pure virtual functions are defined to make the base class uninstantiated,
Because instantiating such an abstract data structure doesn't make sense in and of itself.
Or it doesn't make sense to give an implementation
In fact, I personally believe that pure virtual functions are introduced for two purposes:
1. For safety, because to avoid any unknown result that needs to be explicit but is caused by carelessness, remind the subclass to do the implementation that should be done.
2. For efficiency, not for program execution, but for coding.

Related articles: