/*
* Copyright ©2026 Soham Pardeshi. All rights reserved.
* Permission is hereby granted to students registered for University of
* Washington CSE 333 for use solely during Summer Quarter 2026 for
* purposes of the course. No other use, copying, distribution, or
* modification is permitted without prior written consent. Copyrights
* for third-party components of this work must be honored. Instructors
* interested in reusing these course materials should contact the author.
*/
#include <iostream>
using std::cout;
using std::endl;
// Demonstrates the two dispatch rules in one program (lecture 12 slide 26).
// M1 is NON-virtual -> resolved by the POINTER's declared type (static).
// M2 is virtual -> resolved by the ACTUAL object (dynamic).
class A {
public:
void M1() { cout << "a1, "; } // static dispatch
virtual void M2() { cout << "a2"; } // dynamic dispatch
virtual ~A() {}
};
class B : public A {
public:
void M1() { cout << "b1, "; } // hides A::M1
void M2() override { cout << "b2"; } // overrides A::M2
};
int main(int argc, char** argv) {
A obj_a;
B obj_b;
A* a_ptr_a = &obj_a; // A* to an A
A* a_ptr_b = &obj_b; // A* to a B <-- the interesting one
B* b_ptr_b = &obj_b; // B* to a B
cout << "a_ptr_a: ";
a_ptr_a->M1(); // a1, (A* type)
a_ptr_a->M2(); // a2 (object A)
cout << endl;
cout << "a_ptr_b: ";
a_ptr_b->M1(); // a1, M1 is static -> follows the A* pointer type
a_ptr_b->M2(); // b2 M2 is virtual -> follows the actual B object
cout << endl;
cout << "b_ptr_b: ";
b_ptr_b->M1(); // b1, (B* type)
b_ptr_b->M2(); // b2 (object B)
cout << endl;
return EXIT_SUCCESS;
}