გენერიკების გამოყენება RAD Studio Delphi-ში. ჩვენ ვქმნით ბიბლიოთეკას მსგავსი ობიექტების სიების დასახარისხებლად. გენერიკების გამოყენება Delphi-ში! დელფის მიჯაჭვული სიები

დღეს ჩვენ შევქმნით კლასის ბიბლიოთეკას RAD Studio Delphi-ში, რომელიც ახორციელებს მსგავსი ობიექტების სიების დახარისხებას.

დავალების მიზანი

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

Ვიწყებთ

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

აიკომპარერი = ინტერფეისის ფუნქცია Compare(const Left, Right: T): მთელი რიცხვი; დასასრული; TComparer = კლასი (TInterfacedObject, IComparer ) საჯარო კლასის ფუნქცია ნაგულისხმევი: IComparer ; კლასის ფუნქცია Construct(const Comparison: TComparison ): IComparer ; ფუნქცია Compare(const Left, Right: T): მთელი რიცხვი; ვირტუალური; აბსტრაქტული; დასასრული;
ინტერფეისში ჩვენ ვხედავთ ერთადერთ მეთოდს შეადარეკეთილი

შედარება
შესასვლელში არის ორი ობიექტის ტიპის პარამეტრი, ხოლო გამოსავალზე მთელი რიცხვი (0 - ობიექტები ტოლია, -1 - პირველი ნაკლებია მეორეზე, 1 - პირველი მეტია მეორეზე).

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

შედარება = ფუნქციაზე მითითება (const Left, Right: T): მთელი რიცხვი;
და TComparer(T) კლასი უბრალოდ ემსახურება ორი ობიექტის შედარებას მეთოდის გამოძახებით შეადარე.
შეგიძლიათ გამოიყენოთ ნაგულისხმევი შედარება ( ნაგულისხმევი), ან შექმენით საკუთარი შედარების მეთოდი კონსტრუქციარასაც ჩვენ ვაპირებთ.

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

ოპერაციები ობიექტებთან
სიის ობიექტებთან ოპერაციების შესასრულებლად Delphi-ს უკვე აქვს ჩვენთვის საჭირო პარამეტრიზებული კლასი, ის ასევე არის ზოგადი, ჩვენთვის საჭირო მეთოდებით

TList = კლასი (TE უთვალავი )
ზოგადად, ზოგადი პარამეტრიზებული ტიპები (გენერიკები) გამოჩნდა Delphi 2009-ში, მაგრამ ჩვენი მაგალითისთვის მე ვიყენებ RAD Studio Berlin 10.1 UPD1. თუ რამე არ არის შედგენილი თქვენთვის, თქვენ უნდა დაასრულოთ მაგალითი თქვენი დელფის ვერსიისთვის.

ჩვენ ვწერთ ჩვენი ბიბლიოთეკის მემკვიდრის ძირითად კლასს TList(T)

// მთავარი კლასი იმავე ტიპის TAppliedObjectList ობიექტების ჩამონათვალთან მუშაობისთვის = კლასი (TList ) კერძო ტიპის TSort = ფუნქციაზე მითითება (var მნიშვნელობები: T მასივი; const შედარება: IComparer ; Index, Count: Integer): მთელი რიცხვი; var FCS: TCriticalSection; // ოპერაციები სიის ელემენტების გადაცემით კეთდება ძაფისგან დამოუკიდებელი FComparer: IComparer ; // სიის ობიექტების შედარების არჩეული მეთოდი ინახება Target: Array of T; // ელემენტების დროებითი მასივი, რომელიც გადაეცემა დახარისხების მეთოდს // შექმნილია იმიტომ, რომ ელემენტების მასივი მშობელ კლასშია პირადისაჯარო კონსტრუქტორი შექმნა; გადატვირთვა; კონსტრუქტორი Create(const AComparer: IComparer ); გადატვირთვა; დესტრუქტორი Destroy; გადააჭარბებს; // აქ განვათავსებთ დამატებით საჯარო მეთოდებს ობიექტებზე მუშაობისთვის // უნივერსალური დახარისხების მეთოდი სასურველი მეთოდის მითითებით // აბრუნებს პერმუტაციების რაოდენობას, იმედია ნაკლები იქნება MaxIntფუნქციაSortBy (შემდეგ AProc: TSorting ): მთელი რიცხვი; გადატვირთვა; დასასრული;
ჩვენი ამოცანის მთავარი მეთოდი დალაგება, ჩვენ აღვწერთ მის გამოყენებას ქვემოთ.

