0

The following code has 4 classes: Base1, Derived1 (derived from Base1), Base2, Derived2 (derived from Base2). Both base classes have integer data1 and display_data() functions. Both derived classes have integers data1 and data2, and display_data() functions.

I tried 4 cases in my code, which can be seen in the main function. I am unable to figure which of these is a case of static binding and which is dynamic. I need some help here. I would also like to know, which of these cases can be considered as "function overriding".

CODE:

#include <iostream>
using namespace std;

class Base1{
protected:
    int data1;

public:
    Base1(int idata1 = 0) {
        data1 = idata1;
    }

    void display_data() {
        cout << "Base1: " << data1 << endl;
    }
};

class Derived1 : public Base1 {
protected:
    int data2;

public:
    Derived1(int idata1 = 0, int idata2 = 0) {
        data1 = idata1;
        data2 = idata2;
    }

    void display_data() {
        cout << "Derived1: " << data1 << ' ' << data2 << endl;
    }
};


class Base2 {
protected:
    int data1;

public:
    Base2(int idata1 = 0) {
        data1 = idata1;
    }

    virtual void display_data() {
        cout << "Base2: " << data1 << endl;
    }
};

class Derived2 : public Base2 {
protected:
    int data2;

public:
    Derived2(int idata1 = 0, int idata2 = 0) {
        data1 = idata1;
        data2 = idata2;
    }

    void display_data() {
        cout << "Derived2: " << data1 << ' ' << data2 << endl;
    }
};

int main()
{
    // case 1
    Derived1 d1(1, 10);
    d1.display_data();

    // case 2
    Base1* d2 = new Derived1(2, 20);
    d2->display_data();

    // case 3
    Derived2 d3(3, 30);
    d3.display_data();

    // case 4
    Base2* d4 = new Derived2(4, 40);
    d4->display_data();

    return 0;
}

OUPUT:

Derived1: 1 10
Base1: 2
Derived2: 3 30
Derived2: 4 40
Amethyst
  • 13
  • 5
  • The key here is the [virtual](https://en.cppreference.com/w/cpp/language/virtual) function specifier. When a member function is not `virtual`, the version used is determined at compile time on the basis of the type of the object invoking the function--hence in case 2 you see `Base1::display_data` being called, because it's called from a `Base1*` pointer. When the function is `virtual`, the version used is determine at runtime on the basis of the actual most-derived type of the object, which you can see in case 4. – Nathan Pierson Mar 23 '21 at 13:50
  • When you read "virtual", think "dynamically bound and overridable". – molbdnilo Mar 23 '21 at 13:55

1 Answers1

1

Here is my attempt to explain it in a simple way :)

Static binding occurs when an object is associated with a member function based on the static type of the object (understand the type of its class).

Dynamic binding occurs when a pointer or reference is associated with a member function based on the dynamic type of the object (understand the instance of the variable at runtime).

Before reading on: Dynamic binding works only with pointers or references and with virtual functions for the base class.

The first call is a static binding (also called early binding)because everything needed to call the function is known at compile-time.

    Derived1 d1(1, 10);
    d1.display_data();

You know that the d1 instance is an automatic variable of type Derived1 and then it will call the method Derived1::display_data().

  • The first conditions is not OK: d1 is not a pointer nor is it a reference.
  • the second conditions is not OK: Derived1::display_data is not virtual.

For the second call

    Base1* d2 = new Derived1(2, 20);
    d2->display_data();

We see that the declared type of the variable d2 is of Base1 but the instance is of Derived1 (it is correct because of inheritance thus Derived1 is a Base1 class). But you do not know yet at if the display_data method that it will call is the one from Base1::display_data o the one from Derived1::display_data.

  • The first conditions is OK because we have the d2 of type pointer Base1*.
  • The second condition is not OK because the Base1::display_data is not virtual. Thus it is still a static binding then the function that will be called is the one with the declared type, thus the code will call Base1::display_data

For the third call

    // case 3
    Derived2 d3(3, 30);
    d3.display_data();

This will result in a static binding then calling the Derived3::display_data

  • The first conditions is not OK: d3 is not a pointer nor is it a reference.
  • the second conditions is OK: Derived2::display_data is virtual.

For the fourth call

    Base2* d4 = new Derived2(4, 40);
    d4->display_data();

This time it is a dynamic binding.

  • The first conditions is OK: d4 is a pointer.
  • the second conditions is OK: Derived2::display_data is virtual. thus instead of calling the method from the declared type base2, it will call the method from the declared instance at runtime Derived2::display_data
Pat. ANDRIA
  • 2,330
  • 1
  • 13
  • 27
  • Is there any practical way to find whether a certain part of code is using static-binding or dynamic-binding? Something like an ide feature or some print statements, to be able to use for any other cases that arise. Or do we have to understand it the way you explained? Also, can you also please clarify whether all of these cases are considered as "method overriding"? I might be confused about its definition due to the multiple resources available online. Is it related to it being virtual? Thankyou for such a detailed answer. This clears the concept of static and dynamic binding. :) – Amethyst Mar 23 '21 at 15:15
  • 1
    The practical way is to find the keyword `virtual` as told by @molbdnilo. You may wan to read why `destructor`shall be `virtual` or not and have a better understanding of why a method shall be virtual also. Indeed, dynamic binding is exploited through the inheritance (the overrding) of a a virtual method. Method overirding is the fact of redefining an base class method in a derived class method but changing its definition (exactly what you did for Derived classes). You may have some concise litterature [here](https://techdifferences.com/difference-between-static-and-dynamic-binding.html) – Pat. ANDRIA Mar 23 '21 at 15:50