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
- Write a class template MyArray that can store up to 10 elements of any type, with the following functions:-
- addElement
- sort
- 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)
