• Nie Znaleziono Wyników

Dariusz Wardowski

N/A
N/A
Protected

Academic year: 2021

Share "Dariusz Wardowski"

Copied!
14
0
0

Pełen tekst

(1)

Dariusz Wardowski

(2)

Wielokrotne wykorzystywanie kodu

Poza dziedziczeniem oraz kompozycją klas, język C++ udostępnia kolejne narzędzie w postaci szablonów, które służą do wielokrotnego wykorzystywania kodu.

Szablony służą do tworzenia ogólnych deklaracji klas (lub funkcji). W ten sposób realizowana jest koncepcja tzw. typów sparametryzowanych. Typ jest argumentem przekazywanym do ogólnego wzorca klasy lub funkcji.

Stos<int> s1;

Stos<double> s2;

Stos<Pracownik> s3;

(3)

Klasa Punkt i klasa … Punkt

class Punkt {

private:

int x, y;

public:

Punkt();

Punkt(int,int);

int getX();

int getY();

void setXY(int,int);

};

class Punkt {

private:

double x, y;

public:

Punkt();

Punkt(double,double);

double getX();

double getY();

void setXY(double,double);

};

Dobrym rozwiązaniem jest zamiana powyższych klas na jedną definicję szablonu, posługując się tzw. parametrem typów.

(4)

Szablon klasy

#ifndef PUNKTTP_H_

#define PUNKTTP_H_

template <typename T>

class Punkt {

private:

T x, y;

public:

Punkt();

Punkt(T,T);

T getX();

T getY();

void setXY(T,T);

void wypisz();

};

template <typename T>

Punkt<T>::Punkt() {

x = y = 0;

}

template <typename T>

Punkt<T>::Punkt(T _x, T _y) {

x = _x;

y = _y;

}

template <typename T>

T Punkt<T>::getX() {

return x;

}

template <typename T>

T Punkt<T>::getY() {

return y;

}

template <typename T>

void Punkt<T>::setXY(T _x, T _y) {

x = _x;

y = _y;

}

#endif

(5)

Konkretyzacja szablonu

Chcąc wygenerowad klasę na podstawie zdefiniowanego szablonu należy jawnie określid typ parametru (tzn. dokonad jawnej konkretyzacji typu).

#include <iostream>

#include "Punkttp.h"

using namespace std;

int main() {

Punkt<int> p(3,2);

cout << p.getX();

Punkt<double> z(3.2,2.1);

z.setXY(5.01,3);

return 0;

}

Konkretyzując klasę możemy użyd zarówno typu wbudowanego jak i obiektu jakiejś klasy.

(6)

Szablon tablicy

template <typename Typ, int n>

class TabTP {

private:

Typ tablica[n];

public:

TabTP() {};

explicit TabTP(Typ &);

virtual Typ & operator[](int);

};

Template<typename Typ, int n>

TabTP<Typ,n>::TabTP(Typ & w) {

for (int i=0; i<n; i++) tablica[i]=w;

}

Template<typename Typ, int n>

Typ & TabTP<Typ,n>::operator[](int i) {

if (i<0 || i>=n) {cerr << „Blad!”; exit(1);}

return tablica[i];

}

Typ – argument typu n – argument wyrażenia

TabTP<double,10> t1;

TabTP<int,100> t2;

TabTP<char,20> t3;

(7)

Nie-typy, czyli argumenty wyrażenia

Argumenty wyrażenia podlegają następującym ograniczeniom:

-Typ argumentu może byd: całkowity, wyliczeniowy, referencją, wskaźnikiem - W kodzie szablonu nie można zmieniad wartości argumentu

- W kodzie szablonu nie można pobierad adresu argumentu

- Przy konkretyzacji szablonu wartośd użyta dla argumentu powinna byd stałą

(8)

Dziedziczenie i szablony

Szablony klas mogą służyd do tworzenia klas, które będą pełniły rolę klas macierzystych.

template <typename T1>

class A {

private:

T x;

… };

template <typename T2>

class B: public A<T2>

{

… }

(9)

Klasy szablonowe jako składowe innych klas

Klasy szablonowe mogą służyd jako składowe dla innych klas szablonowych.

template <typename T1>

class A {

… };

template <typename T2>

class B {

A<T2> y;

… }

(10)

Klasa szablonowa jako argument typu

Klasy szablonowe mogą stanowid argument typu dla innych szablonów.

template <typename T1>

class A {

… };

template <typename T2>

class B {

… }

A< B<int> > x;

Inny przykład:

Tablica < Stos<double> > TAB; //tablica stosów liczb zmiennoprzecinkowych

(11)

Rekurencja w szablonach

Konkretyzując szablon możemy korzystad z rekurencji:

TabTP< TabTP<double,10>, 20> T;

T jest dwudziestoelementową tablicą, w której każdy element jest dziesięcioelementową tablicą liczb zmiennoprzecinkowych.

(12)

Więcej niż jeden argument typu

W języku C++ możemy używad szablony, które posiadają więcej niż jeden argument typu.

Korzystając z tej możliwości możemy utworzyd klasę do przechowywania dwóch elementów różnych typów.

template <typename T1, typename T2>

class Pair {

private: T1 x, T2 y;

public:

T1 & first(const T1 & f) {x = f; return x;};

T2 & second(const T2 & s) {y = s; return y;};

T1 first() const {return x;}

T2 second() const {return y;}

Pair(const T1 & f, const T2 & s) : x(f), y(s) {}

Pair(){}

};

(13)

Użycie szablonu Pair

Pair<int,double> points[4] = {

Pair<int,double>(1,1.2), Pair<int,double>(-4,1.0), Pair<int,double>(100,0.45), Pair<int,double>(12,1.2) };

Pair<char *, int> adresy[2] = {

Pair<char *, int>(„ul. Banacha”,22), Pair<char *, int>(„ul. Zielona”,13) };

(14)

Dziękuję za uwagę

Cytaty

Powiązane dokumenty

Współczynniki dopasowania linii prostej do zbioru punktów można też wyznaczyć bez rysowania wykresu, przy pomocy funkcji statystycznej REGLINP (skrót od Regresji

•Jeżeli obiekt utworzono w sposób dynamiczny (tzn. za pomocą operatora new), wówczas destruktor tego obiektu jest wywoływany automatycznie, gdy użyjemy delete do

Konstruktory, które posiadają jeden argument mogą pełnić rolę funkcji konwersji, czyli mechanizmu, który przekształca wartość argumentu na typ

Jeżeli wskaźnik (referencja) wskazuje na obiekt typu B, wówczas nastąpi wywołanie destruktora ~B() klasy potomnej, a następnie ~A() klasy macierzystej... Wiązanie statyczne

Jeżeli klasa dziedziczy z klas, które dziedziczą po wirtualnej klasie macierzystej, wówczas konstruktor tej pierwszej klasy musi jawnie wywoływad konstruktor tej drugiej klasy.

Definiując szablon klasy możemy korzystać zarówno z wartości domyślnych dla parametrów typu jaki i wartości domyślnych dla argumentów wyrażeń (nie-typów).. Definiując szablon

Metoda end() zwraca iterator wskazujący na element, który znajduje się za ostatnim elementem kontenera, element ten nazywany jest elementem ograniczającym. it

 opcjonalne - nie każdy obiekt danej klasy posiada wartość dla tego atrybutu, np.: nazwisko panieńskie, stosunek do służby wojskowej, lista poprzednich miejsc pracy; na