logo

Veidnes C++ valodā ar piemēriem

A veidne ir vienkāršs, bet ļoti spēcīgs rīks C++. Vienkārša ideja ir nodot datu tipu kā parametru, lai mums nebūtu jāraksta viens un tas pats kods dažādiem datu tipiem. Piemēram, programmatūras uzņēmumam var būt nepieciešams šķirot () dažādiem datu tipiem. Tā vietā, lai rakstītu un uzturētu vairākus kodus, mēs varam rakstīt vienu sort () un nodot datu tipu kā parametru.

C++ pievieno divus jaunus atslēgvārdus, lai atbalstītu veidnes: 'veidne' un 'tipa nosaukums' . Otro atslēgvārdu vienmēr var aizstāt ar atslēgvārdu 'klase' .



Kā darbojas veidnes?

Veidnes tiek paplašinātas kompilatora laikā. Tas ir kā makro. Atšķirība ir tāda, ka kompilators pirms veidnes paplašināšanas veic tipa pārbaudi. Ideja ir vienkārša, avota kodā ir tikai funkcija/klase, bet apkopotajā kodā var būt vairākas vienas funkcijas/klases kopijas.

veidnes-cpp

Funkciju veidnes

Mēs rakstām vispārīgu funkciju, ko var izmantot dažādiem datu tipiem. Funkciju veidņu piemēri ir sort(), max(), min(), printArray().

Lai uzzinātu vairāk par tēmu, skatiet Vispārīgi C++ .



Piemērs:

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 '>' ir pārslogota veidneT myMax(T x, T y) { return (x> y) ? x : y; } int main() { // Izsauciet myMax, lai iegūtu 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; }>

Izvade
7 7 g>

Piemērs: Īstenošana Burbuļu kārtošana izmantojot veidnes programmā C++

C++
// 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; }>

Izvade
 Sorted array : 10 20 30 40 50>

Klases veidnes

Klases veidnes, piemēram, funkciju veidnes, klašu veidnes ir noderīgas, ja klase definē kaut ko, kas nav atkarīgs no datu veida. Var būt noderīga tādām klasēm kā LinkedList, BinaryTree, Stack, Queue, Array utt.



Piemērs:

C++
// C++ Program to implement // template Array class #include  using namespace std; template class Masīvs { privāts: T* ptr;  int izmērs; public: Array(T arr[], int s);  tukša druka (); }; veidneMasīvs::Masīvs(T arr[], int s) { ptr = new T[s];  izmērs = s;  for (int i = 0; i< size; i++)  ptr[i] = arr[i]; } template tukšs masīvs::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();  atgriezties 0; }>

Izvade
 1 2 3 4 5>

Vai veidnēm var būt vairāk nekā viens arguments?

Jā, tāpat kā parastie parametri, mēs varam nodot vairāk nekā vienu datu tipu kā argumentus veidnēm. Nākamais piemērs parāda to pašu.

Piemērs:

C++
// C++ Program to implement // Use of template #include  using namespace std; template klase A { T x;  U y; publisks: A() { cout<< 'Constructor Called' << endl; } }; int main() {  Aa;  A b;  atgriezties 0; }>

Izvade
Constructor Called Constructor Called>

Vai varam norādīt noklusējuma vērtību veidnes argumentiem?

Jā, tāpat kā parastie parametri, mēs varam norādīt noklusējuma argumentus veidnēm. Nākamais piemērs parāda to pašu.

Piemērs:

C++
// C++ Program to implement // Use of template #include  using namespace std; template klase A { publisks: T x;  U y;  A() { cout<< 'Constructor Called' << endl; } }; int main() {  // This will call A  Aa;  atgriezties 0; }>

Izvade
Constructor Called>

Kāda ir atšķirība starp funkciju pārslodzi un veidnēm?

Gan funkciju pārslodze, gan veidnes ir OOP polimorfisma iezīmju piemēri. Funkciju pārslodze tiek izmantota, ja vairākas funkcijas veic diezgan līdzīgas (ne identiskas) darbības, veidnes tiek izmantotas, ja vairākas funkcijas veic identiskas darbības.

Kas notiek, ja veidņu klasē/funkcijā ir statisks dalībnieks?

Katrs veidnes gadījums satur savu statisko mainīgo. Skat Veidnes un statiskie mainīgie lai iegūtu sīkāku informāciju.

Kas ir veidņu specializācija?

Veidņu specializācija ļauj mums izmantot dažādus kodus noteiktam datu tipam. Skat Veidņu specializācija lai iegūtu sīkāku informāciju.

Vai veidnēm varam nodot parametrus, kas nav tipiski?

Veidnēm varam nodot argumentus, kas nav tipiski. Parametrus, kas nav tipi, galvenokārt izmanto, lai norādītu maksimālās vai minimālās vērtības vai jebkuru citu konstantu vērtību konkrētam veidnes gadījumam. Svarīgi, kas jāņem vērā attiecībā uz parametriem, kas nav tipa parametri, ir tas, ka tiem jābūt konst. Kompilatoram kompilēšanas laikā ir jāzina netipa parametru vērtība. Tā kā kompilatoram kompilēšanas laikā ir jāizveido funkcijas/klases noteiktai netipa vērtībai. Zemāk redzamajā programmā, ja mēs aizstājam 10000 vai 25 ar mainīgo, mēs saņemam kompilatora kļūdu.

parseint java

Piemērs:

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;  for (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);    atgriezties 0; }>

