C da umumiy turlardan foydalangan holda, shablon funksiyalar v
sinf_nomi obyekt; Sinf shabloni uchun oddiy misol. #include
using namespace std;
template
class mypair {
T a, b;
public:
mypair (T first, T second)
{a=first; b=second;}
T getmax ();
10. };
11. template 12. T mypair::getmax ()
13. {
14. T retval;
15. retval = a>b? a : b;
16. return retval;
17. }
18. int main () {
19. mypair myobject (100, 75);
20. cout << myobject.getmax();
21. return 0;
22. }
Sinf shablonida ikki xil toifadan foydalanish
#include
using namespace std;
template class myclass
{
Type1 i;
Type2 j;
public:
myclass(Type1 a, Type2 b) { i = a; j = b; }
void show() { cout << i << ' ' << j << '\n'; }
10. };
11. int main()
12. {
13. myclass ob1(10, 0.23);
14. myclass ob2('X', "Templates add power.");
15. ob1.show(); // show int, double
16. ob2.show(); // show char, char *
17. return 0;
18. }
Dastur natijasi:
10 0.23
X Templates add power.
Maxsuslashtirilgan sinf shabloni
template<> konstruktori maxsusashtirilgan sinf shabloni uchun ishlatiladi.
template class myclass {
T x;
public:
myclass(T a) {
cout << "Inside generic myclass\n";
x = a;
}
T getx() { return x; }
};
10. // int toifasi uchun maxsuslashtirilgan sinf shabloni.
11. template <> class myclass {
12. int x;
13. public:
14. myclass(int a) {
15. cout << "Inside myclass specialization\n";
16. x = a * a;
17. }
18. int getx() { return x; }
19. };
Shablonning asosiy xususiyatlari:
• reusable kod yozish imkonini beradi.
• Shablonlar yordamida framework lar yaratish mumkin
X Templates add power.
• Dastur kodi egiluvchanlik xususiyatiga ega bo'ladi.
• Turli xil tipdagi ma'lumotlar ustida ishlash uchun kod yozishda vaqtni tejash.
• C++ dagi STL lar (Standard Shablon Kutubxonalar), nomidan ko'rinib turibdiki, shablonlar yordamida yaratilgan
1. Sinf shablonlari (class template)
Sinf uchun umumiy turni aniqlash mumkin. Oldingi qismda funksiya uchun mo`ljallangan tur parametrga ega funksiya shabloni aniqlandi. Biz sinf uchun mo`ljallangan tur parametrga ega sinfni ham aniqlashimiz mumkin. Tur parametrlar sinfning tur shakllantiriladigan ixtiyoriy qismida foydalanilishi mumkin.
int qiymatlar uchun stek hosil qilish mumkin. Quyida, 1.1a-rasmdagi kabi, o`sha sinf nusxasi va uning UML sinf diagrammasi berilgan.
StackOfIntegers
-elements[100]: int
-size: int
+StackOfIntegers()
+empty(): bool const
+peek(): int const
+push(value: int): void
+pop(): int
+getSize(): int const
(a)
StackOfIntegers
-elements[100]: T
-size: int
+Stack()
+empty(): bool const
+peek(): T const
+push(value: T): void
+pop(): T
+getSize(): int const
(b)
1.1-rasm. Stack – Stack sinfining umumiy versiyasi #ifndef STACK_H
#define STACK_H
class StackOfIntegers
{
public:
StackOfIntegers();
bool empty() const;
int peek() const;
void push(int value);
10. int pop();
11. int getSize() const;
12. private: 13. int elements[100];
14. int size;
15. };
16. StackOfIntegers::StackOfIntegers()
17. {
18. size = 0;
19. }
20. bool StackOfIntegers::empty() const 21. {
22. return size == 0;
23. }
24. int StackOfIntegers::peek() const 25. {
26. return elements[size - 1];
27. }
28. void StackOfIntegers::push(int value)
29. {
30. elements[size++] = value;
31. }
32. int StackOfIntegers::pop()
33. {
34. return elements[--size];
35. }
36. int StackOfIntegers::getSize() const 37. {
38. return size;
39. }
40. #endif Boyalgan int kalit so`zlarini double, char, yoki string bilan almashtirib, double, char va string qiymatlar uchun StackOfDouble, StackOfChar va StackOfString kabi sinflarni aniqlash uchun ushbu sinfni osongina o`zgartirishlar kiritishimiz mumkin. Lekin, deyarli bir xil bo`lgan bir nechta sinflarni aniqlamasdan, shunchaki ixtiyoriy turdagi elemen uchun ishlaydigan bitta shablon sinfni aniqlashimiz mumkin. Yangi umumiy Stack sinfi uchun UML diagramma 1.1b-rasmda berilgan. 1.4-kodli ro`yxatda umumiy tur elementlarini saqlashga mo`ljallangan umumiy stek sinfi aniqlangan.
1.4-kodli ro`yxat. GenericStack.h #ifndef STACK_H
#define STACK_H
template <typename T>
class Stack
{
public:
Stack();
bool empty() const;
T peek() const;
10. void push(T value);
11. T pop();
12. int getSize() const;
13. private: 14. T elements[100];
15. int size;
16. };
17. template <typename T>
18. Stack::Stack()
19. {
20. size = 0;
21. }
22. template <typename T>
23. bool Stack::empty() const 24. {
25. return size == 0;
26. }
27. template <typename T>
28. T Stack::peek() const
29. {
30. return elements[size - 1];
31. }
32. template <typename T>
33. void Stack::push(T value)
34. {
35. elements[size++] = value;
36. }
37. template <typename T>
38. T Stack::pop()
39. {
40. return elements[--size];
41. }
42. template <typename T>
43. int Stack::getSize() const 44. {
45. return size;
46. }
47. #endif Sinf shablonlari sintaksisi asosan funksiya shablonlari bilan bir xil. Xuddi funksiya shablonidagi kabi sinf aniqlanishidan oldin template qo`shimchasi yozilishi kerak (47-qator).
template T> Xuddi oddiy ma’lumot turiga o`xshab, sinfda tur parametri qo`llanilishi mumkin. Bu yerda T tur peek()(10-qator), push(T value) (11-qator), va pop() (12-qator) funksiyani aniqlash uchun ishlatilgan. Shuningdek, T tur 16-qatorda, massiv elementlarini e’lon qilishda ham qo`llanilgan.
Konstruktorlar va funksiyalar ularning o`zlari shablonlar ekanliklari inobatga olinmaganda, oddiy sinflardagi kabi, bir xil yo`l bilan aniqlanadi. Buni amalga oshirish uchun, template qo`shimchasini konstruktor yoki funksiyaning bosh qismidan avval joylashtirish kerak bo`ladi. Masalan:
template <typename T>
Stack::Stack()
{
size = 0;
}
template <typename T>
bool Stack::empty()
{
return size == 0;
}
template <typename T>
T Stack::peek()
{
return elements[size - 1];
}
Shu o`rinda e’tibor qaratishimiz lozimki, :: qarashlilik operatoridan oldin keladigan sinf nomi Stack, Stack emas.
Maslahat. GenericStack.h sinf aniqlanishini va tadbiqini bitta faylga o`tkazadi. Sinf aniqlanishini va tadbiqini ikkita turli fayllarga joylashtirish yaxshi ish albatta. Biroq, shunday bo`lsa ham, sinf shablonlari uchun ularni birlashtirish bir muncha xavfsizroq, chunki, ba’zi kompilyatorlar ularni tarqoq holda kompilyatsiya qilmaydi.
1.5-kodli ro`yxatda, uning qatorida int qiymatlar uchun va 18-qatorda satrlar uchun stek hosil qiluvchi sinovchi dastur berilgan.
1.5-kodli ro`yxat. TestGenericStack.cpp #include
Shablon sinfda ob’yekt yaratishda T - tur parametri uchun aniq bir turni belgilab olishimiz zarur. Masalan:
Stack intStack;
Bu e’lon qilinish T - tur parametrini int bilan almashtiradi. Shu sababli ham intStack steki int qiymatlar steki hisoblanadi. intStack ob’yekti ham xuddi ixtiyoriy boshqa ob’yektlarga o`xshaydi. Dastur intStack stekka int qiymatlarni qo`shish uchun push funksiyasini chaqiradi (11-qator) va stekdan elementlarni chop etadi (13-14-qatorlar).
Dastur 18-qatorda satrlarni yozish uchun stek ob’yektni e’lon qiladi, stekda uchta satrni yozadi (19-21-qatorlar) va stekdagi satrlarni chop etadi (24-qator).
Quyidagi kodli qismlarga e’tibor beraylik:
9-11-qatorlar. while (!intStack.empty())
cout << intStack.pop() << " ";
cout << endl;
23-25-qatorlar while (!stringStack.empty())
cout << stringStack.pop() << " ";
cout << endl;
Bu kodli qismlar deyarli bir xil. Ular o`rtasidagi farq intStack va stringStack yozuvlaridagi shakllantirish operatsiyalarida. Stekdagi elementlarni chop etish uchun stek parametrli funksiya aniqlashimiz mumkin. Yangi dastur 1.6-kodli ro`yxatda keltirilgan.
1.6-kodli ro`yxat. TestGenericStackWithTemplateFunction.cpp #include
14. int main()
15. {
16. // int qiymatlar uchun yangi stek yaratish 17. Stack<int> intStack;
18. for (int i = 0; i < 10; i++)
19. intStack.push(i);
20. printStack(intStack);
21.
22. // Satrlar uchun yangi stek yaratish 23. Stack<string> stringStack;
24. stringStack.push("Chicago");
25. stringStack.push("Denver");
26. stringStack.push("London");
27. printStack(stringStack);
28.
29. return 0;
30. }
Shablon funksiyada umumiy sinf nomi Stack tur parametr sifatida qo`llanilgan (7-qator).
Eslatma. C++ sinf shablonida tur parametr uchun jimlik qoidasiga ko`ra tur ni ta’minlashga ruxsat beradi. Masalan, jimlik qoidasiga ko`ra tur sifatida, umumiy Stack sinfida quyidagicha ta’minlash mumkin:
template<typename T = int>
class Stack
{
...
};
Endi sinf shablonida jimlik qoidasi turidan foydalanishimiz mumkin, lekin funksiya shablonida emas.
Eslatma.Biz shuningdek, template qo`shimchasi tarkibida tur parametri bilan tursiz parametr ni ham qo`llashimiz mumkin. Masalan, Stack sinfda parametr sifatida, massiv o`lchamini quyidagicha e’lon qilish mumkin:
template<typename T, int capacity>
class Stack
{
...
private: T elements[capacity];
int size;
};
Shunday qilib, biz stek hosil qilganimizda, massiv o`lchamini belgilashimiz mumkin. Masalan,
Stack500> stack;
500 tagacha satrlarni saqlay oluvchi stekni e’lon qiladi.
Eslatma. Sinf shablonida statik a’zolarni aniqlash mumkin. Har bir shablon belgilanishi o`zining statik ma’lumotlar maydonidagi nusxasiga ega.
kalit