ფუნქციის შაბლონის განსაზღვრა. ფუნქციის შაბლონის პროტოტიპი. მარტივი ფუნქციის შაბლონის შექმნა

ჩვენ უკვე განვიხილეთ ისეთი ინსტრუმენტი, როგორიცაა შაბლონები C++-ში, როდესაც შევქმენით. რატომ უნდა გამოიყენოთ შაბლონები, დაიწერა სტატიაში ფუნქციის შაბლონებით. იქ ჩვენ გადავხედეთ შაბლონების ძირითად დებულებებს C++-ში. გავიხსენოთ ისინი.

ნებისმიერი შაბლონი იწყება სიტყვა შაბლონით, იქნება ეს ფუნქციის შაბლონი თუ კლასის შაბლონი. შაბლონის საკვანძო სიტყვას მოსდევს კუთხის ფრჩხილები −< >, რომელშიც ჩამოთვლილია შაბლონის პარამეტრების სია. თითოეულ პარამეტრს წინ უნდა უძღოდეს რეზერვირებული სიტყვის კლასი ან ტიპის სახელი. ამ საკვანძო სიტყვების არარსებობა შემდგენელის მიერ ინტერპრეტირებული იქნება როგორც . შაბლონის დეკლარაციების რამდენიმე მაგალითი:

შაბლონი

შაბლონი

შაბლონი

typename საკვანძო სიტყვა ეუბნება შემდგენელს, რომ შაბლონი გამოიყენებს ჩაშენებულ მონაცემთა ტიპს, როგორიცაა: int, double, float, char და ა.შ. და კლასის საკვანძო სიტყვა ეუბნება შემდგენელს, რომ ფუნქციის შაბლონი გამოიყენებს მონაცემთა მორგებულ ტიპებს პარამეტრად. ანუ კლასები. მაგრამ არავითარ შემთხვევაში არ აურიოთ შაბლონის პარამეტრი კლასის შაბლონთან. თუ ჩვენ გვჭირდება კლასის შაბლონის შექმნა int და char ტიპის ერთი პარამეტრით, კლასის შაბლონი ასე გამოიყურება:

შაბლონი

სადაც T არის კლასის შაბლონის პარამეტრი, რომელსაც შეუძლია მიიღოს ნებისმიერი ჩაშენებული მონაცემთა ტიპი, რაც ჩვენ გვჭირდება.

და თუ კლასის შაბლონის პარამეტრი უნდა იყოს მორგებული ტიპის, როგორიცაა Array, სადაც Array არის კლასი, რომელიც აღწერს მასივს, კლასის შაბლონი ასე გამოიყურება:

