0

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.

ANDREW
  • 21
  • 4
  • A virtual function is *always* called with dynamic lookup, at least conceptually (a compiler may of course call directly or even inline if it can prove that's the correct function). The dynamic lookup will always call the function definition in the actual object referred to, independent of the pointer or reference type. The two may be the same, then that's what's being called. No surprise there. – Peter - Reinstate Monica Feb 25 '23 at 19:55
  • How did you come to the conclusion that one binds dynamically and the other binds statically? (I would expect the same behavior in either case in your example since the pointer types match the object types.) You could answer this by editing your question to add the output you'd expect if both bound dynamically and the output you'd expect if both bound statically. Then to complete the picture, add the output you actually get. – JaMiT Feb 25 '23 at 21:20
  • It is not me who concluded, it is the online instructor, he said in the video p1->print( ); binds dynamically, and this really confused me. – ANDREW Feb 26 '23 at 17:47

2 Answers2

1

Both calls are dynamically bound it just makes no difference in your example.

Dynamic binding means that a call will be resolved based on the dynamic, runtime type of the object pointed to rather than the static type of the pointer pointing to it. In your example, however, both of those types are the same, so the result will be identical.

Dynamic binding only comes into play when the static type of the object is different from the type of the pointer pointing to it. For example:

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

Demo

This will print "Derived" even though the static type of p3 is Base* because the dynamic type of the object pointed to is Derived.

Miles Budnek
  • 28,216
  • 2
  • 35
  • 52
  • Base * p4 = new Base { } ; p4->print( ) ; this is dynamic binding even though both static and dynamic types are match , why ? – ANDREW Feb 25 '23 at 19:40
  • I'm not sure what you're getting at. You already covered that case in your original example. It's dynamically bound because `print` is declared `virtual` and called via a pointer or reference. The dynamic dispatch finds `Base::print` because that's the runtime type of the object pointed to. – Miles Budnek Feb 25 '23 at 19:48
0

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.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335