Izvade
10 1>

Šeit ir C++ programmas piemērs, lai parādītu dažādus datu tipus, izmantojot konstruktoru un veidni. Mēs veiksim dažas darbības

  • rakstzīmju vērtības nodošana, izveidojot objektu galvenajā () funkcijā.
  • vesela skaitļa vērtības nodošana, izveidojot objektu galvenajā () funkcijā.
  • peldošās vērtības nodošana, izveidojot objektu main() funkcijā.

Piemērs:

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: // konstruktors tipa veidnes info(T A) { 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');  // vesela skaitļa vērtības nodošana, izveidojot objekta informāciju q(22);  // peldošās vērtības nodošana, izveidojot objekta informācijur(2,25);  atgriezties 0; }>

Izvade
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>

Veidnes argumentu atskaitīšana

Veidnes argumentu atskaitīšana automātiski nosaka klases vai funkcijas veidnēm nodotā ​​argumenta datu tipu. Tas ļauj mums izveidot veidni, skaidri nenorādot datu veidu.

Piemēram, apsveriet tālāk norādīto funkcijas veidni, lai reizinātu divus skaitļus:

template  t multiply (t num1,t num2) { return num1*num2; }>

Parasti, ja vēlamies izmantot funkciju reizināt () veseliem skaitļiem, mums tā ir jāizsauc šādi:

multiply (25, 5);>

Bet mēs to varam saukt arī:

multiply(23, 5);>

Mēs nepārprotami nenorādam veidu, ti, 1,3 ir veseli skaitļi.

Tas pats attiecas uz veidņu klasēm (tikai kopš C++17). Pieņemsim, ka mēs definējam veidnes klasi kā:

template class student{  private:  t total_marks;  public:  student(t x) : total_marks(x) {} };>

Ja mēs vēlamies izveidot šīs klases gadījumu, mēs varam izmantot jebkuru no šīm sintakses:

student stu1(23);    or  student stu2(24);>

Piezīme: Ir svarīgi atzīmēt, ka veidnes argumentu atskaitīšana klasēm ir pieejama tikai kopš C++17, tādēļ, ja mēs mēģināsim izmantot automātisko veidnes argumentu atskaitīšanu klasei iepriekšējā versijā, tiks parādīta kļūda.

stropu arhitektūra

Veidnes argumentu atskaitīšanas piemērs

Tālāk sniegtajā piemērā ir parādīts, kā STL vektoru klases veidne izsecina datu tipu, to nenorādot tieši.

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 << ' ';  } }>


Izvade

Elements of v1 : 1.1 2 3.9 4.909  Elements of v2 : 1 2 3 4>

Piezīme: Iepriekš minētās programmas kompilācija neizdosies C++14 un zemākā kompilatorā, jo C++17 valodā tika pievienota klases veidnes argumentu atskaitīšana.

Funkciju veidnes argumenti Atskaitīšana

Funkcijas veidnes argumentu atskaitīšana ir bijusi daļa no C++ kopš standarta C++98. Mēs varam izlaist to argumentu veida deklarēšanu, kurus vēlamies nodot funkcijas veidnei, un kompilators automātiski secinās veidu, izmantojot argumentus, kurus mēs nodevām funkcijas izsaukumā.

Piemērs: Nākamajā piemērā mēs parādām, kā funkcijas programmā C++ pašas automātiski nosaka savu veidu.

C++
// C++ program to illustrate the function template argument // deduction #include  using namespace std; // defining function template template t reizināt(t pirmais, t otrais) { return first * second; } // draivera kods int main() { auto rezultāts = multiply(10, 20);  std::cout<< 'Multiplication OF 10 and 20: ' << result  << std::endl;  return 0; }>

Izvade
Multiplication OF 10 and 20: 200>

Piezīme: Funkciju veidnēm, kurām ir tāds pats tips argumentiem, piemēram, template void function(t a1, t a2){}, mēs nevaram nodot dažāda veida argumentus.

Klases veidnes argumentu atskaitīšana (no C++17 un turpmāk)

Klases veidnes argumentu atskaitīšana tika pievienota C++17 un kopš tā laika ir daļa no valodas. Tas ļauj mums izveidot klases veidnes gadījumus, nepārprotami nedefinējot tipus, tāpat kā funkciju veidnes.

Piemērs: Nākamajā piemērā mēs demonstrējam, kā kompilators automātiski klasificē veidnes C++ valodā.

C++
// C++ Program to implement Class Template Arguments // Deduction #include  #include  #include  using namespace std; // Defining class template template klases skolēns { privāts: string studenta_nosaukums;  T total_marks; publisks: // Parametrizēts konstruktors students(string n, T m) : student_name(n) , total_marks(m) { } void getinfo() { // studenta cout informācijas drukāšana<< '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; }>


Izvade

STUDENT NAME: Vipul TOTAL MARKS: 100 Type ID: i STUDENT NAME: Yash TOTAL MARKS: 98.5 Type ID: d>

Šeit i nozīmē int un d nozīmē dubultā.

Veidņu metaprogrammēšanai r skatiet šo rakstu - Veidņu metaprogrammēšana .

Paņemiet a Viktorīna par veidnēm . Java atbalsta arī šīs funkcijas. Java to sauc ģenēriskās zāles .