შაბლონი კლასის სახელი (//კლასის შაბლონის სხეული);

ჯობია თავიდანვე გაარკვიოთ ეს, რათა მოგვიანებით შეცდომა არ წარმოიშვას, თუნდაც კლასის შაბლონი სწორად იყოს დაწერილი.

მოდით შევქმნათ Stack კლასის შაბლონი, სადაც , რომელიც ინახავს მონაცემთა მსგავს ელემენტებს. თქვენ შეგიძლიათ დააჭიროთ და გადაიტანოთ მონაცემები დასტაზე. დასტაზე დამატებული ელემენტი მოთავსებულია სტეკის ზედა ნაწილში. დასტის ელემენტები ამოღებულია ზემოდან დაწყებული. Stack კლასის შაბლონში თქვენ უნდა შექმნათ ძირითადი მეთოდები:

  • ბიძგი- დაამატეთ ელემენტი სტეკში;
  • პოპ- ამოიღეთ ელემენტი დასტიდან
  • printStack— დასტის ჩვენება ეკრანზე;

მოდით განვახორციელოთ ეს სამი მეთოდი და ბოლოს მივიღებთ უმარტივეს კლასს, რომელიც ახორციელებს სტეკის სტრუქტურის მოქმედებას. არ დაივიწყოთ კონსტრუქტორები და დესტრუქტორები. იხილეთ კოდი ქვემოთ.

#include "stdafx.h" #include შაბლონი << "Заталкиваем элементы в стек: "; int ct = 0; while (ct++ != 5) { int temp; cin >> << "\nУдаляем два элемента из стека:\n"; myStack.pop(); // удаляем элемент из стека myStack.pop(); // удаляем элемент из стека myStack.printStack(); // вывод стека на экран return 0; } // конструктор template დასტის :: Stack(int s) ( ზომა = s > დასტის bool Stack bool Stack void Stack ::printStack() ( (int ix = ზომა -1; ix >= 0; ix--) cout<< "|" << setw(4) << stackPtr << endl; }

// კოდი Code::Blocks

// Dev-C++ კოდი

#შეიცავს სახელთა სივრცის გამოყენებით std; #შეიცავს შაბლონი კლასი Stack ( კერძო: T *stackPtr; // ინდიკატორი სტეკის int ზომაზე; // სტეკის ზომა T ზედა; // დასტის ზედა საჯარო: Stack(int = 10); // ნაგულისხმევად დატის ზომა არის 10 ელემენტი ~Stack() ; int main() ( Stack myStack (5); // შეავსეთ სტეკის კოუტ<< "Заталкиваем элементы в стек: "; int ct = 0; while (ct++ != 5) { int temp; cin >> ტემპერატურა; myStack.push(temp); ) myStack.printStack(); // დასტა ამობეჭდეთ ეკრანზე<< "\nУдаляем два элемента из стека:\n"; myStack.pop(); // удаляем элемент из стека myStack.pop(); // удаляем элемент из стека myStack.printStack(); // вывод стека на экран return 0; } // конструктор template დასტის :: Stack(int s) ( size = s > 0 ? s: 10; // stack size stackPtr = new T; // მეხსიერების გამოყოფა სტეკის ზედა = -1; // მნიშვნელობა -1 მიუთითებს, რომ დასტა ცარიელი ) // შაბლონის დამღუპველი დასტის ::~Stack() ( delete stackPtr; // delete stack ) // ელემენტი არის Stack კლასის ფუნქცია დასტაზე ელემენტის განთავსებისთვის // დაბრუნების მნიშვნელობა არის true, ოპერაცია წარმატებით დასრულდა // false, ელემენტი არ დაემატა სტეკის შაბლონს bool Stack :: push (const T მნიშვნელობა) (თუ (ზედა == ზომა - 1) დააბრუნებს false; // დასტა სავსეა ზედა ++; stackPtr = მნიშვნელობა; // დააწექი ელემენტს დასტაზე return true; // წარმატებით დასრულება ოპერაციიდან ) // ელემენტის ფუნქცია დაწყობის კლასი ელემენტის დასტადან ამოსაღებად // დაბრუნების მნიშვნელობა არის true, ოპერაცია წარმატებით დასრულდა // false, დასტა ცარიელია შაბლონი bool Stack ::pop() (თუ (top == - 1) დაბრუნდება false; // დასტა ცარიელია stackPtr = 0; // ამოიღეთ ელემენტი სტეკის ზემოდან--; დააბრუნეთ true; // ოპერაციის წარმატებით დასრულება) // დატის ჩვენება ეკრანის შაბლონზე void Stack ::printStack() ( (int ix = ზომა -1; ix >= 0; ix--) cout<< "|" << setw(4) << stackPtr << endl; }

როგორც ხედავთ, Stack კლასის შაბლონი დეკლარირებული და განსაზღვრულია ფაილში ძირითადი ფუნქციით. რა თქმა უნდა, შაბლონების გადამუშავების ეს მეთოდი არ არის კარგი, მაგრამ ეს გამოდგება მაგალითად. 7-20 სტრიქონები აცხადებს კლასის შაბლონის ინტერფეისს. კლასის დეკლარაცია ხდება ჩვეული წესით, ხოლო კლასამდე არის შაბლონის დეკლარაცია, მე-7 სტრიქონზე. კლასის შაბლონის გამოცხადებისას ყოველთვის გამოიყენეთ ეს სინტაქსი.

47 - 100 სტრიქონები შეიცავს Stack კლასის შაბლონის ფუნქციის ელემენტს და ყოველი ფუნქციის წინ აუცილებელია შაბლონის გამოცხადება, ზუსტად იგივე, რაც კლასის - შაბლონის წინ. . ანუ გამოდის, რომ კლასის შაბლონის ფუნქციის ელემენტი დეკლარირებულია ზუსტად ისე, როგორც ჩვეულებრივი ფუნქციის შაბლონები. თუ ჩვენ აღვწერდით მეთოდების განხორციელებას კლასის შიგნით, მაშინ შაბლონის სათაური იქნებოდა შაბლონი არ არის საჭირო თითოეული ფუნქციისთვის რეგისტრაცია.

თითოეული ფუნქციის ელემენტის კლასის შაბლონთან დასაკავშირებლად, ჩვეულებისამებრ, ვიყენებთ ორობითი მასშტაბის გარჩევადობის ოპერაციას - :: კლასის შაბლონის სახელით - Stack. . რაც გავაკეთეთ 49, 58, 68, 83, 96 სტრიქონებში.

გაითვალისწინეთ Stack კლასის თარგის myStack ობიექტის დეკლარაცია მთავარ ფუნქციაში, სტრიქონში 24. კუთხის ფრჩხილებში ცალსახად უნდა იყოს მითითებული გამოყენებული მონაცემთა ტიპი, ეს არ იყო საჭირო ფუნქციის შაბლონებში. შემდეგი, main აწარმოებს რამდენიმე ფუნქციას, რომელიც აჩვენებს, თუ როგორ მუშაობს Stack კლასის შაბლონი. პროგრამის შედეგი ნაჩვენებია ქვემოთ.

ჩვენ ვაყენებთ ელემენტებს დასტაზე: 12 3456 768 5 4564 |4564 | 5 | 768 |3456 | 12 ამოიღეთ ორი ელემენტი დასტადან: | 0 | 0 | 768 |3456 | 12

მე ვაპირებდი ტექსტის დაწერას ყველა სახის მაგარი მონაცემთა სტრუქტურის შესახებ, შემდეგ კი აღმოჩნდა, რომ ჯერ კიდევ არ გვქონდა შესწავლილი C++-ის რამდენიმე ძალიან მნიშვნელოვანი მახასიათებელი. შაბლონები ერთ-ერთი მათგანია.

შაბლონები ძალიან ძლიერი ინსტრუმენტია. შაბლონის ფუნქციებსა და კლასებს შეუძლიათ მნიშვნელოვნად გაამარტივონ პროგრამისტის ცხოვრება და დაზოგონ დიდი დრო, ძალისხმევა და ნერვები. თუ ფიქრობთ, რომ შაბლონები არ არის ძალიან მნიშვნელოვანი თემა შესასწავლად, იცოდეთ, რომ ცდებით.

შაბლონის ფუნქციები

შაბლონის ფუნქციის მარტივი მაგალითი:

კოდი c++ ენაზეაკრიფეთ კვადრატი (ტიპი a) ( ტიპი b; b = a*a; დაბრუნება b; ) int x = 5; int i; i = კვადრატი (5); float y = 0,5; float f; f = კვადრატი (y);

თუ ჩვენ შევქმნით ფუნქციებს ძველებურად, მაშინ მოგვიწევდა ორი განსხვავებული ფუნქციის დაწერა: int ტიპისთვის და float ტიპისთვის. და თუ დაგჭირდათ იგივე ფუნქცია სხვა ტიპების გამოყენებით, მოგიწევთ ხელახლა დაწერა. შაბლონების გამოყენებით შეგიძლიათ შემოიფარგლოთ ფუნქციის მხოლოდ ერთი ეგზემპლარით და მთელი ბინძური სამუშაო კომპილატორს დაუტოვოთ.

კონკრეტული ტიპის გამოყენების ნაცვლად, ფუნქცია იყენებს პარამეტრულ ტიპს (ან, სხვა სიტყვებით რომ ვთქვათ, შაბლონის არგუმენტს). აქ პარამეტრულ ტიპს დავარქვი იდენტიფიკატორი ტიპი. ეს იდენტიფიკატორი ჩნდება სამჯერ ფუნქციაში: დაბრუნების მნიშვნელობა, ფუნქციის არგუმენტი და ცვლადის განმარტება s. ანუ ტიპი გამოიყენება როგორც ნებისმიერი ჩვეულებრივი ტიპი.

მაგრამ იმისათვის, რომ კოდი იმუშაოს, თქვენ უნდა დაამატოთ შემდეგი ხაზი ფუნქციის წინ (მე ვაჩვენე რამდენიმე სინტაქსის ვარიანტი, ისინი ყველა მუშაობს):

კოდი c++ ენაზეშაბლონი აკრიფეთ კვადრატული (ტიპი a) შაბლონი < class Type >აკრიფეთ კვადრატული (ტიპი a) შაბლონი< class Type >აკრიფეთ კვადრატი (ტიპი a)

ამრიგად, ფუნქციას წინ უნდა უძღოდეს საკვანძო სიტყვის შაბლონი, ხოლო კუთხის ფრჩხილებში უნდა მიუთითოთ პარამეტრული ტიპის სახელი საკვანძო სიტყვის კლასით. კლასის საკვანძო სიტყვის ნაცვლად, შეგიძლიათ გამოიყენოთ ტიპი - ზოგადად, განსხვავება არ არის.

პარამეტრული ტიპის იდენტიფიკატორი ასევე შეიძლება იყოს ნებისმიერი. ჩვენ ხშირად გამოვიყენებთ მათ: TypeA, TypeB, Datatype, T.

Მნიშვნელოვანი ჩანაწერი: შაბლონის ფუნქციებს უნდა ჰქონდეს არგუმენტი, რათა შემდგენელმა განსაზღვროს რომელი ტიპის გამოყენება.

შაბლონებში შეგიძლიათ გამოიყენოთ რამდენიმე პარამეტრული ტიპი და, რა თქმა უნდა, შეგიძლიათ პარამეტრული ტიპები შეურიოთ სტანდარტულს (უბრალოდ უნდა იზრუნოთ სწორი ტიპის ჩამოსხმაზე). მე მივცემ მაგალითს, რომელიც იყენებს ორ პარამეტრულ ტიპს TypeA, TypeB და საბაზისო ტიპს int:

კოდი c++ ენაზეშაბლონი TypeB მაგალითი_ფუნქცია (TypeA a, TypeB b) (int x = 5; b = a + x; დაბრუნება b;)

მაგრამ შაბლონის ფუნქციები არ არის ყველაზე საინტერესო რამ, რასაც დღეს განვიხილავთ.

შაბლონური კლასები

ზოგადად, შაბლონის კლასები იქმნება ისევე, როგორც შაბლონის ფუნქციები - საკვანძო სიტყვის შაბლონი იწერება კლასის სახელის წინ. მოდით შევხედოთ შაბლონის კლასებს სტეკის მაგალითის გამოყენებით:

კოდი c++ ენაზეშაბლონი class stack ( private: int top; Type s; public: stack (): top(0) () void push (Type var) ( top++; s = var; ) Type pop(); ); შაბლონი ჩაწერეთ stack::pop() ( Type var = s; top--; return var; ) აქ განვსაზღვრავთ

გააზიარა ათი ელემენტისგან შემდგარი დასტა. ეს ელემენტები შეიძლება იყოს ნებისმიერი ტიპის, უფრო დეტალურად ქვემოთ.

ერთადერთი, რაზეც მინდა თქვენი ყურადღება გავამახვილო, არის პუშის და პოპ ფუნქციების განსაზღვრა. Push ფუნქცია განისაზღვრება კლასის შიგნით, ხოლო pop ფუნქცია განისაზღვრება გარეთ. კლასის გარეთ გამოცხადებული ყველა ფუნქციისთვის უნდა იყოს მითითებული შაბლონის საკვანძო სიტყვა. ფუნქციის სახელის წინ გამოთქმა იგივეა, რაც კლასის სახელის წინ.

ახლა ვნახოთ, როგორ ვიმუშაოთ შაბლონის კლასებთან:

კოდი c++ ენაზედასტის s1; დასტის s2; s1.push(3); s1.ბიძგი(2); s1.pop(); s2.push(0.5);

ობიექტის შექმნისას, კლასის სახელის შემდეგ თქვენ უნდა დააყენოთ კუთხის ფრჩხილები, რომლებშიც მიუთითოთ სასურველი ტიპი. ამის შემდეგ, ობიექტები გამოიყენება ისე, როგორც ჩვენ შეჩვეული ვართ.

შაბლონის კლასებს აქვთ ერთი საოცარი თვისება - სტანდარტული ტიპების გარდა, მათ შეუძლიათ მუშაობა მორგებულებთანაც. მოდით შევხედოთ პატარა მაგალითს. ამისათვის მოდით განვსაზღვროთ მარტივი მეომრის კლასი:

კოდი c++ ენაზეკლასის მეომარი ( public: int health; warrior () : health(0) () ); დასტის ს; მეომარი w1; მეომარი w2; მეომარი w3; s.push(w1); s.push(w3); s.pop(); s.push(w2);

შეხედე, ახლა შეგიძლია დააყენო მეომარი ტიპის ცვლადები სტეკებზე!!! შეიძლება არ დამიჯეროთ, მაგრამ ეს ძალიან მაგარია! თქვენ ხედავთ, რა მაგარია ეს, როდესაც ჩვენ ვქმნით გრაფიკებს და ხეებს სიების საფუძველზე.

ეს ყველაფერი ახლა შაბლონების მიხედვით. მოგვიანებით განვიხილავთ შაბლონური კლასების გამოყენების უფრო რთულ შემთხვევებს.

შაბლონის ფუნქცია განსაზღვრავს ოპერაციების ზოგად კომპლექტს, რომელიც გამოყენებული იქნება სხვადასხვა ტიპის მონაცემებზე. ამ მექანიზმის გამოყენებით შესაძლებელია ზოგიერთი ზოგადი ალგორითმის გამოყენება მონაცემთა ფართო დიაპაზონზე. მოგეხსენებათ, ბევრი ალგორითმი ლოგიკურად ერთნაირია, მიუხედავად მონაცემთა ტიპისა, რომლითაც ისინი მუშაობენ. მაგალითად, Quicksort ალგორითმი ერთნაირია როგორც მთელი რიცხვების, ასევე მცურავი პუნქტიანი რიცხვების მასივისთვის. განსხვავდება მხოლოდ დასახარისხებელი მონაცემების ტიპი. ზოგადი ფუნქციის შექმნით, თქვენ შეგიძლიათ განსაზღვროთ ალგორითმის არსი, მიუხედავად მონაცემთა ტიპისა. ამის შემდეგ, შემდგენელი ავტომატურად აგენერირებს სწორ კოდს მონაცემთა ტიპისთვის, რომლისთვისაც ფუნქციის ეს კონკრეტული განხორციელება შეიქმნა კომპილაციის ეტაპზე. არსებითად, როდესაც შაბლონის ფუნქცია იქმნება, ის ქმნის ფუნქციას, რომელსაც შეუძლია ავტომატურად გადატვირთოს საკუთარი თავი.

შაბლონის ფუნქციები იქმნება შაბლონის საკვანძო სიტყვის გამოყენებით. სიტყვა "ნიმუშის" ჩვეულებრივი მნიშვნელობა საკმაოდ სრულად ასახავს მის გამოყენებას C++-ში. შაბლონი გამოიყენება ფუნქციის ჩონჩხის შესაქმნელად, განხორციელების დეტალები კომპილერს უტოვებს. შაბლონის ფუნქციის ზოგადი ფორმა ასეთია:

შაბლონი დაბრუნების_ტიპის ფუნქცია_სახელი (პარამეტრების სია)
{
// ფუნქციის სხეული
}

აქ ptype არის ტიპის პარამეტრი, "placeholder" მონაცემთა ტიპის სახელისთვის, რომელსაც იყენებს ფუნქცია. ამ ტიპის პარამეტრი შეიძლება გამოყენებულ იქნას ფუნქციის განსაზღვრაში. თუმცა, ეს არის მხოლოდ "placeholder", რომელიც ავტომატურად შეიცვლება შემდგენელის მიერ ფაქტობრივი მონაცემების ტიპით, როდესაც შეიქმნება ფუნქციის კონკრეტული ვერსია.

ქვემოთ მოცემულია მოკლე მაგალითი, რომელიც ქმნის შაბლონის ფუნქციას, რომელსაც აქვს ორი პარამეტრი. ეს ფუნქცია ცვლის ამ პარამეტრების მნიშვნელობებს ერთმანეთთან. ვინაიდან ორ ცვლადს შორის მნიშვნელობების გაცვლის ზოგადი პროცესი არ არის დამოკიდებული მათ ტიპზე, ის ბუნებრივად შეიძლება განხორციელდეს შაბლონის ფუნქციის გამოყენებით.

// ფუნქციის შაბლონის მაგალითი
#შეიცავს
// ფუნქციის შაბლონი
შაბლონი ბათილად გაცვლა (X &a, X &b)
{
X ტემპერატურა;
ტემპერატურა = a;
a = b;
b = ტემპერატურა;
}
int main()
{
int i=10, j = 20;
float x=10.1, y= 23.3;
char a="x", b="z";
კოუტ<< "Original i, j: " << i << " " << j << endl;
კოუტ<< "Original x, y: " << x << " " << у << endl;
კოუტ<< "Original a, b: " << a << " " << b << endl;
swap(i, j); // მთელი რიცხვების გაცვლა
swap (x, y); // რეალური ღირებულებების გაცვლა
swap(a, b); // პერსონაჟების გაცვლა
კოუტ<< "Swapped i, j: " << i << " " << j << endl;
კოუტ<< "Swapped x, y: " << x << " " << у << endl;
კოუტ<< "Swapped a, b: " << a << " " << b << endl;
დაბრუნება 0;
}

მოდით უფრო ახლოს მივხედოთ ამ პროგრამას. ხაზი

შაბლონი ბათილად გაცვლა (X &a, X &b)

მიუთითებს შემდგენელზე, რომ შაბლონი გენერირებულია. აქ X არის ტიპის შაბლონი, რომელიც გამოიყენება როგორც ტიპის პარამეტრი. შემდეგ მოდის swap() ფუნქციის დეკლარაცია, მონაცემთა ტიპის X გამოყენებით იმ პარამეტრებისთვის, რომლებიც გაცვლიან მნიშვნელობებს. main() ფუნქციაში swap() ფუნქცია გამოიძახება მასზე გადაცემული სამი სხვადასხვა ტიპის მონაცემით: მთელი რიცხვები, მცურავი პუნქტიანი რიცხვები და სიმბოლოები. იმის გამო, რომ swap() ფუნქცია არის შაბლონის ფუნქცია, შემდგენელი ავტომატურად შექმნის swap() ფუნქციის სამ განსხვავებულ ვერსიას - ერთი მთელ რიცხვებთან მუშაობისთვის, მეორე მცურავი წერტილის რიცხვებთან მუშაობისთვის და ბოლოს მესამეს სიმბოლოების ცვლადებთან მუშაობისთვის.

ფუნქციის შაბლონის პროტოტიპი შეგიძლიათ წინასწარ გამოაცხადოთ. ეს დეკლარაცია აცნობებს შემდგენელს შაბლონის არსებობის შესახებ და ასევე აცნობებს შემდგენელს მოსალოდნელ პარამეტრებს. მაგალითად, სორტირების ფუნქციის შაბლონის პროტოტიპი ასე გამოიყურება:

შაბლონი void Sort (T მასივი, Tsize ზომა);

შაბლონის ფორმალური პარამეტრების სახელები შეიძლება არ იყოს იგივე შაბლონის წინასწარ დეკლარაციასა და განმარტებაში. ასე რომ, მაგალითად, შემდეგ ფრაგმენტში შაბლონის პროტოტიპიც და შაბლონის განმარტებაც ერთსა და იმავე ფუნქციას ეხება:

შაბლონი T max(T, T);

შაბლონი

ტიპი max (ტიპი a, ტიპი b)

თუ (a > b) დააბრუნეთ a; სხვა დაბრუნება ბ;

ფუნქციის შაბლონის გამოყენება

ფუნქციის შაბლონი აღწერს, თუ როგორ შეიძლება კონკრეტული ფუნქციის აგება ერთი ან რამდენიმე რეალური ტიპის საფუძველზე. შემდგენელი ავტომატურად ქმნის ფუნქციის ორგანოს წარმომადგენლობით ზარში მითითებული ტიპებისთვის. ამ პროცესს ე.წ სპეციფიკაცია. ეს ხდება შაბლონის ფუნქციის გამოძახებისას.

მაგალითად, შემდეგ მაგალითში min() ფუნქცია ინსტანცირდება ორჯერ: ერთხელ ტიპის int და ერთხელ ტიპის double:

შაბლონი

ტიპი min (ტიპი a, ტიპი b)

თუ< b) return a; else return b;

