A predlogo je preprosto, a zelo zmogljivo orodje v C++. Enostavna ideja je podati podatkovni tip kot parameter, tako da nam ni treba pisati iste kode za različne podatkovne tipe. Na primer, podjetje za programsko opremo bo morda moralo sortirati() za različne vrste podatkov. Namesto pisanja in vzdrževanja več kod, lahko napišemo eno sort() in posredujemo podatkovni tip kot parameter.
C++ doda dve novi ključni besedi za podporo predlogam: 'predloga' in 'typename' . Drugo ključno besedo lahko vedno zamenjate s ključno besedo 'razred' .
Kako delujejo predloge?
Predloge se razširijo v času prevajalnika. To je kot makri. Razlika je v tem, da prevajalnik preveri tip pred razširitvijo predloge. Ideja je preprosta, izvorna koda vsebuje samo funkcijo/razred, vendar lahko prevedena koda vsebuje več kopij iste funkcije/razreda.
Funkcijske predloge
Napišemo generično funkcijo, ki se lahko uporablja za različne vrste podatkov. Primeri funkcijskih predlog so sort(), max(), min(), printArray().
Če želite izvedeti več o temi, glejte Generiki v C++ .
primer:
C++ // C++ Program to demonstrate // Use of template #include using namespace std; // One function works for all data types. This would work // even for user defined types if operator '>' je preobremenjena predlogaT myMax(T x, T y) { return (x> y)? x : y; } int main() { // Pokliči myMax za int cout<< myMax (3, 7)<< endl; // call myMax for double cout << myMax(3,0, 7,0)<< endl; // call myMax for char cout << myMax('g', 'e')<< endl; return 0; }>
Izhod
7 7 g>
primer: Izvajanje Bubble Sort z uporabo predlog v C++
javascript onload skriptC++
// C++ Program to implement // Bubble sort // using template function #include using namespace std; // A template function to implement bubble sort. // We can use this for any data type that supports // comparison operator template void bubbleSort(T a[], int n) { for (int i = 0; i< n - 1; i++) for (int j = n - 1; i < j; j--) if (a[j] < a[j - 1]) swap(a[j], a[j - 1]); } // Driver Code int main() { int a[5] = { 10, 50, 30, 40, 20 }; int n = sizeof(a) / sizeof(a[0]); // calls template function bubbleSort (a, n); cout<< ' Sorted array : '; for (int i = 0; i < n; i++) cout << a[i] << ' '; cout << endl; return 0; }>
Izhod
Sorted array : 10 20 30 40 50>
Predloge razredov
Predloge razredov, kot so predloge funkcij, predloge razredov so uporabne, ko razred definira nekaj, kar je neodvisno od vrste podatkov. Lahko je uporaben za razrede, kot so LinkedList, BinaryTree, Stack, Queue, Array itd.
primer:
C++ // C++ Program to implement // template Array class #include using namespace std; template class Array { private: T* ptr; int velikost; javno: Array(T arr[], int s); void print(); }; predlogoArray::Array(T arr[], int s) { ptr = new T[s]; velikost = s; za (int i = 0; i< size; i++) ptr[i] = arr[i]; } template void Array::print() { for (int i = 0; i< size; i++) cout << ' ' << *(ptr + i); cout << endl; } int main() { int arr[5] = { 1, 2, 3, 4, 5 }; Array a(arr, 5); a.print(); vrni 0; }>
Izhod
1 2 3 4 5>
Ali lahko obstaja več kot en argument za predloge?
Da, tako kot pri običajnih parametrih lahko predlogam posredujemo več kot en tip podatkov kot argumente. Naslednji primer dokazuje isto.
primer:
C++ // C++ Program to implement // Use of template #include using namespace std; template razred A { T x; U y; public: A() { cout<< 'Constructor Called' << endl; } }; int main() { Aa; A b; vrni 0; }>
Izhod
Constructor Called Constructor Called>
Ali lahko določimo privzeto vrednost za argumente predloge?
Da, tako kot pri običajnih parametrih lahko predlogam podamo privzete argumente. Naslednji primer dokazuje isto.
primer:
C++ // C++ Program to implement // Use of template #include using namespace std; template razred A { public: T x; U y; A() { cout<< 'Constructor Called' << endl; } }; int main() { // This will call A Aa; vrni 0; }>
Izhod
Constructor Called>
Kakšna je razlika med preobremenitvijo funkcij in predlogami?
Preobremenitev funkcij in predloge so primeri značilnosti polimorfizma OOP. Preobremenitev funkcij se uporablja, ko več funkcij izvaja precej podobne (ne enake) operacije, predloge pa se uporabljajo, kadar več funkcij izvaja enake operacije.
Kaj se zgodi, ko je v razredu/funkciji predloge statični član?
Vsak primerek predloge vsebuje lastno statično spremenljivko. glej Predloge in statične spremenljivke za več podrobnosti.
Kaj je specializacija predlog?
Specializacija predloge nam omogoča, da imamo različne kode za določen tip podatkov. glej Specializacija predloge za več podrobnosti.
Ali lahko v predloge posredujemo netipske parametre?
V predloge lahko posredujemo netipske argumente. Parametri, ki niso tipi, se večinoma uporabljajo za določanje največjih ali najmanjših vrednosti ali katere koli druge konstantne vrednosti za določen primerek predloge. Pomembna stvar, ki jo morate upoštevati pri parametrih, ki niso tipa, je, da morajo biti konstantni. Prevajalnik mora poznati vrednost netipskih parametrov v času prevajanja. Ker mora prevajalnik v času prevajanja ustvariti funkcije/razrede za določeno netipsko vrednost. Če v spodnjem programu zamenjamo 10000 ali 25 s spremenljivko, dobimo napako prevajalnika.
primer:
C++ // C++ program to demonstrate // working of non-type parameters // to templates in C++ #include using namespace std; template int arrMin(T arr[], int n) { int m = max; za (int i = 0; i< n; i++) if (arr[i] < m) m = arr[i]; return m; } int main() { int arr1[] = { 10, 20, 15, 12 }; int n1 = sizeof(arr1) / sizeof(arr1[0]); char arr2[] = { 1, 2, 3 }; int n2 = sizeof(arr2) / sizeof(arr2[0]); // Second template parameter // to arrMin must be a // constant cout << arrMin (arr1, n1)<< endl; cout << arrMin(arr2, n2); vrni 0; }>
Izhod
10 1>
Tukaj je primer programa C++ za prikaz različnih tipov podatkov z uporabo konstruktorja in predloge. Izvedli bomo nekaj dejanj
- podajanje vrednosti znaka z ustvarjanjem predmeta v funkciji main().
- posredovanje celoštevilske vrednosti z ustvarjanjem predmeta v funkciji main().
- posredovanje plavajoče vrednosti z ustvarjanjem predmeta v funkciji main().
primer:
C++ // C++ program to show different data types using a // constructor and template. #include using namespace std; // defining a class template template class info { public: // konstruktor tipske predloge info(TA) { cout<< '
' << 'A = ' << A << ' size of data in bytes:' << sizeof(A); } // end of info() }; // end of class // Main Function int main() { // clrscr(); // passing character value by creating an objects infop('x'); // posredovanje celoštevilske vrednosti z ustvarjanjem informacije o objektu q(22); // posredovanje plavajoče vrednosti z ustvarjanjem informacij o objektur(2,25); vrni 0; }>
Izhod
A = x size of data in bytes:1 A = 22 size of data in bytes:4 A = 2.25 size of data in bytes:4>
Odbitek argumenta predloge
Odštevanje argumentov predloge samodejno izpelje podatkovni tip argumenta, posredovanega predlogam razreda ali funkcij. To nam omogoča, da ustvarimo primerek predloge, ne da bi izrecno navedli vrsto podatkov.
Na primer, razmislite o spodnji funkcijski predlogi za množenje dveh števil:
template t multiply (t num1,t num2) { return num1*num2; }>Na splošno, ko želimo uporabiti funkcijo multiply() za cela števila, jo moramo poklicati takole:
multiply (25, 5);>
Lahko pa ga imenujemo tudi:
multiply(23, 5);>
Ne navajamo eksplicitno vrste, tj. 1,3 so cela števila.
Enako velja za razrede predlog (samo od C++17). Recimo, da definiramo razred predloge kot:
template class student{ private: t total_marks; public: student(t x) : total_marks(x) {} };>Če želimo ustvariti primerek tega razreda, lahko uporabimo katero koli od naslednjih sintaks:
student stu1(23); or student stu2(24);>
Opomba: Pomembno je omeniti, da je odštevanje argumentov predloge za razrede na voljo samo od C++17 naprej, tako da bo, če poskušamo uporabiti odštevanje argumentov samodejne predloge za razred v prejšnji različici, prišlo do napake.
java v objekt json
Primer odbitka argumenta predloge
Spodnji primer prikazuje, kako predloga vektorskega razreda STL izpelje podatkovni tip, ne da bi bil izrecno določen.
C++ // C++ Program to illustrate template arguments deduction in // STL #include #include using namespace std; int main() { // creating a vector object without specifying // type vector v1{ 1.1, 2.0, 3.9, 4.909 }; cout << 'Elements of v1 : '; for (auto i : v1) { cout << i << ' '; } // creating a vector object without specifying type vector v2{ 1, 2, 3, 4 }; cout << endl << 'Elements of v2 : '; for (auto i : v2) { cout << i << ' '; } }>
Izhod
Elements of v1 : 1.1 2 3.9 4.909 Elements of v2 : 1 2 3 4>
Opomba: Zgornji program ne bo uspel prevesti v C++14 in nižjem prevajalniku, ker je bil v C++17 dodan odbitek argumentov predloge razreda.
Argumenti predloge funkcij Odbitek
Dedukcija argumentov predloge funkcij je del C++ od standarda C++98. Lahko preskočimo deklaracijo vrste argumentov, ki jih želimo posredovati predlogi funkcije, in prevajalnik bo samodejno izpeljal tip z uporabo argumentov, ki smo jih posredovali v klicu funkcije.
primer: V naslednjem primeru prikazujemo, kako funkcije v C++ samodejno same izpeljejo svoj tip.
C++ // C++ program to illustrate the function template argument // deduction #include using namespace std; // defining function template template t multiply(t first, t second) { return first * second; } // koda gonilnika int main() { auto result = multiply(10, 20); std::cout<< 'Multiplication OF 10 and 20: ' << result << std::endl; return 0; }>
Izhod
Multiplication OF 10 and 20: 200>
Opomba: Za predloge funkcij, ki imajo isti tip za argumente, kot je template void function(t a1, t a2){}, ne moremo posredovati argumentov različnih tipov.
Odbitek argumentov predloge razreda (C++17 naprej)
Odbitek argumentov predloge razreda je bil dodan v C++17 in je od takrat del jezika. Omogoča nam ustvarjanje primerkov predlog razredov brez eksplicitne definicije vrst, tako kot predloge funkcij.
primer: V naslednjem primeru prikazujemo, kako prevajalnik samodejno razvrsti predloge v C++.
C++ // C++ Program to implement Class Template Arguments // Deduction #include #include #include using namespace std; // Defining class template template razred študent { zasebno: niz student_name; T skupaj_ocen; public: // Parametrizirani konstruktor student(string n, T m) : student_name(n), total_marks(m) { } void getinfo() { // izpis podrobnosti študenta cout<< 'STUDENT NAME: ' << student_name << endl; cout << 'TOTAL MARKS: ' << total_marks << endl; cout << 'Type ID: ' << typeid(total_marks).name() << endl; } }; int main() { student s1('Vipul', 100); // Deduces student student s2('Yash', 98.5); // Deduces student s1.getinfo(); s2.getinfo(); return 0; }>
Izhod
STUDENT NAME: Vipul TOTAL MARKS: 100 Type ID: i STUDENT NAME: Yash TOTAL MARKS: 98.5 Type ID: d>
Tu i pomeni int, d pa dvojno.
Za metaprogramiranje predlog, r glej naslednji članek – Metaprogramiranje predloge .
Vzemi a Kviz o predlogah . Java podpira tudi te funkcije. Java to imenuje generiki .
