77 / 90

C++ Class Templates

C++ sinf shablonlari

Shablonlar C++ tilining kuchli xususiyatlari bo‘lib, umumiy dasturlarni yozish imkonini beradi. Shablonlarni amalga oshirishning ikki yo'li mavjud:

Funksiya shablonlariga o'xshab, biz turli data types bilan ishlash uchun bitta class yaratish uchun sinf shablonlaridan foydalanishimiz mumkin.

Sinf shablonlari foydali bo'ladi, chunki ular bizning kodimizni qisqartirishi va boshqarilishi mumkin.

Sinf shablon deklaratsiyasi

Sinf shabloni template kalit so‘zidan boshlanadi, undan so‘ng <> ichidagi shablon parametr(lar)idan so‘ng sinf deklaratsiyasi keladi.

example.cpp
template <class T>
class className {
  private:
    T var;
    ... .. ...
  public:
    T functionName(T arg);
    ... .. ...
};

Yuqoridagi deklaratsiyada T shablon argumenti bo'lib, foydalanilgan ma'lumotlar turi uchun to'ldiruvchi bo'lib, class esa keyword hisoblanadi.

Sinf tanasi ichida a'zo o'zgaruvchisi var va a'zo funksiyasi functionName() ikkalasi ham T turiga kiradi.

Sinf shablon obyektini yaratish

Biz sinf shablonini e'lon qilganimizdan va aniqlaganimizdan so'ng, uning objects ni boshqa sinflarda yoki functions (masalan, main() funksiyasi) quyidagi sintaksis bilan yaratishimiz mumkin:

example.cpp
className<dataType> classObject;

Masalan,

example.cpp
className<int> classObject;
className<float> classObject;
className<string> classObject;

1-misol: C++ sinfi shablonlari

example.cpp
// Sinf shablonlaridan foydalanishni ko'rsatish uchun C++ dasturi

#include <iostream>
using namespace std;

// Sinf shabloni
template <class T>
class Number {
   private:
    // T tipidagi o'zgaruvchi
    T num;

   public:
    Number(T n) : num(n) {}   // konstruktor

    T getNum() {
        return num;
    }
};

int main() {

    // 
    Number<int> numberInt(7);

    // 
    Number<double> numberDouble(7.7);

    cout << "int Number = " << numberInt.getNum() << endl;
    cout << "double Number = " << numberDouble.getNum() << endl;

    return 0;
}

Chiqish

kod
int Number = 7
double Number = 7.7

Ushbu dasturda. kod bilan Number sinf shablonini yaratdik;

example.cpp
template <class T>
class Number {
   private:
    T num;

   public:
    Number(T n) : num(n) {}
    T getNum() { return num; }
};

E'tibor bering, num o'zgaruvchisi, n konstruktor argumenti va getNum() funksiyasi T turiga yoki T qaytish turiga ega. Bu shuni anglatadiki, ular har qanday turdagi bo'lishi mumkin.

main() da biz sinf shablonini uning obyektlarini yaratish orqali amalga oshirdik;

example.cpp
Number<int> numberInt(7);
Number<double> numberDouble(7.7);

Yuqoridagi kodda Number<int> va Number<double> kodlariga e'tibor bering.

Bu int va float uchun har bir sinf ta'rifini yaratadi, keyinchalik ular mos ravishda ishlatiladi.

Sinf shablonlari ob'ektlarini e'lon qilishda turni ko'rsatish yaxshi amaliyotdir. Aks holda, ba'zi kompilyatorlar xatoga yo'l qo'yishi mumkin.

example.cpp
// Xato
Number numberInt(7);
Number numberDouble(7.7);

Sinf a'zosini sinf shablonidan tashqarida aniqlash

Faraz qilaylik, biz sinf shablonidan tashqari funksiyani aniqlashimiz kerak. Buni quyidagi kod bilan qilishimiz mumkin:

example.cpp
template <class T>
class ClassName {
    ... .. ...
    // Funksiya prototipi
    returnType functionName();
};

// Funksiya ta'rifi
template <class T>
returnType ClassName<T>::functionName() {
    // kod
}

template <class T> kodi sinfdan tashqari funksiyani belgilashda takrorlanishiga e'tibor bering. Bu zarur va sintaksisning bir qismidir.

Agar biz 1-misoldagi kodni ko'rib chiqsak, bizda Number sinf shablonida aniqlangan getNum() funksiyasi mavjud.

getNum() ni Number dan tashqari quyidagi kod bilan aniqlashimiz mumkin:

example.cpp
template <class T>
class Number {
    ... .. ...
    // Funksiya prototipi
    T getnum();
};

// Funksiya ta'rifi
template <class T>
T Number<T>::getNum() {
    return num;
}

2-misol: Sinf shablonlaridan foydalangan holda oddiy kalkulyator

Ushbu dastur ikkita variables num1 va num2 ni qo'shish, ayirish, ko'paytirish va bo'lish uchun sinf shablonidan foydalanadi.

O'zgaruvchilar har qanday turdagi bo'lishi mumkin, ammo biz ushbu misolda faqat int va float turlaridan foydalanganmiz.

example.cpp
#include <iostream>
using namespace std;