int x = 4, y = 5, z;

ორმაგი t = 6.56, r = 3.07, p;

ფუნქციის შაბლონის სპეციალიზაცია

სპეციალიზებული შაბლონის ფუნქცია არის რეგულარული ფუნქცია, რომლის სახელიც იგივეა, რაც შაბლონის ფუნქცია, მაგრამ განსაზღვრულია კონკრეტული ტიპის პარამეტრებისთვის. შაბლონის სპეციალიზებული ფუნქციები განისაზღვრება, როდესაც ზოგადი შაბლონი არ არის შესაფერისი მონაცემთა კონკრეტული ტიპისთვის. მაგალითად, შაბლონის ფუნქცია min

შაბლონი

ტიპი min (ტიპი a, ტიპი b)

თუ< b) return a; else return b;

არ შეიძლება გამოყენებულ იქნას სტრიქონებისთვის (char* ტიპისთვის), რადგან შემდგენელის მიერ გენერირებული კოდი უბრალოდ შეადარებს მათ მეხსიერების პოზიციებს (მისამართებს). სტრიქონების სწორად შესადარებლად, შეგიძლიათ განსაზღვროთ სპეციალიზებული ფუნქცია:

char* min(char* s1, char* s2)

if (strcmp(s1,s2)>0) დააბრუნებს s2; სხვას დააბრუნებს s1;

