Rules for calling virtual functions during inheritance, upcasting, and downcasting

#include <iostream>
using namespace std;

class A{
public:
    virtual void print(){
        cout<<"virtual A print"<<endl;
    }
    void fun(){
        cout<<"non-virtual A fun"<<endl;
    }
};

class B:public A{
public:
    virtual void print(){
        cout<<"virtual B print"<<endl;
    }
    void fun(){
        cout<<"non-virtual B fun"<<endl;
    }
    void funB(){
        cout<<"non-virtual B funB"<<endl;
    }
    virtual void funC(){
        cout<<"virtual B funC"<<endl;
    }
};

int main(){
    ////// The following is for virtual functions
    //When assigning the subclass object pointer to the base class pointer variable, the virtual functions called by the base class pointer variable are all virtual functions implemented by the subclass.
    A *t=new B();
    t->print();//This is the virtual function table at work
    A *t2=(A*) new B();
    t2->print();
    //t->funB();
    //t2->funB();//Invisible, because the base class does not have this non-virtual function
    //t->funC();
    //t2->funC();//Invisible, because the base class virtual function table part of the subclass does not have this virtual function
    ((B*)t2)->funC();//Convert the pointer
    B b;
    A t3=b;
    t3.print();
    A t4=(A)b;
    t4.print ();
    //////The case of non-virtual functions
    t->fun();//This has nothing to do with the virtual function table. Only the address of the virtual function is recorded in the virtual function table. Here, the corresponding function is called directly according to the type of the pointer to view the class information.
    t2->fun();
    B *k=new B();
    k->fun();//
    b.fun();
    t3.fun();
    t4.fun();
    return 0;
}

The function call depends on three key information: the type of the memory block, the current type, and whether it is a virtual function.
    A: For virtual functions, it involves the question of whose virtual function table is to be searched.
    For object calling functions, the current type is the type of the object memory block, which is consistent. Just look up the virtual function table of the class of the current type, such as t3.print (), t4.print();
    
    and for the case of calling a function with a type pointer, the current type is the type of the pointer, and the information of the specific memory block needs to check the type of the specific memory block pointed to by the pointer (I guess it is related to the virtual function table. A pointer to type_info is previously set). If it points to the base class object, look up the virtual function table of the base class; if it points to the derived class object, then look up the virtual function table of the base class part in the derived class and in this virtual function table, the compiler has used the specific function of the derived class The address rewrites the corresponding virtual function of the base class. For example: t->print(), t2->print(), and t2->funC() are invisible, and ((B*)t2)->funC() can be called normally.
    
    B: For non-virtual functions, it does not involve the problem of checking the virtual function table, and directly calls the functions in the class of the current type. (This is related to the function search order, you have to look at the c++ primer, because you don't know how to know it is not a virtual function if you don't check it.) For example, the above: t->fun(), t2->fun(), t3.fun(), t4 .fun(), which directly calls the function of the base class. k->fun() and b.fun() call functions of derived classes.


It can be found:
    1. If it is an object call, it is directly to find the function in the type class of the object.

    2. If it is a pointer call, whether the score is a virtual function, because the virtual function call involves the question of whose virtual function table is to be checked. If a pointer calls a non-virtual function, it directly calls the function in the class of the pointer type.


Note: The above is what I got based on the code analysis. I don't have a deep understanding of the in-depth C++ memory object model. If there is any error, please point it out~

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325894973&siteId=291194637
Recommended