template <class T>
class Calculator {
   private:
    T num1, num2;

   public:
    Calculator(T n1, T n2) {
        num1 = n1;
        num2 = n2;
    }

    void displayResult() {
        cout << "Numbers: " << num1 << " and " << num2 << "." << endl;
        cout << num1 << " + " << num2 << " = " << add() << endl;
        cout << num1 << " - " << num2 << " = " << subtract() << endl;
        cout << num1 << " * " << num2 << " = " << multiply() << endl;
        cout << num1 << " / " << num2 << " = " << divide() << endl;
    }

    T add() { return num1 + num2; }
    T subtract() { return num1 - num2; }
    T multiply() { return num1 * num2; }
    T divide() { return num1 / num2; }
};

int main() {
    Calculator<int> intCalc(2, 1);
    Calculator<float> floatCalc(2.4, 1.2);

    cout << "Int results:" << endl;
    intCalc.displayResult();

    cout << endl
         << "Float results:" << endl;
    floatCalc.displayResult();

    return 0;
}

Chiqish

kod
Int results:
Numbers: 2 and 1.
2 + 1 = 3
2 - 1 = 1
2 * 1 = 2
2 / 1 = 2

Float results:
Numbers: 2.4 and 1.2.
2.4 + 1.2 = 3.6
2.4 - 1.2 = 1.2
2.4 * 1.2 = 2.88
2.4 / 1.2 = 2

Yuqoridagi dasturda biz Calculator sinf shablonini e'lon qildik.

Sinf T tipidagi ikkita xususiy a'zoni o'z ichiga oladi: num1 & num2 va a'zolarni ishga tushirish uchun konstruktor.

Bizda add() , subtract() , multiply() va divide() funksiyalari ham bor, ular T qaytish turiga ega. Shuningdek, bizda boshqa funksiyalar natijalarini chop etadigan void funksiyasi displayResult() mavjud.

main() da biz Calculator ning ikkita ob'ektini yaratdik: biri int ma'lumotlar turi uchun, ikkinchisi float ma'lumotlar turi uchun.

example.cpp
Calculator<int> intCalc(2, 1);
Calculator<float> floatCalc(2.4, 1.2);

Bu kompilyatorni kompilyatsiya paytida tegishli ma'lumotlar turlari uchun ikkita sinf ta'rifini yaratishni taklif qiladi.

Ko'p parametrli C++ sinfi shablonlari

C++ da biz bir nechta shablon parametrlaridan foydalanishimiz va hatto ushbu parametrlar uchun standart argumentlardan foydalanishimiz mumkin. Masalan,

example.cpp
template <class T, class U, class V = int>
class ClassName {
  private:
    T member1;
    U member2;
    V member3;
    ... .. ...
  public:
    ... .. ...
};

3-misol: Bir nechta parametrli C++ shablonlari

example.cpp
#include <iostream>
using namespace std;

// Bir nechta va standart parametrlarga ega sinf shabloni
template <class T, class U, class V = char>
class ClassTemplate {
   private:
    T var1;
    U var2;
    V var3;

   public:
    ClassTemplate(T v1, U v2, V v3) : var1(v1), var2(v2), var3(v3) {}  // konstruktor

    void printVar() {
        cout << "var1 = " << var1 << endl;
        cout << "var2 = " << var2 << endl;
        cout << "var3 = " << var3 << endl;
    }
};

int main() {
    // int, double va char turlari bilan ob'ekt yaratish
    ClassTemplate<int, double> obj1(7, 7.7, 'c');
    cout << "obj1 values: " << endl;
    obj1.printVar();

    // int, double va bool turlari bilan ob'ekt yaratish
    ClassTemplate<double, char, bool> obj2(8.8, 'a', false);
    cout << "\nobj2 values: " << endl;
    obj2.printVar();

    return 0;
}

Chiqish

kod
obj1 values: 
var1 = 7
var2 = 7.7
var3 = c

obj2 values: 
var1 = 8.8
var2 = a
var3 = 0

Ushbu dasturda biz uchta parametrli ClassTemplate nomli sinf shablonini yaratdik, ulardan biri standart parametrdir.

example.cpp
template <class T, class U, class V = char>
class ClassTemplate {
  // kod
};

class V = char kodiga e'tibor bering. Bu shuni anglatadiki, V standart turi char bo'lgan standart parametrdir.

ClassTemplate ichida biz har biri shablon parametrlaridan biriga mos keladigan var1, var2 va var3 3 ta oʻzgaruvchini eʼlon qilamiz.

example.cpp
class ClassTemplate {
   private:
    T var1;
    U var2;
    V var3;
    ... .. ...
    ... .. ...
};

main() da biz kod bilan ClassTemplate ning ikkita ob'ektini yaratamiz

example.cpp
// int, double va char turlari bilan ob'ekt yaratish
ClassTemplate<int, double> obj1(7, 7.7, 'c');

// double, char va bool turlari bilan ob'ekt yaratish
ClassTemplate<double, char, bool> obj2(8, 8.8, false);

Bu yerga,

Object T U V obj1 int double char obj2 double char bool

obj1, T = int , U = double va V = char uchun.

obj2, T = double , U = char va V = bool uchun.

Shuningdek oʻqing