შემდეგ თქვენ შეგიძლიათ შეხვიდეთ ასეთ ფუნქციაზე ისევე, როგორც შაბლონის ფუნქცია:

int i1 = 3, i2 = 5;

კოუტ<< “max int = ” << max(i1, i2) << endl;

char* s1 = „ოქროს არწივი“;

char* s2 = „პერიგრინის ფალკონი“;

კოუტ<< “max str = “ << max(s1, s2) << endl;

კლასის შაბლონები

კლასის შაბლონიიძლევა კლასების ოჯახის ზოგად განმარტებას თვითნებური ტიპების ან მუდმივების გამოყენებით. შაბლონი განსაზღვრავს შაბლონის მონაცემების წევრებიდა შაბლონის წევრის ფუნქციები. კლასის შაბლონის განსაზღვრის შემდეგ, შეგიძლიათ დაავალოთ შემდგენელს შექმნას ახალი კლასი მასზე დაფუძნებული კონკრეტული ტიპისთვის ან მუდმივისთვის.

კლასის შაბლონის სინტაქსი

შაბლონი<<список аргументов шаблона>>

კლასი<имя класса>

<тело класса>

შაბლონის საკვანძო სიტყვას მოსდევს ერთი ან მეტი არგუმენტი (პარამეტრი), რომელიც ჩასმულია კუთხური ფრჩხილებში და გამოყოფილია მძიმეებით. თითოეული არგუმენტი შეიძლება იყოს კლასის საკვანძო სიტყვა, რომელსაც მოჰყვება იდენტიფიკატორი, რომელიც მიუთითებს პარამეტრიზებულ ტიპზე. შაბლონის არგუმენტების სია არ შეიძლება იყოს ცარიელი.