ობიექტების დახარისხება
კლასის წერა TAllSort, რომელიც შეიცავს ხედის დახარისხების 100-ვე მეთოდის აღწერას:

TS დახარისხება ; Index, Count: Integer): მთელი რიცხვი;
შეყვანისას მეთოდი იღებს მონაცემთა მასივს სიიდან, ობიექტების შედარების მეთოდს, დახარისხების საწყის პოზიციას და ელემენტების რაოდენობას ნაკრებში. გამოსავალზე ვიღებთ მონაცემთა ნაკრებში შესრულებული პერმუტაციების რაოდენობას.

ტიპი // დახარისხების მეთოდები უნდა იყოს TSorting ფორმის TS დახარისხება = ფუნქციაზე მითითება ; Index, Count: Integer): მთელი რიცხვი; // მთავარი კლასი, შეიცავს დალაგების 100 მეთოდს TAllSort = კლასი საჯარო // *** Bubble დახარისხების კლასის ფუნქცია BubbleSort (var მნიშვნელობები: T მასივი; const შედარება: IComparer ; Index, Count: Integer): მთელი რიცხვი; // *** QuickSort კლასის ფუნქცია QuickSort (var მნიშვნელობები: T მასივი; const შედარება: IComparer ; Index, Count: Integer): მთელი რიცხვი; დასასრული;
მოხერხებულობისთვის, ჩვენ შევინახავთ დახარისხების ყველა მეთოდს ცალკე მოდულში დალაგების მეთოდები.

დემონსტრაცია

ამოხსნის დემონსტრირებად წარმოგიდგენთ 2 დახარისხების მექანიზმს: „სწრაფი“ და „ბუშტი“. დავახარისხებთ 2 ტიპის ობიექტს: ორგანზომილებიანი ვექტორების სიას (მოწესრიგებული წყვილები) მთელი ტიპის და სიას სტრიქონებით.

პირველ რიგში, მოდით დავახარისხოთ სტრიქონების მასივი "ბუშტების" მიხედვით:

პროცედურა TfmMainTest.Button4Click(Sender: TObject); var // TAppliedObjectList ტიპის ცვლადის გამოცხადება // მიუთითეთ, რომ სიაში შეინახავს სტრიქონის ტიპის ობიექტებს MyClass: TAppliedObjectList ; i: მთელი რიცხვი; დაწყება Memo1.Clear; სცადეთ // შექმენით ჩვენი კლასის ეგზემპლარი, // შედარების მეთოდად გამოვიყენებთ სტანდარტულ შედარებს სტრიქონებისთვის // IComparer ტიპის MyClass:= TAppliedObjectList .Create(TComparer .ნაგულისხმევი); სცადე Memo1.Lines.Text:= "ჩემი მეგობარი არის მხატვარი და პოეტი ჭიქით წვიმიან საღამოს" + sLineBreak + "მან დახატა ჩემი სიყვარული და გამომიცხადა სასწაული დედამიწაზე." + sLineBreak + "ჩუმად ვიჯექი ფანჯარასთან და ვტკბებოდი სიჩუმით" + sLineBreak + "ჩემი სიყვარული მას შემდეგ ყოველთვის ჩემთანაა." + sLineBreak + "და სანამ წყალი მოედინებოდა და მე ყოველთვის თბილი ვიყავი," + sLineBreak + "როცა წვიმიან საღამოს ფანჯრის მინას ვუყურებდი." + sLineBreak + "მაგრამ ყოველწლიურად ვხვდებოდი სევდას ჩემი სიყვარულის თვალში", + sLineBreak + "წვიმიანი მოწყენილობა მოსაწყენი კვალია და, აჰა, სიყვარულმა ფერი იცვალა." + sLineBreak + "ჩემმა სიყვარულმა ფერი შეიცვალა, მშვენიერი ნათელი დღე გაქრა" + sLineBreak + "ჩემი სიყვარული ღამით დაფარულია ჩრდილით." + sLineBreak + "ფერადი ჭორები, ზღაპრული ცეცხლის თამაში" + sLineBreak + "ჩემი სიყვარული აღარ მსიამოვნებს."; // შეავსეთ სია ხაზებით Memo-დან i:= 0-მდე Memo1.Lines.Count - 1 დაიწყეთ MyClass.Add(Memo1.Lines[i]); დასასრული; // მოვუწოდებთ ბუშტების დახარისხების მეთოდს i:= MyClass.SortBy (TAllSort.BubbleSort ); // პერმუტაციების რაოდენობის გამოტანა Memo1.Lines.Add(sLineBreak + "Turns: " + i.ToString); // მიღებული სიის გამოტანა Memo1.Lines.Add("მიღებული სია:"); for i:= 0 to MyClass.Count - 1 დაიწყე Memo1.Lines.Add(MyClass.Items[i]); დასასრული; საბოლოოდ // არ დაგავიწყდეთ წაშალოთ ინსტანცია, როდესაც დავასრულებთ მას MyClass.Free; დასასრული; გარდა E: Exception do Memo1.Lines.Add(E.Message); დასასრული; დასასრული;
მივიღე შედეგი:

