Dynamic Type or Late Binding in C++

I just love learning and sharing because it's all about Feyman's technique.  I was still not satisfied only with the definition of the Late binding, so I wanted to dig more. That's how this post got created. 

#include <iostream>
using namespace std;

class Subjects {
public:
    //virtual
    void fillSurvey() {cout << "Subjects : Fill the survey" << endl;};
};

class Physics : public Subjects {
public:
    //virtual  
    void fillSurvey() {cout << "Physics : Fill the survey" << endl;}; 
};

class BigData : public Physics {
public:
};

class CloudComputing : public Subjects {
public:
};

int main() {
    Physics *pilot = new Physics;
    BigData *Ben = new BigData;
    CloudComputing *Clara = new CloudComputing;

    Subjects *Shirley = Ben;
    Shirley->fillSurvey();  
    
    return 1;
}

Output:

1
Subjects : Fill the survey


At the below line of code, Subjects is the static type of Shirley, and BigData is the dynamic type of Shirley. I hope you already read this post about virtual function.  

Subjects *Shirley = Ben;

The virtual is not turned on, so it called the static type of the Subjects object. 

Now, I turned on only the Physics class' virtual, but still the same behavior. Because the virtualness of the static type of Shirley should be checked by compiler. Since it is turned off, the compiler always gets the static type. 

#include <iostream>
using namespace std;

class Subjects {
public:
    //virtual
    void fillSurvey() {cout << "Subjects : Fill the survey" << endl;};
};

class Physics : public Subjects {
public:
    virtual  
    void fillSurvey() {cout << "Physics : Fill the survey" << endl;}; 
};

class BigData : public Physics {
public:
};

class CloudComputing : public Subjects {
public:
};

int main() {
    Physics *pilot = new Physics;
    BigData *Ben = new BigData;
    CloudComputing *Clara = new CloudComputing;

    Subjects *Shirley = Ben;
    Shirley->fillSurvey();  
    
    return 1;
}


Output:

1
Subjects : Fill the survey


As I want to ensure who is the culprit, I turned off the Physics virtual and turned on the Subjects. It is clear now, and I still stand on my previous statement here. 

#include <iostream>
using namespace std;

class Subjects {
public:
    virtual
    void fillSurvey() {cout << "Subjects : Fill the survey" << endl;};
};

class Physics : public Subjects {
public:
    //virtual  
    void fillSurvey() {cout << "Physics : Fill the survey" << endl;}; 
};

class BigData : public Physics {
public:
};

class CloudComputing : public Subjects {
public:
};

int main() {
    Physics *pilot = new Physics;
    BigData *Ben = new BigData;
    CloudComputing *Clara = new CloudComputing;

    Subjects *Shirley = Ben;
    Shirley->fillSurvey();  
    
    return 1;
}

Output:

1
Physics : Fill the survey

Seeing the virtuality, the compiler decided to react on the dynamic type of the pointer Shirley which is BigData. As BigData doesn't have the method fillSurvey, it worked in its heirarchy and called its parent which is Physics method. 

Now I turned on the Physics virtual also, but still the behavior is same. 

#include <iostream>
using namespace std;

class Subjects {
public:
    virtual
    void fillSurvey() {cout << "Subjects : Fill the survey" << endl;};
};

class Physics : public Subjects {
public:
    virtual  
    void fillSurvey() {cout << "Physics : Fill the survey" << endl;}; 
};

class BigData : public Physics {
public:
};

class CloudComputing : public Subjects {
public:
};

int main() {
    Physics *pilot = new Physics;
    BigData *Ben = new BigData;
    CloudComputing *Clara = new CloudComputing;

    Subjects *Shirley = Ben;
    Shirley->fillSurvey();  
    
    return 1;
}

Output:
1
Physics : Fill the survey

 If the dynamic type of object's versions is available either in BigData or its parent Physics, BigData function fillSurvey will be invoked if it is defined or Physics will be invoked if BigData version is not available.

it by default invokes static version of the function 'fillSurvey'.

Now, I again digged more and removed the fillSurvey from Physics. See the results :-) 

#include <iostream>
using namespace std;

class Subjects {
public:
    virtual
    void fillSurvey() {cout << "Subjects : Fill the survey" << endl;};
};

class Physics : public Subjects {
public:
    //virtual  
    //void fillSurvey() {cout << "Physics : Fill the survey" << endl;}; 
};

class BigData : public Physics {
public:
};

class CloudComputing : public Subjects {
public:
};

int main() {
    Physics *pilot = new Physics;
    BigData *Ben = new BigData;
    CloudComputing *Clara = new CloudComputing;

    Subjects *Shirley = Ben;
    Shirley->fillSurvey(); 

    
    
    return 1;
}


Output:

1
Subjects : Fill the survey

If the dynamic type of object's versions is not available, it by default invokes static version of the function 'fillSurvey'.

Now, I removed the Subjects virtual method and revoked the Physics method. 

#include <iostream>
using namespace std;

class Subjects {
public:
    //virtual
    //void fillSurvey() {cout << "Subjects : Fill the survey" << endl;};
};

class Physics : public Subjects {
public:
    virtual  
    void fillSurvey() {cout << "Physics : Fill the survey" << endl;}; 
};

class BigData : public Physics {
public:
};

class CloudComputing : public Subjects {
public:
};

int main() {
    Physics *pilot = new Physics;
    BigData *Ben = new BigData;
    CloudComputing *Clara = new CloudComputing;

    Subjects *Shirley = Ben;
    Shirley->fillSurvey(); 

    
    
    return 1;
}    

Output:

1
2
3
In function 'int main()':
Line 30: error: 'class Subjects' has no member named 'fillSurvey'
compilation terminated due to -Wfatal-errors.


During the compilation, early binding happens. Shirley's static type is Subjects, so the compiler tries to fill the machine instruction for jump for this line Shirley->fillSurvey();. As the compiler couldn't find it, it will throw and error. 

Hence, it is mandatory to have the method in the static type of the class. 




Comments