შემდეგი მოდის კლასის განმარტება. ის ჩვეულებრივი კლასის განმარტების მსგავსია, გარდა იმისა, რომ იყენებს შაბლონის არგუმენტების სიას.

ხშირად უწოდებენ შაბლონის პარამეტრებს, რომლებიც შედგება კლასის საკვანძო სიტყვისგან, რასაც მოჰყვება იდენტიფიკატორი ტიპის პარამეტრები. სხვა სიტყვებით რომ ვთქვათ, ისინი აცნობებენ შემდგენელს, რომ შაბლონი ელოდება ტიპს, როგორც არგუმენტს.

სხვა სიტყვებით რომ ვთქვათ, ფუნქციების შაბლონები არის ინსტრუქციები, რომლის მიხედვითაც იქმნება შაბლონური ფუნქციის ადგილობრივი ვერსიები პარამეტრების და მონაცემთა ტიპების კონკრეტული ნაკრებისთვის.

სინამდვილეში, ფუნქციის შაბლონები არის ძლიერი ინსტრუმენტი C++-ში, რომელიც პროგრამისტის საქმეს ბევრად აადვილებს. მაგალითად, ჩვენ უნდა დავაპროგრამოთ ფუნქცია, რომელიც აჩვენებს მასივის ელემენტებს. ამოცანა არ არის რთული! მაგრამ ასეთი ფუნქციის დასაწერად უნდა ვიცოდეთ მასივის მონაცემთა ტიპი, რომელსაც გამოვაჩენთ ეკრანზე. შემდეგ ისინი გვეუბნებიან - არის ერთზე მეტი მონაცემთა ტიპი, ჩვენ გვინდა, რომ ფუნქცია გამოვიდეს ტიპის int, double, float და char.