ახლა კი მოდით "სწრაფად" დავახარისხოთ ორგანზომილებიანი ვექტორების მასივი:

პროცედურა TfmMainTest.Button3Click(Sender: TObject); var // TAppliedObjectList ტიპის ცვლადის გამოცხადება // მიუთითეთ, რომ სიაში შეინახავს TVector2D ტიპის ობიექტებს MyClass: TAppliedObjectList ; // TVector2D ტიპის დამხმარე ცვლადი v: TVector2D; i: მთელი რიცხვი; დაწყება Memo1.Clear; სცადეთ // შექმენით ჩვენი სიის კლასის მაგალითი, // შედარების მეთოდად გამოვიყენებთ // TAllComparison.Compare_TVector2D მეთოდს MyClass:= TAppliedObjectList .Create(TComparer .Construct(TAllComparison.Compare_TVector2D)); try // სიის შევსება 2D ვექტორის ტიპის ობიექტებით Memo1.Lines.Add("Initial list:"); v.Create(10, 21); MyClass.Add(v); Memo1.Lines.Add(v.ToString); v.Create(-10, 20); MyClass.Add(v); Memo1.Lines.Add(v.ToString); v.Create(-10, -2); MyClass.Add(v); Memo1.Lines.Add(v.ToString); v.Create(-1, 7); MyClass.Add(v); Memo1.Lines.Add(v.ToString); // მოვუწოდებთ "სწრაფი" დახარისხების მეთოდს i:= MyClass.SortBy (TAllSort.QuickSort ); // პერმუტაციების რაოდენობის გამოტანა Memo1.Lines.Add(sLineBreak + "Turns: " + i.ToString); // მიღებული სიის გამოტანა Memo1.Lines.Add("მიღებული სია:"); for i:= 0 to MyClass.Count - 1 დაიწყე Memo1.Lines.Add(MyClass.Items[i].ToString); დასასრული; ბოლოს // არ დაგავიწყდეთ წაშალოთ ინსტანცია, როდესაც დავასრულებთ მას, if Assigned(MyClass) მაშინ MyClass.Free; დასასრული; გარდა E: Exception do Memo1.Lines.Add(E.Message); დასასრული; დასასრული;
აქ არის შედეგი ვექტორებით:

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

სია შეიძლება იყოს გრაფიკულად (ნახ. 8.5).

ბრინჯი. 8.5. გრაფიკული გამოსახულებასია

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

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

