Programming with C++ - Day7 || Wong Edition || B.Tech Diaries

Lab #7 - Templates

Question 1 - Function Template

The format for function declaration is:

template <class identifier> function_declaration;

The format for function call is:

function_name <type> (parameters);
  • Write a function template getLarger that takes two parameters of any (same) type and returns the larger of the two.
  • Write a class Vehicle and provide the implementation for the ">" operator. Use the Vehicle in the getLarger function from (a). E.g. Bus > Car > Auto > Scooter

Solution:


#include <iostream>

// question 1
class Vehicle
{
private:
    std::string name;
    int legs;
    double cost;

public:
    Vehicle()
    {
    }
    Vehicle(std::string n, int l, double c)
    {
        legs = l;
        cost = c;
        name = n;
    }
    ~Vehicle()
    {
    }
    bool operator>(Vehicle v)
    {
        return (legs > v.legs) || (legs == v.legs && cost > v.cost);
    }
    bool operator<(Vehicle v)
    {
        return (legs < v.legs) || (legs == v.legs && cost < v.cost);
    }

    bool operator==(Vehicle v)
    {
        return (legs == v.legs) && (cost == v.cost);
    }

    operator std::string() const
    {
        return name + "(" + std::to_string(legs) + "," + std::to_string(cost) + ")";
    }

    std::string to_string()
    {
        return name + "(" + std::to_string(legs) + "," + std::to_string(cost) + ")";
    }

    friend std::ostream &operator<<(std::ostream &out, const Vehicle &v);
};

template <typename T>
T getLarger(T a, T b)
{
    return (a > b) ? a : b;
}

template <typename T>
T getSmaller(T a, T b)
{
    return (a < b) ? a : b;
}

int main(int argc, char const *argv[])
{
    int N = 10;

    Vehicle vehicles[N];

    for (int i = 0; i < N; i++)
    {
        int legs = rand() % 4 + 2;
        double cost = rand() % 700 + 100;
        std::string name = "Vehicle " + std::to_string(i + 1);
        vehicles[i] = Vehicle(name, legs, cost);
    }

    std::cout << std::endl
                << "========Comparison of Vehicles========"
                << std::endl;

    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N - i - 1; j++)
        {
            Vehicle v1 = getLarger<Vehicle>(vehicles[j + 1], vehicles[j]);
            Vehicle v2 = getSmaller<Vehicle>(vehicles[j + 1], vehicles[j]);
            vehicles[j] = v1;
            vehicles[j + 1] = v2;
        }
    }

    for (int i = 0; i < N; i++)
    {
        std::cout << vehicles[i];
        if (i != N - 1)
            std::cout << " > ";
    }
    std::cout << std::endl
                << std::endl;

    return 0;
}


========Comparison of Vehicles========
Vehicle 1(5,286.000000) > Vehicle 8(5,226.000000) > Vehicle 4(4,592.000000) > Vehicle 7(4,559.000000) > Vehicle 6(4,427.000000) > Vehicle 3(3,635.000000) > Vehicle 5(3,621.000000) > Vehicle 2(3,315.000000) > Vehicle 9(2,626.000000) > Vehicle 10(2,536.000000)

Question 2 - Class Template

The format for function declaration is:

template <class identifier> class classname
  1. Write a class template MyArray that can store up to 10 elements of any type, with the following functions:-
    • addElement
    • sort
    • print
  2. Store Vehicle instances from Question 1 in MyArray and sort them.

Solution:


...
// question 2
template <typename T>
class MyArray
{
private:
    T *arr;
    int capacity, size;

public:
    MyArray()
    {
        capacity = 8;
        arr = new T[capacity];
        size = 0;
    }
    bool addElement(T item)
    {
        if (size == capacity)
        {
            T *temp = new T[capacity * 2];
            for (int i = 0; i < size; i++)
            {
                temp[i] = arr[i];
            }
            delete[] arr;
            arr = temp;
            capacity *= 2;
        }
        arr[size++] = item;
        return true;
    }
    void sort()
    {
        for (int i = 0; i < size; i++)
        {
            for (int j = i + 1; j < size; j++)
            {
                if (arr[j] > arr[i])
                {
                    std::swap(arr[i], arr[j]);
                }
            }
        }
    }
    T get(int index)
    {
        return arr[index];
    }
    T operator[](int index)
    {
        return arr[index];
    }
    std::string print()
    {
        std::string str = "[";
        for (int i = 0; i < size; i++)
        {
            str += arr[i].to_string();
            if (i != size - 1)
                str += ", ";
        }
        str += "]";
        return str;
    }
};