როგორც იქნა, ამოცანა უფრო გართულდა. ახლა ჩვენ გვესმის, რომ ჩვენ გვჭირდება 4 ფუნქციის დაპროგრამება, რომლებიც ასრულებენ იგივე მოქმედებებს, მაგრამ სხვადასხვა ტიპის მონაცემებისთვის. ვინაიდან ჩვენ ჯერ არ ვიცნობთ ფუნქციების შაბლონებს, ჩვენ ამას გავაკეთებთ: გამოვიყენებთ .

// printArray ფუნქციის გადატვირთვა მასივის ეკრანზე void printArray(const int * array, int count) ( for (int ix = 0; ix< count; ix++) cout << array << " "; cout << endl; } void printArray(const double * array, int count) { for (int ix = 0; ix < count; ix++) cout << array << " "; cout << endl; } void printArray(const float * array, int count) { for (int ix = 0; ix < count; ix++) cout << array << " "; cout << endl; } void printArray(const char * array, int count) { for (int ix = 0; ix < count; ix++) cout << array << " "; cout << endl; }

ამრიგად, ჩვენ გვაქვს 4 გადატვირთული ფუნქცია, მონაცემთა სხვადასხვა ტიპებისთვის. როგორც ხედავთ, ისინი განსხვავდებიან მხოლოდ ფუნქციის სათაურში, მათი სხეული აბსოლუტურად ერთნაირია. ფუნქციის სხეული ერთხელ დავწერე int ტიპისთვის და სამჯერ დავაკოპირე სხვა მონაცემთა ტიპებისთვის.

და თუ პროგრამას ამ ფუნქციებით გაუშვით, ის გამართულად იმუშავებს. შემდგენელი თავად განსაზღვრავს რომელი ფუნქცია გამოიყენოს გამოძახებისას.

როგორც ხედავთ, ასეთი მარტივი ოპერაციისთვის საკმაოდ ბევრი კოდი იყო. რა მოხდება, თუ დაგვჭირდება მისი ფუნქციის დაპროგრამება. გამოდის, რომ თითოეული მონაცემთა ტიპისთვის მოგიწევთ საკუთარი ფუნქციის შექმნა. ანუ, თქვენ თვითონ გესმით, რომ იგივე კოდი იქნება რამდენიმე ეგზემპლარად, ეს ჩვენთვის არაფერ შუაშია. ამიტომ C++-მა მოიფიქრა ასეთი მექანიზმი – ფუნქციის შაბლონები.

ჩვენ ვქმნით ერთ შაბლონს, რომელშიც აღწერს მონაცემთა ყველა ტიპს. ამ გზით წყარო არ იქნება გადატვირთული კოდის არასაჭირო ხაზებით. ქვემოთ განვიხილავთ პროგრამის მაგალითს ფუნქციის შაბლონით. ასე რომ, გავიხსენოთ პირობა: „დააპროგრამე ფუნქცია, რომელიც აჩვენებს მასივის ელემენტებს“.

#შეიცავს < count; ix++) cout << array << " "; cout << endl; } // конец шаблона функции printArray int main() { // размеры массивов const int iSize = 10, dSize = 7, fSize = 10, cSize = 5; // массивы разных типов данных int iArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; double dArray = {1.2345, 2.234, 3.57, 4.67876, 5.346, 6.1545, 7.7682}; float fArray = {1.34, 2.37, 3.23, 4.8, 5.879, 6.345, 73.434, 8.82, 9.33, 10.4}; char cArray = {"MARS"}; cout << "\t\t Шаблон функции вывода массива на экран\n\n"; // вызов локальной версии функции printArray для типа int через шаблон cout << "\nМассив типа int:\n"; printArray(iArray, iSize); // вызов локальной версии функции printArray для типа double через шаблон cout << "\nМассив типа double:\n"; printArray(dArray, dSize); // вызов локальной версии функции printArray для типа float через шаблон cout << "\nМассив типа float:\n"; printArray(fArray, fSize); // вызов локальной версии функции printArray для типа char через шаблон cout << "\nМассив типа char:\n";printArray(cArray, cSize); return 0; }

