c++classvirtualdynamic-bindingstatic-binding

Why Derrived pointer binds statically to Derived object meanwhile a Base pointer binds dynamically to Base object?


In the attached code why: p1->print(); binds dynamically? and why: p2->print(); binds statically ?

#include<iostream>

class Base{   public:

virtual void print() 
{     std::cout<<"Base"<<std::endl;}  
    
};

class Derived : public Base{
public:

virtual void print()
{    std::cout<<"Derived"<<std::endl; }  
};
int main()
{
    Base *p1 = new Base{ } ;
     
    p1->print();
     
    std::cout<<"------------------"<<std::endl; 
    Derived *p2 = new Derived{ } ;    
   
    p2->print();
    
    return 0;
}

According to my knowledge a virtual functions binds dynamically if the pointer or reference is of type different than the object type being pointed to by the pointer or reference AND there must be a virtual function to activate dynamic binding.


Solution

  • The function print is searched in the classes according to the static types of the pointers

    Base *p1 = new Base{ } ;
     
    p1->print();
     
    Derived *p2 = new Derived{ } ; 
    
    p2->print();   
    

    As the static type of the pointer p1 is Base * when the function print is searched in the class Base.

    On the other hand, as the static type of the pointer p2 is Derived * then the function print is searched in the class Derived.

    You could write for example

    Base *p3 = new Derived{};
    
    p3->print();
    

    in this case as the static type of the pointer p3 is Base * then the function print will be searched in the class Base. But as the dynamic type of the pointer is Derived * then the function print of the derived class will be called.

    Consider the following demonstration program

    #include <iostream>
    
    class Base
    {
    public:
        virtual void print() const
        {
            std::cout << "Base\n";
        }
    };
    
    class Derived : public Base
    {
    private:
        void print() const override
        {
            std::cout << "Derived\n";
        }
    };
    
    int main()
    {
        Base *p1 = new Derived();
    
        p1->print();
    
        Derived *p2 = new Derived();
    
        // compilation error: private function is inaccessible
        // p2->print();
    
        delete p1;
        delete p2; 
    }
    

    The program output is

    Derived
    

    As you can see though in the class Derived the function is private nevertheless it is called for the pointer p1 because the pointer static type is Base * and within the class Base the function is public.

    However if you will try to call the function using the pointer p2 having the static type Derived * then the compiler will issue an error because the function within the class Derived is private that is inaccessible.