• Nie Znaleziono Wyników

Programming and Data Structures Programming and Data Structures

N/A
N/A
Protected

Academic year: 2021

Share "Programming and Data Structures Programming and Data Structures"

Copied!
10
0
0

Pełen tekst

(1)

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>

(2)

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;

(3)

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;

(4)

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)

(5)

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;

(6)

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);

(7)

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;

}

(8)

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

(9)

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

(10)

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();

Cytaty

Powiązane dokumenty

● the public method changing the state of an object (modifier) is to check the compliance of such a change with the rules described by invariants. ● if the rules are exceeded,

● destructor, copy constructor and assignment operator (as for bounded) insertion/removal

(3) set a dedicated pointer (killer) to the last node using the address in the next pointer of the node pointed to by tmp (or the head pointer if tmp is empty, or the tail pointer

(1) set the pred pointer on the node preceding the deleted node, and succ on the node to be removed (if there is no node we are looking for, throw an exception or abort the

(1) create two auxiliary pointers: set pred to an empty address, and succ on to the address of the first node (head) and pass the auxiliary pointers towards the end of the list

(1) by comparing values, go from root to children and set the pred pointer on the parent node to be removed, and succ on the node to be removed (if there is no node we are looking

(1) invoke two auxiliary pointers set on the adjacent nodes pred and succ (assume that the pointers next in the preceding nodes pointed to by succ are already inverted, succ is

● input/output streams: iostream, fstream, sstream, iomanip. ● string