// კოდი Code::Blocks

// Dev-C++ კოდი

#შეიცავს #შეიცავს სახელთა სივრცის გამოყენებით std; // ფუნქციის შაბლონი printArray შაბლონი void printArray(const T * მასივი, int რაოდენობა) ( for (int ix = 0; ix< count; ix++) cout << array << " "; cout << endl; } // конец шаблона функции printArray int main() { // размеры массивов const int iSize = 10, dSize = 7, fSize = 10, cSize = 5; // массивы разных типов данных int iArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; double dArray = {1.2345, 2.234, 3.57, 4.67876, 5.346, 6.1545, 7.7682}; float fArray = {1.34, 2.37, 3.23, 4.8, 5.879, 6.345, 73.434, 8.82, 9.33, 10.4}; char cArray = {"MARS"}; cout << "\t\t Шаблон функции вывода массива на экран\n\n"; // вызов локальной версии функции printArray для типа int через шаблон cout << "\nМассив типа int:\n"; printArray(iArray, iSize); // вызов локальной версии функции printArray для типа double через шаблон cout << "\nМассив типа double:\n"; printArray(dArray, dSize); // вызов локальной версии функции printArray для типа float через шаблон cout << "\nМассив типа float:\n"; printArray(fArray, fSize); // вызов локальной версии функции printArray для типа char через шаблон cout << "\nМассив типа char:\n";printArray(cArray, cSize); return 0; }

გთხოვთ გაითვალისწინოთ, რომ კოდი 4-ჯერ შემცირდა, ვინაიდან პროგრამაში ფუნქციის მხოლოდ ერთი ეგზემპლარია გამოცხადებული - შაბლონი. ძირითადში გამოვაცხადე რამდენიმე მასივი - ოთხი, მონაცემთა ტიპებისთვის: int, double, float, char. რის შემდეგაც 26, 28, 30, 32 სტრიქონებში printArray ფუნქცია გამოიძახება სხვადასხვა მასივებისთვის. პროგრამის შედეგი ნაჩვენებია ქვემოთ.

მასივის ეკრანზე გამოტანის შაბლონი int ტიპის მასივი: 1 2 3 4 5 6 7 8 9 10 მასივი double: 1.2345 2.234 3.57 4.67876 5.346 6.1545 7.7682 .21 .37 9 6. 345 73.434 8.82 9.33 10.4 char ტიპის მასივი: M A R S

როგორც ხედავთ, პროგრამა მუშაობს გამართულად და ამისთვის მხოლოდ ერთხელ დაგვჭირდა printArray ფუნქციის განსაზღვრა ჩვენთვის ნაცნობი ფორმით. გთხოვთ გაითვალისწინოთ, რომ თავად ფუნქციის დეკლარირებამდე, მე-5 სტრიქონზე, არის შემდეგი შაბლონის ჩანაწერი . ეს ჩანაწერი ვარაუდობს, რომ printArray ფუნქცია რეალურად არის ფუნქციის შაბლონი, რადგან printArray-ის პირველი პარამეტრი შეიცავს const T* მონაცემთა ტიპს, ზუსტად იგივე, რაც მე-5 სტრიქონში.

ყველა ფუნქციის შაბლონი იწყება სიტყვის შაბლონით, რასაც მოჰყვება კუთხის ფრჩხილები, რომლებიც ჩამოთვლის პარამეტრებს. თითოეულ პარამეტრს წინ უნდა უძღოდეს რეზერვირებული სიტყვის კლასი ან ტიპის სახელი.

შაბლონი

შაბლონი

შაბლონი

typename საკვანძო სიტყვა ეუბნება შემდგენელს, რომ შაბლონი გამოიყენებს ჩაშენებულ მონაცემთა ტიპს, როგორიცაა: int, double, float, char და ა.შ. და კლასის საკვანძო სიტყვა ეუბნება შემდგენელს, რომ ფუნქციის შაბლონი გამოიყენებს მონაცემთა მორგებულ ტიპებს პარამეტრად. ანუ კლასები.

ჩვენი ფუნქციის შაბლონი იყენებდა ჩაშენებულ მონაცემთა ტიპებს, ამიტომ მე-5 ხაზზე ჩვენ დავწერეთ შაბლონი . T-ის ნაცვლად, შეგიძლიათ შეცვალოთ ნებისმიერი სხვა სახელი, რომელიც მოიფიქრეთ. მოდით უფრო ახლოს მივხედოთ კოდის ფრაგმენტს ზედა პროგრამიდან, ცალკე დავდებ.

// ფუნქციის შაბლონი printArray შაბლონი void printArray(const T * მასივი, int რაოდენობა) ( for (int ix = 0; ix< count; ix++) cout << array << " "; cout << endl; } // конец шаблона функции printArray

ხაზი 2 განსაზღვრავს შაბლონს ერთი პარამეტრით, T, და ამ პარამეტრს ექნება მონაცემთა ერთ-ერთი ჩაშენებული ტიპი, რადგან მითითებულია typename საკვანძო სიტყვა.

