Lab 8 - Polymorphism 2

Some notes on covariance and contravariance

Within the type system of a programming language, a typing rule or a type conversion operator is: covariant if it preserves the ordering, ≤, of types, which orders types from more specific to more generic; contravariant if it reverses this ordering, which orders types from more generic to more specific; invariant if neither of these apply.
In object oriented languages such as C++, if class B is a subtype of class A, then all member functions of B must return the same or narrower set of types as A; the return type is said to be covariant. On the other hand, the member functions of B must take the same or broader set of arguments compared with the member functions of A; the argument type is said to be contravariant. The problem for instances of B is how to be perfectly substitutable for instances of A. The only way to guarantee type safety and substitutability is to be equally or more liberal than A on inputs, and to be equally or more strict than A on outputs. - From Wikipedia

Examples from Lecture

Conversion operator Fraction Example - slides 16 & 17

#include <iostream>
using namespace std;
class Frac {
        Frac(int top, int bottom) {
            t = top;
            b = bottom;
        Frac(int top) {
            t = top;
            b = 1;
        Frac operator*(const Frac &right) {
            return Frac(t*right.t, b*right.b);
        operator double() {
            return (double) t / (double) b;
        void printFrac() {
            cout << t << " / " << b << endl;
        int t; int b;
int main() {
    Frac a(2, 3);
    Frac b(2, 2);
    a = a * b;
    double f = a;
    cout << "f=" << f << endl;
    double bVal = b;
    cout << "bVal=" << bVal <<endl;


Exercises 1: Overload +, - and / operators for the Frac class

Overload the +, - and / operators in the above Frac class to add, subtract and divide fractions.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License