În urma parcurgerii acestui articol studentul va:
Motivul principal pentru care folosim C++ în cadrul SD este datorită funcționalității oferite de template-uri.
Acestea permit generalizarea tipurilor de date folosite în interiorul funcțiilor și claselor.
Sintaxa pentru acestea este:
template <class identifier> declaratie; template <typename identifier> declaratie;
declaratie poate fi fie o funcție, fie o clasă. Nu există nicio diferență între keyword-ul class și typename - important este că ceea ce urmează după ele este un placeholder pentru un tip de date.
În primul rând template-urile pot fi aplicate funcțiilor.
Un exemplu comun și simplu este următorul:
template<typename T> T getMax(T a, T b) { return a > b ? a : b; }
Funcția poate fi apelată astfel:
getMax<int>(2, 3); getMax<double>(3.2, 4.6);
Concret, să presupunem că avem o clasă numită KeyStorage care are:
Vrem să putem folosi codul clasei indiferent de tipul de date al membrului.
Iată cum putem face acest lucru:
template<typename T> class KeyStorage { public: int key; T member; };
În funcția main, să presupunem că vrem să folosim clasa cu membrul de tip long.
#include "KeyStorage.h" int main() { KeyStorage<long> keyElement; return 0; }
Practic, oriunde folosim tipul de date T în clasă, este înlocuit cu tipul pe care îl specificăm.
Sunt destul de multe lucruri de spus despre template-uri, dar ne vom concentra pe lucrurile care schimbă modul în care ați implementat până acum.
Template-urile sunt de fapt indicii pentru compilator pentru a genera cod la rândul lui! Practic, voi îi spuneți compilatorului un șablon generic pe care ați vrea să-l folosiți și el trebuie să fie pregătit să îl pună la dispoziția voastră când aveți nevoie.
Ce trebuie să rețineți din asta? Totul se întâmplă la compile time, nu la run time.
Compilatorul practic analizează modul în care voi folosiți clasa respectivă și generează pentru fiecare mod în care o folosiți șablonul corespunzător. Folosirea KeyStorage<int> și KeyStorage<float> determină compilatorul să genereze cod pentru ambele clase (înlocuind o dată T cu int și altă cu float).
Pentru că totul se întâmplă la compile time, înseamnă că în momentul în care compilatorul întâlnește secvența de cod ce folosește template-uri trebuie să știe toate modurile în care aceasta este folosita.
Asta înseamnă că:
Ultimul rând de fapt forțează folosirea template-ului cu un anumit tip de date și deci compilatorul generează cod corespunzător (trebuie să scrieți asta pentru toate tipurile).
Iată mai jos o structură mai dezvoltată pentru clasa KeyStorage, în care cheia este setată în constructor. .
template<typename T> class KeyStorage { public: KeyStorage(int k); ~KeyStorage(); T getMember(); T setMember(T element); private: T member; int key; };
Implementarea completa a ei poate fi realizată:
#include "KeyStorage.h" template<typename T> KeyStorage<T>::KeyStorage(int k) { //TODO } template<typename T> KeyStorage<T>::~KeyStorage() { } //TODO: restul metodelor. // La sfarsit, cu tipurile de date pe care le veti folosi. template class KeyStorage<int>; template class KeyStorage<long>;