| 1.1 ทำไมต้องใช้อินเทอร์เฟซ? ตัวอย่างเช่นมีบริการขายตั๋วเช่นโรงภาพยนตร์สามารถขายตั๋วบ้านโอเปร่าสามารถขายตั๋วและสถานีผู้โดยสารสามารถขายตั๋วได้ บริการขายตั๋ว? คุณควรรู้ว่าแม้แต่ผู้จัดการสามารถขายตั๋วได้ซึ่งไม่เหมาะที่จะรวมผู้จัดการไว้ในโครงสร้างมรดกของบริการขายตั๋ว ดังนั้นบริการขายตั๋วเป็นอินเทอร์เฟซ 1.2 วิธีใช้อินเทอร์เฟซใน Delphi | | 1.2.1 ประกาศอินเท อ ร์เฟซ imyInterface = อินเตอร์เฟส ( IIInterface) // คำแนะนำ (1) ['{63E072DF-B81E-4734-B3CB-3C23C7FDA8EA}'] // คำสั่ง (2) ฟังก์ชั่น getName ;ฟังก์ชั่น _release: จำนวนเต็ม ; end ; คำอธิบาย (1): หากมีความสัมพันธ์อย่างต่อเนื่องให้เติมอินเทอร์เฟซหลักในวงเล็บมิฉะนั้นให้บันทึกเช่น: imyInterface = อินเตอร์เฟส หมายเหตุ (2): GUID นี้เป็นทางเลือก รันไทม์เช่นคำจำกัดความของวิธีการอินเตอร์เฟส หมายเหตุ (3): อินเทอร์เฟซต้องใช้ฟังก์ชั่นทั้งสามนี้ 1.2.2 บริการอินเทอร์เฟซการใช้งานส่วนต่อประสานถูกนำมาใช้โดยคลาส tintfclass = class (tobject, imyinterface) privatefcounter: จำนวนเต็ม; frefcount: จำนวนเต็ม; publicfunction queryinterface (const iid: tguid; out obj): hresult; ตัวอย่างเช่น: var aintf: imyInterface; beartaobj: = tintfclass.create; tryaintf: = (imyInterface (aobj); ... b. ใช้กลไกในตัวของคอมไพเลอร์ Delphi ตัวอย่างเช่น: AINTF: = AOBJ.C. ใช้วิธีการ queryinterface ของวัตถุ อินเทอร์เฟซจะต้องระบุอย่างชัดเจนจาก IInterface อินเทอร์เฟซสืบทอด Delphi จะตรวจสอบอินเทอร์เฟซเองหากรหัสปล่อยไม่ได้เปิดตัวและ เพิ่ม โปรแกรมที่สร้างขึ้น แต่สิ่งนี้ยังทำให้เกิดปัญหาเช่นรหัสต่อไปนี้: VAR I: Integer; = tintfclass.create ; NIL ถูกตั้งค่าเป็นอินเทอร์เฟซและ Freeandnil (AOBJ) จะปล่อย AINTF อีกครั้งและวัตถุได้รับการปล่อยตัวเมื่อ AINTF เป็น NIL คุณจะต้องลดจำนวนการอ้างอิงโดยไม่ต้องปล่อย การมอบหมายวัตถุ คลาส ใช้อินเทอร์เฟซ: timplclass = คลาส (tobject, iimplinterface) private frefcount: จำนวนเต็ม; ฟังก์ชั่นสาธารณะ converttousd (const intd: จำนวนเต็ม): double; เริ่มต้นถ้า getInterface (IID, OBJ) จากนั้นผลลัพธ์: = 0 ผลลัพธ์อื่น ๆ : = e_noInterface; end; ฟังก์ชั่น timplclass._release: integer; ตอนนี้มีคลาส Tintfserviceclass อื่นที่จะใช้อินเตอร์เฟส IIMPLINTERFACE ไม่จำเป็นต้องกำหนดใหม่ ด้วย วัตถุที่ ได้ รับการทำลายล้าง; มอบหมายกับวัตถุ End; การใช้งานมีดังนี้: constructor tintfserviceclass.create; .Create; end; destructor tintfserviceclass.destroy; ตัวชี้อินเตอร์เฟส GOG ถูกกำหนดที่การกระจัด VMT -72 ในอินเตอร์เฟสและ rttidelphi: vmtintftable = -72 ฟังก์ชั่นที่เกี่ยวข้อง: getInterfacecount; getInterfacetable; โครงสร้างที่เกี่ยวข้อง: tinterfaceentry = packed recordiid: tguid; vtable: pointer; ioffset: จำนวนเต็ม; impletter: จำนวนเต็ม; end; pinterfacetable = ^tinterfacetable; tinterfacetable = packed recordentryCount: จำนวนเต็ม; Self เป็นตัวชี้ไปยังตัวชี้ VMT ดังนั้น: self.getInterfacetable.entryCount เทียบเท่ากับ: APTR: = pPointer (integeer ((ตัวชี้ (ตัวเอง))^) + vmtintftable)^; คำแนะนำในการประกาศข้อมูล RTTI สามารถเพิ่มลงในโปรแกรมที่รวบรวมใน Delphi เช่น: {$ m+} iinvokable = อินเตอร์เฟส (iiinterface) {$ m-} ข้อมูล RTTI ของอินเทอร์เฟซถูกกำหนดโดยโครงสร้างบันทึก TintfMetadata: Tintfmetadata = recordname: String; ข้อมูลอินเตอร์เฟส: ptypeinfo; // ตัวชี้อธิบายข้อมูลอินเตอร์เฟส ancinfo: ptypeinfo; // ตัวชี้อธิบายข้อมูลหลัก Numanc: จำนวนเต็ม; // จำนวนวิธีการที่สืบทอดมาจากส่วนต่อประสานหลัก , ccpascal, ccstdcall, ccsafecall); ptypeinfo; // อธิบายตัวชี้ข้อมูลของวิธีการ back-pass ประเภท selfinfo: ptypeinfo; // ตัวชี้ข้อมูลอธิบายวิธีการของตัวเองพารามิเตอร์: tintfparamentryarray; // อาร์เรย์แบบไดนามิกที่อธิบายข้อมูลพารามิเตอร์ hasrtti: boolean; // สิ้นสุดข้อมูล RTTI; รูปแบบจุดสิ้นสุดของข้อมูลประเภท; |
|