L5 Polymorphism 1 - Code Examples

Slides 6 Function overloading in Derived class - original

This code does not compile. Why?

#include<iostream>
using namespace std;
 
class Base {
    public:
         virtual void f1(double p1) {
            cout << "Base.f1(double p1) called " << endl;
        }        
};
 
class Derived : public Base {
    public:                    
        void f1(double p1, int p2) {
            cout << "Derived.f1(double p1,int p2) called " << endl;
        }
};
 
int main() {    
    Derived d;
    d.f1(1.0);
    d.f1(1.0, 2);
}

Slide 6 Function overloading in derived class - Solution 1 using polymorphic call

#include<iostream>
using namespace std;
 
class Base {
    public:
        virtual void f1(double p1) {
            cout << "Base.f1(double p1) called " << endl;
        }
 
        virtual void f1(double p1, int p2) = 0; //need to add this to base class
};
 
class Derived : public Base {
    public:        
        void f1(double p1, int p2) {
            cout << "Dervied.f1(double p1,int p2) called " << endl;
        }
};
 
int main() {
    Base *d = new Derived;
    d->f1(1.0);
    d->f1(1.0,3);
 
    /*Derived d;
    d.f1(1.0);
    d.f1(1.0, 3);*/
}

Slide 6 Function overloading in derived class - Solution 1 using polymorphic call

Use this when you do not want Base class to be abstract

#include<iostream>
using namespace std;
 
class Base {
    public:
        virtual void f1(double p1) {
            cout << "Base.f1(double p1) called " << endl;
        }
 
            //need to add this to base class 
        virtual void f1(double p1, int p2) {//empty method} 
};
 
class Derived : public Base {
    public:        
        void f1(double p1, int p2) {
            cout << "Dervied.f1(double p1,int p2) called " << endl;
        }
};
 
int main() {
    Base *d = new Derived;
    d->f1(1.0);
    d->f1(1.0,3);
 
    /*Derived d;
    d.f1(1.0);
    d.f1(1.0, 3);*/
}

Slide 6 - Function overloading example - solution 2 using scope resolution operator (::)

#include<iostream>
using namespace std;
 
class Base {
    public:
         virtual void f1(double p1) {
            cout << "Base.f1(double p1) called " << endl;
        }        
};
 
class Derived : public Base {
    public:                    
        void f1(double p1, int p2) {
            cout << "Derived.f1(double p1,int p2) called " << endl;
        }
};
 
int main() {    
    Derived d;
    d.Base::f1(1.0); //just one change 
    d.f1(1.0, 2);
}

Slide 6 Function overloading example - Solution 3 using overloading with scope resolution operator

#include<iostream>
using namespace std;
 
class Base {
    public:
         void f1(double p1) {
            cout << "Base.f1(double p1) called " << endl;
        }        
};
 
class Derived : public Base {
    public:        
        void f1(double p1) {
            cout << "... calling parent ..." << endl;
            Base::f1(p1);
        }
 
        void f1(double p1, int p2) {
            cout << "Dervied.f1(double p1,int p2) called " << endl;
        }
};
 
int main() {    
    Derived d;
    d.f1(1.0);
    d.f1(1.0, 3);
}

Slide 7 - C++ Gotcha

What is the output? Which overloaded Test() function is called ? Why?

#include<iostream>
using namespace std;
 
class Parent {
    public:
        virtual void test () {
            cout << "Parent " << endl;
        }
};
 
class Child : public Parent {
    public:
        virtual void test () {
            cout << "Child " << endl;
        }
};
 
void Test(Parent *p) {
    cout << "Parent " << endl;
}
 
void Test(Child *c) {
    cout << "Child " << endl;
}
 
int main() {
    Parent *val = new Child();
    Test(val);
    val->test();
}

Slide 7 - C++ Gotcha

What is the output? Does it compile ? Does it run? Why or why not?

#include<iostream>
using namespace std;
 
class Parent {
    public:
        virtual void test () {
            cout << "Parent " << endl;
        }
};
 
class Child : public Parent {
    public:
        virtual void test () {
            cout << "Child " << endl;
        }
};
 
void Test(Parent *p) {
    cout << "Parent " << endl;
}
 
int main() {
    Child *val = new Child();
    Test(val);
    val->test();
}

Slide 8 C++ Gotcha

#include <iostream>
using namespace std;
 
class Parent {
    public:
        void example(int a) {
            cout << "Parent.example(int a)" << endl;
        }
};
 
class Child : public Parent {
    public:
        void example(int a, int b) {
            cout << "Child.example(int a, int b)" << endl;
        }
 
        void example (int a) {
            cout << "Child.example(int a)" << endl;
        }
};
 
int main() {
    Child c;
    c.example(3); //does it call parent method or child method?
}

Slide 8 C++ Gotcha - What is the output?

Are the outputs of calling example(3) twice in the main() the same? Why?

#include <iostream>
using namespace std;
 
class Parent {
    public:
        void example(int a) {
            cout << "Parent.example(int a)" << endl;
        }
};
 
class Child : public Parent {
    public:
        void example(int a, int b) {
            cout << "Child.example(int a, int b)" << endl;
        }
 
        void example (int a) {
            cout << "Child.example(int a)" << endl;
        }
};
 
int main() {
    Child c;
    c.example(3); //with this call you cannot see the problem
 
    Parent *p = new Child();
    p->example(3); //with this call you can see the problem
}

The above code is example of shadowing - see the output of p->example(3);


Slide 8 C++ Gotcha - the solution - use polymorphism

Are the outputs of calling example(3) twice in the main() the same? Why?

#include <iostream>
using namespace std;
 
class Parent {
    public:
        virtual void example(int a) {    //make method virtual 
            cout << "Parent.example(int a)" << endl;
        }
};
 
class Child : public Parent {
    public:
        void example(int a, int b) {
            cout << "Child.example(int a, int b)" << endl;
        }
 
        void example (int a) {
            cout << "Child.example(int a)" << endl;
        }
};
 
int main() {
    Child c;
    c.example(3); //prefer not to use this 
 
    Parent *p = new Child(); 
    p->example(3); //use this - preferred way to write code 
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License