ქვემოთ, 3 - 8 სტრიქონებში გამოცხადებულია ფუნქცია, რომელიც აკმაყოფილებს რეგულარული ფუნქციის გამოცხადების ყველა კრიტერიუმს, არის სათაური, არის ფუნქციის სხეული, სათაური შეიცავს ფუნქციის სახელს და პარამეტრებს, ყველაფერი ჩვეულებრივად არის. მაგრამ ის, რაც ამ ფუნქციას ფუნქციის შაბლონად აქცევს, არის პარამეტრი მონაცემთა ტიპის T, რომელიც არის ერთადერთი კავშირი ადრე გამოცხადებულ შაბლონთან. თუ დავწერდით

Void printArray(const int * array, int count) ( for (int ix = 0; ix< count; ix++) cout << array << " "; cout << endl; }

მაშინ ეს იქნება მარტივი ფუნქცია int ტიპის მასივისთვის.

ასე რომ, ფაქტობრივად, T არ არის მონაცემთა ტიპი, ის არის დაცული ადგილი ნებისმიერი ჩაშენებული მონაცემთა ტიპისთვის. ანუ ამ ფუნქციის გამოძახებისას შემდგენელი აანალიზებს შაბლონური ფუნქციის პარამეტრს და ქმნის ინსტანციას შესაბამისი მონაცემთა ტიპისთვის: int, char და ა.შ.

ამიტომ, უნდა გესმოდეთ, რომ თუნდაც კოდის ოდენობა უფრო მცირე იყოს, ეს არ ნიშნავს იმას, რომ პროგრამა ნაკლებ მეხსიერებას მოიხმარს. შემდგენელი თავად ქმნის შაბლონის ფუნქციის ლოკალურ ასლებს და, შესაბამისად, მოხმარებული მეხსიერების რაოდენობა ისეთია, თითქოს თქვენ თვითონ დაწერეთ ფუნქციის ყველა ინსტანცია, როგორც ეს ხდება გადატვირთვის შემთხვევაში.
იმედია გადმოგცეთ ძირითადი იდეა ფუნქციების შაბლონების შესახებ. მასალის გასამყარებლად, მოდით შევხედოთ სხვა პროგრამის მაგალითს ფუნქციის შაბლონის გამოყენებით.

#include "stdafx.h" #include #შეიცავს < size; ix++) if (max < array) max = array; return max; } int main() { // тестируем шаблон функции searchMax для массива типа char char array = "aodsiafgerkeio"; int len = strlen(array); cout << "Максимальный элемент массива типа char: " << searchMax(array, len) << endl; // тестируем шаблон функции searchMax для массива типа int int iArray = {3,5,7,2,9}; cout << "Максимальный элемент массива типа int: " << searchMax(iArray, 5) << endl; return 0; }

// კოდი Code::Blocks

// Dev-C++ კოდი

#შეიცავს #შეიცავს სახელთა სივრცის გამოყენებით std; // ფუნქციის შაბლონი მასივის შაბლონში მაქსიმალური მნიშვნელობის საპოვნელად T searchMax(const T* მასივი, int ზომა) ( T max = მასივი; // მაქსიმალური მნიშვნელობა მასივში for (int ix = 0; ix< size; ix++) if (max < array) max = array; return max; } int main() { // тестируем шаблон функции searchMax для массива типа char char array = "aodsiafgerkeio"; int len = strlen(array); cout << "Максимальный элемент массива типа char: " << searchMax(array, len) << endl; // тестируем шаблон функции searchMax для массива типа int int iArray = {3,5,7,2,9}; cout << "Максимальный элемент массива типа int: " << searchMax(iArray, 5) << endl; return 0; }

აქ არის ფუნქციის შაბლონების გამოყენების კიდევ ერთი მაგალითი. ფუნქციის შაბლონი დეკლარირებულია 5-13 სტრიქონებზე. ფუნქციამ უნდა დააბრუნოს მასივის მაქსიმალური მნიშვნელობა, ამიტომ დაბრუნებული მნიშვნელობა არის T ტიპის, რადგან მასივის მონაცემთა ტიპი წინასწარ არ არის ცნობილი. სხვათა შორის, ფუნქციის შიგნით არის გამოცხადებული T ტიპის ცვლადი max, მასივის მაქსიმალური მნიშვნელობა შეინახება. როგორც ხედავთ, T მონაცემთა ტიპი გამოიყენება არა მხოლოდ ფუნქციის პარამეტრების დასაზუსტებლად, არამედ დაბრუნების ტიპის აღსანიშნავად და ასევე შეიძლება თავისუფლად იქნას გამოყენებული ფუნქციის შაბლონში ნებისმიერი ცვლადის გამოცხადებისთვის.

char ტიპის მასივის მაქსიმალური ელემენტი: s int ტიპის მასივის მაქსიმალური ელემენტი: 9

ფუნქციის შაბლონები ასევე შეიძლება გადატვირთული იყოს სხვა ფუნქციების შაბლონებით, ფუნქციაზე გადაცემული პარამეტრების რაოდენობის შეცვლით. გადატვირთვის კიდევ ერთი მახასიათებელია ის, რომ შაბლონის ფუნქციები შეიძლება გადატვირთული იყოს ჩვეულებრივი არა შაბლონური ფუნქციებით. ანუ მითითებულია იგივე ფუნქციის სახელი, იგივე პარამეტრებით, ოღონდ კონკრეტული მონაცემთა ტიპისთვის და ყველაფერი სწორად იმუშავებს.



გაქვთ შეკითხვები?

შეატყობინეთ შეცდომას

ტექსტი, რომელიც გაეგზავნება ჩვენს რედაქტორებს: