Программалау оқулық Алматы, 012 Қазақстан Республикасы Білім жəне ғылым министрлігінің «Оқулық»



Pdf көрінісі
бет327/642
Дата30.03.2022
өлшемі3,66 Mb.
#29231
түріПрограмма
1   ...   323   324   325   326   327   328   329   330   ...   642
Байланысты:
pavlovskaia-jogargy-dengeili

template class List{ 

class Node{ 

public: 

Data d;

Node *next, *prev;

Node(Data dat = 0){d = dat; next = 0; prev = 0;}

};

Node *pbeg, *pend; 

public:

List(){pbeg = 0; pend = 0;} 

~List();

void add(Data d);

Node * fi nd(Data i);

Node * insert(Data key, Data d);

bool remove(Data key);

void print();

void print_back();

};

// -------------------------------

template  

   List ::~List(){ 

      if (pbeg !=0){ 

         Node *pv = pbeg; 

         while (pv){

            pv = pv->next; delete pbeg; 

            pbeg = pv;}

      }

}

// ------------------------------

template

   void List ::print(){ 

      Node *pv = pbeg; 

      cout << endl << "list: "; 

      while (pv){

         cout << pv->d << ' '; 

         pv = pv->next;} 

      cout << endl;

}

// ------------------------------

template

   void List ::print_back(){ 


235

Node *pv = pend; 

cout << endl << " list back: "; 

      while (pv){

         cout << pv->d << ' '; 

         pv = pv->prev;} 

      cout << endl;

}

// ------------------------------ 

template

   void List ::add(Data d){ 

      Node *pv = new Node(d); 

      if (pbeg == 0)pbeg = pend = pv; 

      else{

         pv->prev = pend; 

         pend->next = pv; 

         pend = pv;}

}

// ----------------------------- 

template

   Node * List ::fi nd(Data d){ 

      Node *pv = pbeg; 

      while (pv){

         if(pv->d == d)break; 

         pv = pv->next;

      }

      return pv;

}

// ------------------------------

template

   Node * List ::insert(Data key, Data d){ 

if(Node *pkey = fi nd(key)){ 

Node *pv = new Node(d); 

pv->next = pkey->next;

pv->prev = pkey; 

pkey->next = pv;

if( pkey != pend) (pv->next)->prev = pv; 

else pend = pv; 

return pv;} 

      return 0;

}

// ------------------------------

template

 

  bool List ::remove(Data key){ 

      if(Node *pkey = fi nd(key)){ 


236

   if (pkey == pbeg){

            pbeg = pbeg->next; pbeg->prev = 0;} 

         else if (pkey == pend){

            pend = pend->prev; pend->next = 0;} 

         else {

            (pkey->prev)->next = pkey->next; 

            (pkey->next)->prev = pkey->prev;}

         delete pkey; return true;} 

      return false;

}

Егер 


List

 шаблонын құрамдас типтегі емес, қолданушы анықтаған типтегі 

мəліметтерді сақтау үшін қолдану керек болса, онда осы типтің сипаттамасын-

да ағымға шығару (бұл туралы «Қолданушы анықтаған ағымдар мен типтер» 

бөлімінде, 305 б. жазылған) жəне теңдікке тексеру операцияларының асыра 

жүктелуін қосу керек, ал егер оның  өрістері үшін жадыны динамикалық бөлу 

қолданылса, онда меншіктеу операциясын да қосу керек болады.  

Шаблон синтаксисін анықтау кезінде оған типтер мен үлгілермен қоса, ай-



нымалыларды да беруге болатынын айтылған. Олар бүтін немесе тізбелік типті, 

сонымен қатар объектіге немесе функцияға нұсқауыштар немесе сілтемелер 

болуы мүмкін. Олар шаблон тұлғасының тұрақтылық өрнекті пайдалануға бо-

латын кез келген жерінде қолданылуы мүмкін. Мысал ретінде ұзындығы мен 

типі белгілі жады блогын қамтитын класс шаблонын құрайық: 

