Template
Simple Template Class
//Array.h
#ifndef ARRAY_H
#define ARRAY_H
#include <iostream>
template <class T>
class Array
{
private:
T num;
public:
Array(T);
T getNum() const {return num;}
void setNum(T n);
~Array();
};
#endif
template <class T>
Array<T>::Array(T n):num(n)
{
std::cout<<"Constructor ..."<<std::endl;
}
template <class T>
void Array<T>::setNum(T n)
{
num = n;
}
template <class T>
Array<T>::~Array()
{
std::cout<<"Destructor ..."<<std::endl;
}
//main.cpp
#include <iostream>
#include "Array.h"
int main(int argc, char *argv[])
{
Array<int> array(4);
array.setNum(10);
std::cout<<"Num: "<<array.getNum()<<std::endl;
return 0;
}
Template Class with Pointer
//V.h
#ifndef V_H
#define V_H
#include <iostream>
#include <new>
#include <cstdlib>
#include <string>
template <class T>
class V
{
private:
int size;
T *array;
public:
//constructor
V(int s);
//copy constructor
V(const V &right);
//move constructor
V(V && right);
T *getAddress() const {return array;}
int getSize() const {return size;}
void display() const;
std::string toString() const;
//copy assignment
const V& operator=(const V &right);
//move assignment
V & operator=(V&& right);
//Overloading
//Operator +
V operator+(const V &right);
//Prefix ++ Operator
V operator++();
//Postfix ++ Operator
V operator++(int);
//Operator <
bool operator<(const V &right);
~V();
};
//constructor
template <class T>
V<T>::V(int s):size(s)
{
std::cout<<"Constructor ..."<<std::endl;
try
{
array = new T[size];
}
catch (std::bad_alloc &ba)
{
std::cerr<<ba.what()<<std::endl;
std::cerr<<"Error: Cannot allocate memory ..."<<std::endl;
exit(1);
}
for(int i = 0; i < size; i++)
array[i] = 10*i;
std::cout<<"----End Constructor ..."<<std::endl;
}
//copy constructor
template <class T>
V<T>::V(const V &right):size(right.size), array(size?new T [size]:nullptr)
{
std::cout<<"Copy Constructor ..."<<std::endl;
std::copy(right.array, right.array+size, array);
std::cout<<"----End Copy Constructor ..."<<std::endl;
}
//move constructor
template <class T>
V<T>::V(V && right):size(0), array(nullptr)
{
std::cout<<"Move Constructor ..."<<std::endl;
size = right.size;
array = right.array;
right.size = 0;
right.array = nullptr;
std::cout<<"----End Move Constructor ..."<<std::endl;
}
template <class T>
void V<T>::display() const
{
for(int i = 0; i < size; i++)
std::cout<<array[i]<<" ";
std::cout<<std::endl;
}
template <class T>
std::string V<T>::toString() const
{
std::string str = "V: ";
for(int i = 0; i < size; i++)
str += std::to_string(array[i])+" ";
return str;
}
//copy assignment
template <class T>
const V<T>& V<T>::operator=(const V &right)
{
std::cout<<"Copy Assignment ..."<<size<<std::endl;
if(this != &right)
{
V temp(right);
std::swap(*this, temp);
}
std::cout<<"----End Assignment ..."<<std::endl;
return *this;
}
//move assignment
template <class T>
V<T> & V<T>::operator=(V&& right)
{
std::cout<<"Move Assignment ..."<<std::endl;
if(this != &right)
{
delete [] array;
array = 0;
size = 0;
size = right.size;
array = right.array;
right.size = 0;
right.array = nullptr;
}
std::cout<<"----End Move Assignment ..."<<std::endl;
return *this;
}
//Overloading
//Operator +
template <class T>
V<T> V<T>::operator+(const V &right)
{
std::cout<<"Operator + ..."<<std::endl;
V temp(size+right.size);
std::copy(array, array+size, temp.array);
std::copy(right.array, right.array+right.size, temp.array+size);
std::cout<<"End Operator + ..."<<std::endl;
return temp;
}
//Prefix ++ Operator
template <class T>
V<T> V<T>::operator++()
{
std::cout<<"Prefix ++ ..."<<std::endl;
for(int i = 0; i < size; i++)
array[i] += 1;
std::cout<<"End Prefix ++ ..."<<std::endl;
return *this;
}
//Postfix ++ Operator
template <class T>
V<T> V<T>::operator++(int)
{
std::cout<<"Postfix ++ ..."<<std::endl;
V temp(*this);
for(int i = 0; i < size; i++)
array[i] += 1;
std::cout<<"End Postfix ++ ..."<<std::endl;
return temp;
}
//Operator <
template <class T>
bool V<T>::operator<(const V &right)
{
if(size < right.size)
return true;
else
return false;
}
template <class T>
V<T>::~V()
{
std::cout<<"Destructor ..."<<size<<std::endl;
delete array;
array = 0;
size = 0;
}
#endif
//main.cpp
#include <iostream>
#include <algorithm>
#include <vector>
#include "V.h"
int main(int argc, char *argv[])
{
std::vector<V<double>> container;
V<double> v(10), v2(2), v3(4), v4(20);
container.push_back(v);
container.push_back(v2);
container.push_back(v3);
container.push_back(v4);
std::sort(container.begin(), container.begin()+4);
for(int i = 0; i < container.size(); i++)
std::cout<<container[i].toString()<<std::endl;
return 0;
}
Put #endif after the function declarations to avoid redefinement in .h files
V<T> V<T>::operator+(), specify the return type
Template Default Arguments
//g++ *.cpp -std=c++11
#ifndef V_H
#define V_H
#include <iostream>
#include <new>
#include <cstdlib>
#include <string>
template <class T = int>
class V
{
private:
int size;
T *array;
public:
//constructor
V(int s);
//copy constructor
V(const V &right);
//move constructor
V(V && right);
T *getAddress() const {return array;}
int getSize() const {return size;}
void display() const;
std::string toString() const;
//copy assignment
const V& operator=(const V &right);
//move assignment
V & operator=(V&& right);
//Overloading
//Operator +
V operator+(const V &right);
//Prefix ++ Operator
V operator++();
//Postfix ++ Operator
V operator++(int);
//Operator <
bool operator<(const V &right);
~V();
};
#endif
//main.cpp
#include <iostream>
#include <algorithm>
#include <vector>
#include "V.h"
int main(int argc, char *argv[])
{
std::vector<V<>> container;
V<> v(10), v2(2), v3(4), v4(20);
container.push_back(v);
container.push_back(v2);
container.push_back(v3);
container.push_back(v4);
std::sort(container.begin(), container.begin()+4);
for(int i = 0; i < container.size(); i++)
std::cout<<container[i].toString()<<std::endl;
return 0;
}
Template Inheritance
#ifndef SEARCH_H
#define SEARCH_H
#include <iostream>
#include "V.h"
template <class T>
class Search : public V<T>
{
public:
Search(int s);
bool findItem(const T &);
};
template <class T>
Search<T>::Search(int s):V<T>(s)
{
std::cout<<"Search Constructor ..."<<std::endl;
}
template <class T>
bool Search<T>::findItem(const T &n)
{
T *temp;
temp = V<T>::getAddress();//Explicitly select function template
for(int i = 0; i < V<T>::getSize(); i++)
if(n == temp[i])
return true;
return false;
}
#endif
Explicitly select function template
- T does not appear in the function's parameter list
- Specify the actual arguments before the compiler deduces the template type
- Starting out with C++, Tony Gaddis