int main(int argc, char const *argv[])
{
    int N = 15;

    MyArray<Vehicle> vehicles;

    for (int i = 0; i < N; i++)
    {
        int legs = rand() % 4 + 2;
        double cost = rand() % 1000 * 0.1234 + 100;
        std::string name = "Vehicle " + std::to_string(i + 1);
        vehicles.addElement(Vehicle(name, legs, cost));
    }

    std::cout << "Vehicles before sorting" << std::endl;
    std::cout << vehicles.print()
              << std::endl
              << std::endl;

    std::cout << "Vehicles after sorting" << std::endl;

    vehicles.sort();

    return 0;
}


    Vehicles before sorting
[Vehicle 1(5,209.332400), Vehicle 2(3,212.911000), Vehicle 3(3,141.339000), Vehicle 4(4,160.712800), Vehicle 5(3,151.951400), Vehicle 6(4,103.331800), Vehicle 7(4,107.280600), Vehicle 8(5,214.268400), Vehicle 9(2,152.568400), Vehicle 10(2,190.822400), Vehicle 11(5,145.411200), Vehicle 12(5,152.938600), Vehicle 13(4,165.402000), Vehicle 14(4,115.178200), Vehicle 15(5,116.659000)]

Question 3 - Friend Function

In Question 1 and Question 2, the `printTypeString()` function in the Vehicle class was used to output Vehicle information.

Overload the cout "<<" operator to output Vehicle information. Declare the "<<" function as friend in the Vehicle class, so as to access Vehicle's private attributes:-

friend ostream& operator<<(ostream &out, const Vehicle& v)

Note: friend functions and classes should be used sparingly as they break the good idea of encapsulation.

Solution:


...
// question 3
std::ostream &operator<<(std::ostream &out, const Vehicle &v)
{
    out << v.operator std::string();
    return out;
}

int main(int argc, char const *argv[])
{
    int N = 15;

    MyArray<Vehicle> vehicles;

    for (int i = 0; i < N; i++)
    {
        int legs = rand() % 4 + 2;
        double cost = rand() % 1000 * 0.1234 + 100;
        std::string name = "Vehicle " + std::to_string(i + 1);
        vehicles.addElement(Vehicle(name, legs, cost));
    }

    std::cout << "Vehicles before sorting" << std::endl;
    std::cout << vehicles.print()
                << std::endl
                << std::endl;

    std::cout << "Vehicles after sorting" << std::endl;

    vehicles.sort();

    std::cout << vehicles.print() << std::endl;
    std::cout << std::endl;

    std::cout << vehicles[0] << std::endl;

    return 0;
}    

Output:


Vehicles before sorting
[Vehicle 1(5,209.332400), Vehicle 2(3,212.911000), Vehicle 3(3,141.339000), Vehicle 4(4,160.712800), Vehicle 5(3,151.951400), Vehicle 6(4,103.331800), Vehicle 7(4,107.280600), Vehicle 8(5,214.268400), Vehicle 9(2,152.568400), Vehicle 10(2,190.822400), Vehicle 11(5,145.411200), Vehicle 12(5,152.938600), Vehicle 13(4,165.402000), Vehicle 14(4,115.178200), Vehicle 15(5,116.659000)]

Vehicles after sorting
[Vehicle 8(5,214.268400), Vehicle 1(5,209.332400), Vehicle 12(5,152.938600), Vehicle 11(5,145.411200), Vehicle 15(5,116.659000), Vehicle 13(4,165.402000), Vehicle 4(4,160.712800), Vehicle 14(4,115.178200), Vehicle 7(4,107.280600), Vehicle 6(4,103.331800), Vehicle 2(3,212.911000), Vehicle 5(3,151.951400), Vehicle 3(3,141.339000), Vehicle 10(2,190.822400), Vehicle 9(2,152.568400)]

Vehicle 8(5,214.268400)

Share:

0 comments:

Post a Comment