template  

   class Block{ 

      public:

Block(){p = new Type [kol];} 

~Block(){delete [] p;} 

operator Type *(); 

      protected: 

         Type * p;

};

template

   Block :: operator Type *(){

      return p;

Класс шаблондарын құру мен жөндеп түзетуден кейін  тақырыптық 

файлдарға орналастырған ыңғайлы болады.

Класс шаблондарын қолдану 

Шаблондар көмегімен нақты бір кластың нақты объектісін құру үшін (бұл 

үрдіс инстанциялау деп аталады) объектіні сипаттау кезінде шаблон атауынан 

кейін бұрыштық жақша ішінде оның аргументтері тізіліп жазылады: 




237

шаблон_атауы <аргументтер>

объект_атауы [(конструктор_параметрлері)];

Аргументтер шаблонның параметрлерімен сəйкес келуі тиіс. Шаблонның 

аргументтерімен бірге жазылған атауын кластың нақтыланған атауы ретінде 

қабылдауға болады. Объектілерді өткен бөлімде сипатталған шаблондар 

бойынша құру мысалдары:

List List_int; 

List List_double;

List List_monstr; 

Block buf; 

Block stado;

Шаблонның келісім бойынша параметрлерін қолдану кезінде аргументтер 

тізімі бос болып шығуы мүмкін, мұндайда бұрыштық жақшаларды тастап ке-

туге болмайды:



template class String;

String<>* p;

Егер шаблонның параметрі специализациясы бар шаблон болса, ол ин-

станциялау кезінде ескеріледі (шаблондардың специализациясы туралы келесі 

бөлімде жазылады):



template class A{ 

  // Бастапқы шаблон

   int x;

};

template class A {  // Шаблонның 

                                 // специализациясы 

   long х;

};

template class V> class C{

   V y; 

   V z;

};

...

C c;

Бұл мысалда 



С<А>

 ішінде 


V

  бастапқы шаблонды қолданады, сол 

себепті 

с.у.х

 

типі 



int

 болады, ал 



V

 шаблон специализациясын 

қолданады, сондықтан 

с.z.х

 типі 


long

 болады.


Бүтін типті айнымалылар болып табылатын формалды параметрлердің 

орындарында тұрақтылық өрнектер болу керек.

Шаблонның көмегімен объектілерді құрғаннан кейін олармен қарапайым 

кластардың объектілерімен бірдей жұмыс істеуге болады, мысалы:



for (int i = 1; i<10; i++) List_double.add(i * 0.08); 

List_double.print();


238

// ----------------------------------

for (int i = 1; i<10; i++) List_monstr.add(i);

List_monstr.print();

// ----------------------------------

strcpy(buf, "Өте маңызды хабарлама"); 

cout << buf << endl;

Кластардың шаблондарын қолдануды жеңілдету үшін 



typedef

 көмегімен 

типтерге қайта атау беруді жүзеге асыруға болады:

typedef List Ldbl;

Ldbl List_double;

Класс шаблондарының специализациясы 

Шаблон бойынша құрылатын кластың немесе функцияның əрбір 

нұсқасының базалық кодтары бірдей болады; тек шаблон параметрлерімен 

байланысы бар элементтер өзгереді. Мұндайда əртүрлі мəліметтер типтері 

үшін құрылатын нұсқалардың жұмыс істеу тиімділігі де əркелкі болуы мүмкін. 

Егер қандай да бір мəліметтер типі үшін бұрынғысынан тиімдірек код 

бар болса, онда бұл тип үшін жеке əдістердің арнайы жүзеге асырылуын 

қарастыруға болады немесе класс шаблонын толығымен қайта анықтау (спе-

циализациялау) керек болады. 

Əдісті специализациялау үшін оның тақырыбында нақты мəліметтер 

типін көрсету арқылы код нұсқасын анықта алу керек. Мысалы, егер 



Достарыңызбен бөлісу:
1   ...   323   324   325   326   327   328   329   330   ...   642




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет