Programming and Data Structures Programming and Data Structures
Lecture 5 Lecture 5
Dr Piotr Cybula <piotr.cybula@wmii.uni.lodz.pl>
Dr Piotr Cybula <piotr.cybula@wmii.uni.lodz.pl>
Generic structures Generic structures
Structure of a dynamic array with integer values:
struct Array { private:
int *array;
int size;
public:
Array(int _size = 10)
{ size = _size; array = new int[size];
} ~Array()
{ if(size > 0) delete [] array;
} int length() const { return size; }
int& operator[](int index) { return array[index]; } };
Array t(5);
t[0] = 7;
Generic structures Generic structures
Structure of a dynamic array with real values:
struct Array { private:
float *array;
int size;
public:
Array(int _size = 10)
{ size = _size; array = new float[size];
} ~Array()
{ if(size > 0) delete [] array;
} int length() const { return size; }
float& operator[](int index) { return array[index]; } };
Array t(5);
t[0] = 7.5;
Generic programming Generic programming
●
implemented in C++ in the form of template structures
●
templates allow reuse of the existing data structure source code for multiple versions of this structure with the same interface but different types for
internal components (generic/generalized programming, parameterized structures)
●
the template keyword tells the compiler that a structure uses an undefined data type that is a parameter to that structure
●
during instantiation of a template with a specific type, the compiler replaces each instance of a parametric type with the specified type and compiles the data structure (the so-called static polymorphism)
●
templates can be parameterized with types or values (there can be many of
them and they can have default values)
Template structure Template structure
Structure of the template dynamic array:
template<typename T> struct Array //template structure { private:
T *array; //T is a template parameter being a type int size;
public:
Array(int _size = 10)
{ size = _size; array = new T[size];
} ~Array()
{ if(size > 0) delete [] array;
} int length() const { return size; }
T& operator[](int index) { return array[index]; } };
Array<int> t1(5); Array<float> t2(10); //instantiations t1[0] = 7; t2[0] = 7.5;
Template parameters Template parameters
Structure of a dynamic array which is a two-parameter template:
template<typename T, int size = 10> struct Array //template { private:
T array[size]; //size is a template parameter being a value //size cannot be changed
public:
Array() {}
~Array() {}
int length() const { return size; }
T& operator[](int index) { return array[index]; } };
Array<int, 5> t1; //instantiation, size must be a constant Array<float> t2; //instantiation with default value for size Array<Student, 10> t3; //instantiation with a structure type t1[0] = 7;
t2[0] = 7.5;
cout << t2.length();
t3[0] = Student(”Scott Tiger”);
t3[0].setIndex(12345);
Template methods Template methods
●
when implementing methods of the template structure outside the structure, we use the keyword template with the same template parameters (the
implementation must take place in the header file!)
template<typename T, int size>
T& Array<T, size>::operator[](int index) //template method { if(index < 0 || index >= size)
throw range_error("bad index");
return array[index];
}
//the result and the parameter types are templates template<typename T, int size>
Array<T, size>&
Array<T, size>::operator=(const Array<T, size>& arr) { if(this != &arr)
for(int i = 0; i < size; i++) array[i] = arr.array[i];
return *this;
}
Template interface Template interface
●
typical for a template is: «I will take any type»
●
sometimes a template implies an interface of the type being a parameter
●
some operators or methods for the instantiation class are required: «I will take any type that supports ...»
Array<Student> t;
t.print(); //compile-time error, no operator<< for Student //after the declaration of the operator
ostream& operator<<(ostream &out, const Student &s) { ...
return out;
}
Array<Student> t;
t.print(); //OK
Template composition Template composition
template<typename T, int size>
struct NamedArray //structure with template field is template { private:
Array<T, size> array; //template field string name;
public:
NamedArray(string n);
T& operator[](int index);
T sum() const; //T must support operator+
T max() const; //T must support operator<
… //other methods };
NamedArray<float, 3> marks("My marks");
marks[0] = 4.5;
marks[1] = 5.0;
marks[2] = 4.0;
cout << marks.sum() / 3;
cout << marks.max();
cout << marks.length(); //compile-time error, hidden method
Recursive templates Recursive templates
●
the template structure can be parameterized with a template type
●
in the compiler version before C++11 it is necessary to put a space between consecutive angle brackets (> > instead of >>)
//5-item array of 10-item arrays of integers //dynamic size version
Array< Array<int> > t(5);
//static size version
Array< Array<int, 10>, 5> t;
t[0][0] = 5;
cout << t.length();
cout << t[0].length();