ტიპი TPStudent = """TStudent; // მაჩვენებელი TStudent ტიპის ცვლადზე

// სიის ელემენტის ტიპის აღწერა TStudent = ჩანაწერი

გვარი: სიმებიანი; // გვარი

სახელი: სიმებიანი; // სახელი

ჯგუფი: მთელი რიცხვი; // დასის ნომერი

მისამართი:სტრიქონი; // სახლის მისამართი

შემდეგი: T.P.Student; // მაჩვენებელი სიის ბოლოს მომდევნო ელემენტზე;

var ხელმძღვანელი: TPSstudent; // მაჩვენებელი სიის პირველ ელემენტზე

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


ბრინჯი. 8.6. ელემენტების სიაში დამატება

შემდეგი პროგრამა, რომელიც ნაჩვენებია სიაში 8.4, ქმნის სტუდენტების სიას სიის წინ გვარების დამატებით. მონაცემები შეიტანება პროგრამის დიალოგური ფანჯრის რედაქტირების ველებში (ნახ. 8.7) და დაემატება სიას Add ღილაკის (v#op1) დაჭერით.


ბრინჯი. 8.7. პროგრამის ფანჯარა დინამიური სია 1

\ ჩამონათვალი 8.4. ელემენტის დამატება დინამიური სიის დასაწყისში

ერთეული dlistl_; ინტერფეისი იყენებს Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; ტიპი TForml = class(TForm) Label1: TLabel; Label2: T Label; Label3: T Label;

რედაქტირება: TEdit; // გვარი

Edit2: TEdit; // სახელი

ღილაკი: TButton; // ღილაკი დამატება

ღილაკი 2: TButton; // ღილაკი ჩვენება

Procedure ButtonlClick(Sender: TObject); პროცედურა Button2Click(გამომგზავნი: TObject); კერძო (Private declarations) public (Public declarations) დასასრული; var ფორმა: TForml;

($R *.DFM) ტიპი TPStudent=/4TStudent; // მაჩვენებელი ტიპი TStudent

TStudent = ჩანაწერი

f_name:string; // გვარი l_name: string; // სახელი

შემდეგი: T.P.Student; // სიის შემდეგი ელემენტი

var ხელმძღვანელი: TPSstudent; // სიის დასაწყისი (თავი).

// დაამატეთ ელემენტი სიის დასაწყისში

პროცედურა TForml.ButtonlClick(Sender: TObject); var curr: TPStudent; // ახალი ელემენტისია იწყება ახალი (curr); // მეხსიერების გამოყოფა სიის ელემენტისთვის siggle.f_name:= Edit1.Text; siggle.l_name:= Edit2.Text; // სიის დასაწყისში დამატება curl.next:= head; ხელმძღვანელი:=curr; // შეყვანის ველების გასუფთავება Editl.text:=""; Edit2.text:=""; დასასრული;

// სიაში

პროცედურა TForml.Button2Click(გამომგზავნი: TObject); var curr: TPStudent; // სიის მიმდინარე ელემენტი n:integer; // სიის სიგრძე (ელემენტების რაოდენობა).

st:string; // სიის სიმებიანი წარმოდგენა

დასაწყისი n:= 0; st:= " ; curr:= head; // მაჩვენებელი სიის პირველ ელემენტზე, ხოლო curr o NIL იწყება n:= n + 1; st:= st + siggle.£_path + " " + siggle.1_path + #13; curr:= curch.next // მაჩვენებელი შემდეგი ელემენტის ბოლოს;

შემდეგ ShowMessage("List:" + #13 + st) else ShowMessage("სიაში არ არის ელემენტი."); დასასრული; დასასრული.

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

სიის გამომავალი ხორციელდება პროცედურა TForml. Button2ciick, რომელიც ამოქმედდება ღილაკზე ჩვენების დაჭერისას. Curr მაჩვენებელი გამოიყენება სიის ელემენტებზე წვდომისთვის. ის ჯერ შეიცავს სიის პირველი ელემენტის მისამართს. სიის პირველი ელემენტის დამუშავების შემდეგ, curr მაჩვენებელი დაყენებულია ჩანაწერის შემდეგი ველის მნიშვნელობაზე, რომელზეც მიუთითებს curr. შედეგად, ცვლადი curr შეიცავს სიის მეორე ელემენტის მისამართს. ამრიგად, მაჩვენებელი გადადის სიაში. პროცესი მეორდება მანამ, სანამ სიის მიმდინარე ელემენტის შემდეგი ველის მნიშვნელობა (ელემენტი, რომლის მისამართი შეიცავს curr ცვლადს) არ იქნება ნულის ტოლი.

დინამიური სია 3
ერთეული dlist3_; ინტერფეისი იყენებს Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; ტიპი TForm1 = კლასი(TForm) Label1: TLabel; Label2: T Label; ღილაკი 1: TButton; ღილაკი 2: TButton; Label3: T Label; რედაქტირება1: TEdit; Edit2: TEdit; ღილაკი 3: TButton; პროცედურა Button1Click(გამომგზავნი: TObject); პროცედურა Button2Click(გამომგზავნი: TObject); პროცედურა FormActivate(გამომგზავნი: TObject); პროცედურა Button3Click(გამომგზავნი: TObject); კერძო (პირადი დეკლარაციები) საჯარო (საჯარო განცხადებები) დასასრული; ვარფორმა1: TForm1; განხორციელება ($R *.DFM) ტიპი TPStudent = ^TStudent; //მაჩვენებელი აკრიფეთ TStudent TSსტუდენტი= ჩანაწერი f_name: სიმებიანი; // გვარი l_name: სიმებიანი; // სახელიშემდეგი: T.P.Student; // სიის შემდეგი ელემენტი დასასრული; ვარხელმძღვანელი: თ.პ.სტუდენტი; // სიის დასაწყისი (თავი). პროცედურა TForm1.Button1Click(გამომგზავნი: TObject); ვარკვანძი: TPSstudent; // სიის ახალი კვანძი curr: T.P.Student; // მიმდინარე სიის კვანძი პრე: ტ.პ.სტუდენტი; // წინა, curr-თან შედარებით, კვანძი დაიწყებაახალი (კვანძი); // სიის ახალი ელემენტის შექმნა node^.f_name:= Edit1.Text; node^.l_name:= Edit2.Text; // სიაში კვანძის დამატება // ჯერ იპოვნეთ სიაში შესაფერისი ადგილი კვანძისთვის curr:=ხელმძღვანელი; წინასწარ:= ნული; ( ყურადღება! თუ ქვემოთ მოცემული პირობა შეიცვალა (node.f_name>curr^.f_name)და (curr)<>NIL), პირველი კვანძის დამატება იწვევს გაშვების დროის შეცდომას, რადგან curr = NIL და, შესაბამისად, არ არსებობს curr.^name ცვლადი! პირობის გამოყენებულ ვარიანტში შეცდომა არ ხდება, რადგან პირობა ჯერ შემოწმდება (curr<>NIL), რომლის მნიშვნელობა არის FALSE და მეორე პირობა ამ შემთხვევაში არ არის შემოწმებული. ) ხოლო(კურ<> ნული) და(node.f_name > curr^.f_name) კეთება დაიწყება // შეყვანილი მნიშვნელობა უფრო დიდია ვიდრე მიმდინარე წინასწარ:=curr; curr:= curr^.next; // შემდეგ კვანძში დასასრული; თუწინასწარ = ნული მაშინ დაიწყება // ახალი კვანძი სიის სათავეში კვანძი^.შემდეგი:= თავი; ხელმძღვანელი:=კვანძი; დასასრული სხვა დაიწყება // ახალი კვანძი პრე-ს შემდეგ, curr-მდე node^.next:= pre^.next; pre^.next:= კვანძი; დასასრული; Edit1.text:=""; Edit2.text:=""; Edit1.SetFocus; დასასრული; პროცედურა TForm1.Button2Click(გამომგზავნი: TObject); ვარ curr: T.P.Student; // სიის მიმდინარე ელემენტი n: მთელი რიცხვი // სიის სიგრძე (ელემენტების რაოდენობა). st: სიმებიანი; // სიის სიმებიანი წარმოდგენა დაიწყება n:=0; st:=""; curr:=ხელმძღვანელი; ხოლო curr<> ნული კეთება დაიწყება n:= n + 1; st:= st + curr^.f_name + " " + curr^.l_name + #13; curr:= curr^.next; დასასრული; თუნ<> 0 მაშინ ShowMessage("List:" + #13 + st) სხვა ShowMessage ("სიაში არ არის ელემენტი."); დასასრული; პროცედურა TForm1.FormActivate(გამომგზავნი: TObject); დაიწყებათავი:= ნული; დასასრული; // დააჭირეთ წაშლის ღილაკს პროცედურა TForm1.Button3Click(გამომგზავნი: TObject); ვარ curr: T.P.Student; // მიმდინარე, შემოწმებული კვანძი პრე: ტ.პ.სტუდენტი; // წინა კვანძი ნაპოვნია: ლოგიკური; // TRUE - კვანძი, რომელიც უნდა წაიშალოს, არის სიაში დაიწყება თუთავი = ნული მაშინ დაიწყება MessageDlg(" სია ცარიელია!", mtError, , 0); გასასვლელი; დასასრული; curr:=ხელმძღვანელი; // მიმდინარე კვანძი - პირველი კვანძი წინასწარ:= ნული; // წინა კვანძი არ არის ნაპოვნია:= FALSE; // იპოვნეთ წასაშლელი კვანძი ხოლო(კურ<> ნული) და (არანაპოვნია) კეთება დაიწყება თუ(curr^.f_name = Edit1.Text) და(curr^.l_name = Edit2.Text) მაშინნაპოვნია: = TRUE // მოიძებნა სასურველი კვანძი სხვა // შემდეგ კვანძში დაიწყებაწინასწარ:=curr; curr:= curr^.next; დასასრული; დასასრული; თუნაპოვნია მაშინ დაიწყება // მოიძებნა სასურველი კვანძი თუ MessageDlg ("კვანძი წაიშლება სიიდან!", mtWarning, , 0)<>ბატონო დიახ მაშინგასასვლელი; // ამოიღეთ კვანძი თუწინასწარ = ნული მაშინხელმძღვანელი:= curr^.შემდეგი // ამოიღეთ სიის პირველი კვანძი სხვა pre^.next:= curr.next; განკარგვა (curr); MessageDlg("Node" + #13 + "Name:" + Edit1.Text + #13 + "LastName:" + Edit2.Text + #13 + "ამოღებულია სიიდან.", mtInformation, , 0); დასასრული სხვა // წაშლილი კვანძი არ არის სიაში MessageDlg("Node" + #13 + "Name:" + Edit1.Text + #13 + "LastName:" + Edit2.Text + #13 + "არ მოიძებნა სიაში.", mtError, , 0); Edit1.Text:=""; Edit1.Text:=""; Edit1.SetFocus; დასასრული; დასასრული. ჩამოტვირთვა რა არის გენერიკა და რატომ არის საჭირო?
ენაში განზოგადებების არსებობა საშუალებას გაძლევთ შექმნათ ღია ტიპები, რომლებიც ხდება პირადი შედგენის დროს. გენერიკების სინტაქსი ზოგადი TPoint აღნიშვნის მაგალითზე მიცემული ჩამონათვალი 1:
ჩამონათვალი 1 - ზოგადი TPoint ჩანაწერის გამოცხადება
აკრიფეთ TPoint = ჩანაწერი X: T; Y:T; დასასრული; განსხვავებები რეგულარული ჩანაწერის გამოცხადებისგან მაშინვე თვალშისაცემია - ყოფნა შესვლის სახელში და იმავე ტიპის T-ის X და Y კოორდინატებში. T აქ არის დაუზუსტებელი ტიპი, რომელიც მოგვიანებით იქნება მითითებული, როდესაც შეიქმნება კონკრეტული ჩანაწერი.
დავუშვათ, რომ ჩვენ გადავწყვიტეთ გამოვიყენოთ "ფრაქციული" წერტილები აპლიკაციაში (მაგალითად, Double ). ყველაფერი რაც თქვენ უნდა გააკეთოთ არის შემდეგი პირადი ტიპის გამოცხადება:
ჩამონათვალი 2 - ზოგადი TPPoint აღნიშვნის გამოყენება როგორც "ფრაქციული" წერტილი
... var MyPoint: TPoint ; დაიწყე MyPoint.X:= 1.5; MyPoint.Y:= -0.5; ... და თუ ჩვენ გვჭირდება მთელი ტიპი, ჩვენ უბრალოდ ვცვლით Double-ს მთელ რიცხვზე:
ჩამონათვალი 3 - ზოგადი TPoint ჩანაწერის გამოყენება როგორც "მთლიანი" წერტილი
... var MyPoint: TPoint ; დაიწყე MyPoint.X:= 1; MyPoint.Y:= 100; ... მარტივია, არა? MyPoint: TPoint და MyPoint: TPoint - უკვე დახურული ტიპებია და ემორჩილება ყველა იმ წესს, რომელიც მოქმედებს ჩვეულებრივი, არაგენერიკული ტიპებისთვის.

შეიძლება გაჩნდეს კითხვა: შემიძლია ამის გაკეთება გენერიკების გარეშე? Რა თქმა უნდა, შეგიძლია. მართალია, დაკარგეთ მრავალი უპირატესობა.

[ნაწილი 1 - შესავალი გენერიკაში] [