Pengenalan
Dalam pengaturcaraan C ++ asas, jenis data, e.g., int atau char, mesti ditunjukkan dalam deklarasi atau definisi. Nilai seperti 4 atau 22 atau -5 adalah int. Nilai seperti 'A' atau 'b' atau 'c' adalah char. Mekanisme templat membolehkan pengaturcara menggunakan jenis generik untuk sekumpulan jenis sebenar. Sebagai contoh, pengaturcara boleh memutuskan untuk menggunakan pengecam T untuk int atau char. Kemungkinan algoritma C ++ mempunyai lebih daripada satu jenis generik. Dengan, katakanlah, T untuk int atau char, U mungkin bermaksud jenis float atau pointer. Kelas, seperti string atau kelas vektor, seperti jenis data, dan objek yang disusun seperti nilai dari jenis data, yang merupakan kelas yang ditentukan. Oleh itu, mekanisme templat juga membolehkan pengaturcara menggunakan pengenal jenis generik untuk satu set kelas.
Templat C ++ membuat algoritma yang tidak bergantung pada jenis data yang digunakan. Jadi, algoritma yang sama, dengan banyak kejadian jenis yang sama, dapat menggunakan pelbagai jenis pada pelaksanaan yang berbeza. Entiti pemboleh ubah, fungsi, struktur, dan kelas boleh mempunyai templat. Artikel ini menjelaskan cara mendeklarasikan templat, cara menentukan templat, dan bagaimana menerapkannya dalam C++. Anda semestinya sudah mempunyai pengetahuan mengenai entiti yang disebutkan di atas untuk memahami topik yang dibahas dalam artikel ini.
Jenis-Jenis
Skalar
Jenis skalar adalah batal, bool, char, int, float, dan pointer.
Kelas sebagai Jenis
Kelas tertentu boleh dianggap sebagai jenis dan objeknya sebagai nilai yang mungkin.
Jenis generik mewakili sekumpulan jenis skalar. Senarai jenis skalar adalah luas. Jenis int, misalnya, mempunyai jenis lain yang berkaitan, seperti int pendek, int panjang, dll. Jenis generik juga boleh mewakili sekumpulan kelas.
Pembolehubah
Contoh pernyataan dan definisi templat adalah seperti berikut:
templatT pi = 3.14;
Sebelum meneruskan, perhatikan bahawa pernyataan seperti ini tidak dapat muncul dalam fungsi utama () atau ruang lingkup blok apa pun. Baris pertama adalah deklarasi kepala templat, dengan nama jenis generik yang dipilih oleh pengaturcara, T. Baris seterusnya adalah definisi pengecam, pi, yang merupakan jenis generik, T. Ketepatan, sama ada T adalah int atau pelampung atau jenis lain, boleh dilakukan dalam fungsi C ++ utama () (atau beberapa fungsi lain). Ketepatan sedemikian akan dilakukan dengan pemboleh ubah pi, dan bukan T.
Baris pertama adalah deklarasi kepala-templat. Deklarasi ini bermula dengan kata kunci, templat, dan kemudian kurungan sudut terbuka dan tertutup. Dalam kurungan sudut, terdapat sekurang-kurangnya satu pengecam jenis generik, seperti T, di atas. Terdapat lebih dari satu pengecam jenis generik, dengan masing-masing didahului dengan kata nama khas, nama taip. Jenis generik seperti itu dalam kedudukan disebut parameter templat.
Pernyataan berikut boleh ditulis dalam utama () atau fungsi lain:
cout << piDan fungsi akan memaparkan 3.14. Ungkapan pi
Pada pengkhususan, jenis data yang dipilih, seperti apungan, diletakkan dalam kurungan sudut selepas pemboleh ubah. Sekiranya terdapat lebih dari satu parameter templat dalam deklarasi kepala-templat, akan ada sejumlah jenis data yang sesuai dalam urutan yang sama dalam ungkapan pengkhususan.
Pada pengkhususan, jenis dikenali sebagai templat argumen. Jangan mengelirukan antara ini dan argumen fungsi untuk fungsi panggilan.
Jenis Lalai
Sekiranya tidak ada jenis yang diberikan pada pengkhususan, jenis lalai dianggap. Oleh itu, dari ungkapan berikut:
templatU pi = "cinta";
paparan dari:
cout << pi<> << '\n';
adalah "cinta" untuk penunjuk berterusan ke arang. Perhatikan dalam pengisytiharan bahawa U = const char *. Kurungan sudut akan kosong semasa pengkhususan (tidak ada jenis yang diberikan); jenis sebenarnya dianggap sebagai pointer const to char, jenis lalai. Sekiranya beberapa jenis lain diperlukan pada pengkhususan, maka nama jenis akan ditulis dalam tanda kurung sudut. Apabila jenis lalai diinginkan pada pengkhususan, mengulangi jenis dalam kurungan sudut adalah pilihan, i.e., kurungan sudut boleh dibiarkan kosong.
Catatan: jenis lalai masih boleh diubah pada pengkhususan dengan mempunyai jenis yang berbeza.
struktur
Contoh berikut menunjukkan bagaimana parameter templat dapat digunakan dengan struktur:
templatT John = 11;
T Peter = 12;
T Mary = 13;
T Kegembiraan = 14;
;
Ini adalah usia pelajar dalam kelas (kelas). Baris pertama ialah deklarasi templat. Badan dengan pendakap adalah definisi sebenar templat. Umur boleh dikeluarkan dalam fungsi utama () dengan yang berikut:
Umurcout << grade7.John << " << grade7.Mary << '\n';
Keluarannya adalah: 11 13. Pernyataan pertama di sini melakukan pengkhususan. Perhatikan bagaimana ia dibuat. Ia juga memberikan nama untuk objek struktur: grade7. Pernyataan kedua mempunyai ekspresi objek struktur biasa. Struktur seperti kelas. Di sini, Umur seperti nama kelas, sementara kelas 7 adalah objek kelas (struktur).
Sekiranya beberapa usia adalah bilangan bulat dan yang lain adalah terapung, maka struktur memerlukan dua parameter generik, seperti berikut:
templatT John = 11;
U Peter = 12.3;
T Mary = 13;
U Joy = 14.6;
;
Kod yang relevan untuk fungsi utama () adalah seperti berikut:
Umurcout << grade7.John << " << grade7.Peter << '\n';
Keluarannya adalah: 11 12.3. Pada pengkhususan, urutan jenis (argumen) mesti sesuai dengan urutan jenis generik dalam deklarasi.
Deklarasi templat dapat dipisahkan dari definisi, seperti berikut:
templatT John;
U Peter;
T Mary;
U Joy;
;
Umur
Segmen kod pertama adalah pengisytiharan templat semata-mata (tidak ada penugasan). Segmen kod kedua, yang hanya pernyataan, adalah definisi pengecam, gred7. Bahagian kiri adalah pernyataan pengecam, gred7. Bahagian kanan adalah senarai pemula, yang memberikan nilai yang sesuai kepada anggota struktur. Segmen kedua (pernyataan) boleh ditulis dalam fungsi utama (), sementara segmen pertama tetap berada di luar fungsi utama ().
Bukan Jenis
Contoh jenis bukan data termasuk int, pointer ke objek, pointer to function, dan auto type. Terdapat jenis bukan lain, yang tidak ditangani oleh artikel ini. Jenis bukan seperti jenis yang tidak lengkap, yang nilainya diberikan kemudian dan tidak dapat diubah. Sebagai parameter, ia bermula dengan jenis bukan tertentu, diikuti oleh pengecam. Nilai pengenal diberikan kemudian, pada pengkhususan, dan tidak dapat diubah lagi (seperti pemalar, yang nilainya diberikan kemudian). Program berikut menggambarkan ini:
#sertakanmenggunakan ruang nama std;
templat
T John = N;
U Peter = 12.3;
T Mary = N;
U Joy = 14.6;
;
int utama ()
Umur
cout << grade7.John << " << grade7.Joy << '\n';
pulangan 0;
Pada pengkhususan, jenis pertama, int, dalam kurungan sudut ada lebih banyak untuk formalitas, untuk memastikan bahawa bilangan dan susunan parameter sesuai dengan bilangan dan urutan jenis (argumen). Nilai N telah diberikan pada pengkhususan. Keluarannya adalah: 11 14.6.
Pengkhususan Separa
Mari kita anggap bahawa templat mempunyai empat jenis generik dan bahawa, di antara empat jenis itu, ada keperluan untuk dua jenis lalai. Ini dapat dicapai dengan menggunakan konstruk pengkhususan separa, yang tidak menggunakan operator penugasan. Jadi, konstruk pengkhususan separa memberikan nilai lalai kepada subset jenis generik. Walau bagaimanapun, dalam skema pengkhususan separa, kelas asas (struct) dan kelas pengkhususan separa (struct) diperlukan. Program berikut menggambarkan ini untuk satu jenis generik daripada dua jenis generik:
#sertakanmenggunakan ruang nama std;
// kelas templat asas
templat
Stres Berumur
;
// pengkhususan separa
templat
Stres Berumur
T1 John = 11;
terapung Peter = 12.3;
T1 Mary = 13;
kegembiraan terapung = 14.6;
;
int utama ()
Umur
cout << grade7.John << " << grade7.Joy << '\n';
pulangan 0;
Kenal pasti perisytiharan kelas asas dan definisi kelas separa. Deklarasi kepala templat kelas asas mempunyai semua parameter generik yang diperlukan. Deklarasi templat kepala kelas pengkhususan separa hanya mempunyai jenis generik. Terdapat satu set kurungan sudut tambahan yang digunakan dalam skema yang muncul tepat setelah nama kelas dalam definisi pengkhususan separa. Ini adalah apa yang sebenarnya dilakukan pengkhususan separa. Ia mempunyai jenis lalai dan jenis tidak lalai, mengikut urutan yang ditulis dalam kelas asas. Perhatikan bahawa jenis lalai masih boleh diberi jenis yang berbeza dalam fungsi utama ().
Kod yang relevan dalam fungsi () utama adalah seperti berikut:
Umurcout << grade7.John << " << grade7.Joy << '\n';
Keluarannya adalah: 11 14.6.
Pek Parameter Templat
Paket parameter adalah parameter templat yang menerima jenis generik templat sifar atau lebih untuk jenis data yang sesuai. Parameter pek parameter dimulakan dengan nama taip atau kelas yang dikhaskan. Ini diikuti oleh tiga titik, dan kemudian pengecam untuk pek. Program berikut menggambarkan bagaimana paket parameter templat dapat digunakan dengan struktur:
#sertakanmenggunakan ruang nama std;
templat
int John = 11;
terapung Peter = 12.3;
int Mary = 13;
kegembiraan terapung = 14.6;
;
int utama ()
Umur
cout << gradeB.John << " << gradeB.Mary << '\n';
Umur
cout << gradeC.Peter << " << gradeC.Joy << '\n';
Umur
cout << gradeD.John << " << gradeD.Joy << '\n';
Berumur <> gradeA; // seperti lalai
cout << gradeA.John << " << gradeA.Joy << '\n';
pulangan 0;
Keluarannya adalah:
11 1312.3 14.6
11 14.6
11 14.6
Templat Fungsi
Ciri templat yang disebutkan di atas berlaku dengan cara yang serupa untuk templat fungsi. Program berikut menunjukkan fungsi dengan dua parameter templat generik dan tiga argumen:
#sertakanmenggunakan ruang nama std;
templat
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';
int utama ()
func (12, '$', "500");
pulangan 0;
Keluarannya adalah seperti berikut:
Terdapat 12 buku bernilai $ 500 di kedai.
Pemisahan dari Prototaip
Definisi fungsi dapat dipisahkan dari prototaipnya, seperti yang ditunjukkan oleh program berikut:
#sertakanmenggunakan ruang nama std;
templat
templat
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';
int utama ()
func (12, '$', "500");
pulangan 0;
Catatan: Deklarasi templat fungsi tidak dapat muncul dalam fungsi utama () atau fungsi lain.
Beban berlebihan
Overloading fungsi yang sama boleh berlaku dengan deklarasi kepala-templat yang berbeza. Program berikut menggambarkan ini:
#sertakanmenggunakan ruang nama std;
templat
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';
templat
cout << "There are " << no << " books worth $" << str << " in the store." << '\n';
int utama ()
func (12, '$', "500");
func (12, "500");
pulangan 0;
Keluarannya adalah:
Terdapat 12 buku bernilai $ 500 di kedai.
Terdapat 12 buku bernilai $ 500 di kedai.
Templat Kelas
Ciri templat yang disebutkan di atas berlaku dengan cara yang serupa dengan templat kelas. Program berikut adalah perisytiharan, definisi, dan penggunaan kelas sederhana:
#sertakanmenggunakan ruang nama std;
kelas TheCla
awam:
int int;
char statik;
kekosongan kosong (char cha, const char * str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';
keseronokan kekosongan statik (char ch)
jika (ch == 'a')
cout << "Official static member function" << '\n';
;
int utama ()
TheCla obj;
obj.angka = 12;
obj.func ('$', "500");
pulangan 0;
Keluarannya adalah seperti berikut:
Terdapat 12 buku bernilai $ 500 di kedai.
Program berikut adalah program di atas dengan deklarasi template-head:
#sertakanmenggunakan ruang nama std;
templat
awam:
T num;
U ch statik;
void func (U cha, const char * str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';
keseronokan kekosongan statik (U ch)
jika (ch == 'a')
cout << "Official static member function" << '\n';
;
int utama ()
TheCla
obj.angka = 12;
obj.func ('$', "500");
pulangan 0;
Daripada nama kata nama dalam senarai parameter templat, kelas kata boleh digunakan. Perhatikan pengkhususan dalam pengisytiharan objek. Keluarannya masih sama:
Terdapat 12 buku bernilai $ 500 di kedai.
Pengisytiharan Berasingan
Deklarasi templat kelas dapat dipisahkan dari kod kelas, seperti berikut:
templattemplat
awam:
T num;
U ch statik;
void func (U cha, const char * str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';
keseronokan kekosongan statik (U ch)
jika (ch == 'a')
cout << "Official static member function" << '\n';
;
Berurusan dengan Ahli Statik
Program berikut menunjukkan cara mengakses anggota data statik dan fungsi anggota statik:
#sertakanmenggunakan ruang nama std;
templat
awam:
T num;
U ch statik;
void func (U cha, const char * str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';
keseronokan kekosongan statik (U cha)
jika (ch == 'a')
cout << "Official static member function" << cha << '\n';
;
templat
int utama ()
TheCla
pulangan 0;
Menetapkan nilai kepada ahli data statik adalah perisytiharan dan tidak boleh utama (). Perhatikan penggunaan dan kedudukan jenis generik dan jenis generik data dalam penyataan tugasan. Sebagai tambahan, perhatikan bahawa fungsi anggota data statik telah dipanggil di utama (), dengan jenis data templat yang sebenarnya. Keluarannya adalah seperti berikut:
Fungsi anggota statik rasmi.
Menyusun
Deklarasi (tajuk) dan definisi templat mesti ada dalam satu fail. Maksudnya, mereka mesti berada di unit terjemahan yang sama.
Kesimpulannya
Templat C ++ membuat algoritma tidak bergantung pada jenis data yang digunakan. Entiti pemboleh ubah, fungsi, struktur, dan kelas dapat memiliki templat, yang melibatkan deklarasi dan definisi. Membuat templat juga melibatkan pengkhususan, iaitu ketika jenis generik mengambil jenis sebenarnya. Deklarasi dan definisi templat mesti ada dalam satu unit terjemahan.