OOP "วัตถุ" และ "คลาส" จัดระเบียบในหน่วยความจำในแง่ของภาษาแอสเซมบลีอย่างไร


13

วัตถุถูกจัดระเบียบในหน่วยความจำอย่างไร

ตัวอย่างเช่นฉันรู้ว่าฟังก์ชั่นเป็นส่วนหนึ่งของรหัสในหน่วยความจำที่คาดว่าพารามิเตอร์ผ่านสแต็คและ / หรือการลงทะเบียนและจัดการสแต็กเฟรมของตัวเอง

แต่วัตถุเป็นโครงสร้างที่ซับซ้อนกว่ามาก พวกเขาจัดระเบียบอย่างไร แต่ละวัตถุมี "ลิงก์" ไปยังวิธีการและส่งต่อที่อยู่ให้กับตัวเองไปยังวิธีการนั้นหรือไม่

มันจะเป็นการดีถ้าได้เห็นคำอธิบายที่ดีของหัวข้อนี้

UPD ฉันทำให้คำถามถูกต้องมากขึ้นและฉันสนใจในการพิมพ์ภาษาแบบคงที่เป็นส่วนใหญ่


4
สามารถแตกต่างกันอย่างมากระหว่างภาษาต่าง ๆ โดยเฉพาะอย่างยิ่งระหว่างภาษาที่พิมพ์แบบไดนามิกและภาษาที่พิมพ์แบบคงที่ คุณ จำกัด คำถามของคุณให้แคบลงเป็นภาษา OO ที่คุณสนใจมากที่สุดได้หรือไม่?
Bart van Ingen Schenau

ฉันได้อัปเดตคำถามดังนั้นฉันจึงคิดว่าภาษาที่พิมพ์แบบไดนามิกนั้นยากที่จะเข้าใจ
Nikolai Golub

คำตอบ:


17

หากไม่มีการแจกจ่ายแบบไดนามิก (polymorphism) "เมธอด" เป็นเพียงฟังก์ชันน้ำตาลอาจมีพารามิเตอร์เพิ่มเติมโดยนัย ดังนั้นอินสแตนซ์ของคลาสที่ไม่มีพฤติกรรม polymorphic นั้นเป็นหลัก C structs เพื่อจุดประสงค์ในการสร้างรหัส

สำหรับการกระจายแบบไดนามิกแบบคลาสสิกในระบบชนิดสแตติกมีกลยุทธ์หนึ่งที่โดดเด่น: vtables ทุกอินสแตนซ์ได้รับตัวชี้เพิ่มเติมอีกหนึ่งตัวที่อ้างถึง (การ จำกัด การแสดงออก) ชนิดของมันสิ่งสำคัญที่สุดคือ vtable: อาเรย์ของพอยน์เตอร์ของฟังก์ชันหนึ่งตัวต่อวิธี เนื่องจากชุดเต็มของวิธีการสำหรับทุกประเภท (ในห่วงโซ่การสืบทอด) เป็นที่รู้จักกันในเวลารวบรวมหนึ่งสามารถกำหนดดัชนีต่อเนื่อง (0..N สำหรับวิธีการ N) กับวิธีการและเรียกใช้วิธีการโดยการค้นหาตัวชี้ฟังก์ชั่นใน vtable โดยใช้ดัชนีนี้ (อีกครั้งผ่านการอ้างอิงอินสแตนซ์เป็นพารามิเตอร์เพิ่มเติม)

สำหรับภาษาที่ใช้คลาสแบบไดนามิกมากขึ้นโดยทั่วไปคลาสของตัวเองจะเป็นออบเจ็กต์ชั้นหนึ่งและแต่ละออบเจ็กต์จะมีการอ้างอิงไปยังออบเจกต์คลาส ในทางกลับกันคลาสอ็อบเจ็กต์เป็นเจ้าของเมธอดในลักษณะที่ขึ้นกับภาษาบางอย่าง (ใน Ruby เมธอดเป็นส่วนหลักของโมเดลวัตถุใน Python พวกมันเป็นเพียงฟังก์ชั่นของวัตถุ โดยทั่วไปคลาสจะจัดเก็บการอ้างอิงถึงซูเปอร์คลาส (es) ของพวกเขาเช่นกันและมอบหมายการค้นหาวิธีการสืบทอดให้กับคลาสเหล่านั้นเพื่อช่วย metaprogramming ซึ่งจะเพิ่มและเปลี่ยนแปลงวิธีการ

มีระบบอื่น ๆ อีกมากมายที่ไม่ได้ขึ้นอยู่กับคลาส แต่แตกต่างกันอย่างมีนัยสำคัญดังนั้นฉันจะเลือกทางเลือกการออกแบบที่น่าสนใจเพียงทางเดียว: เมื่อคุณสามารถเพิ่มวิธีการใหม่ ๆ เช่นคลาสของประเภทใน Haskell และลักษณะใน Rust) วิธีการแบบเต็มรูปแบบไม่เป็นที่รู้จักในขณะที่รวบรวม ในการแก้ไขปัญหานี้จะสร้าง vtable ต่อลักษณะและส่งผ่านเมื่อจำเป็นต้องใช้งานคุณลักษณะ นั่นคือรหัสเช่นนี้:

void needs_a_trait(SomeTrait &x) { x.method2(1); }
ConcreteType x = ...;
needs_a_trait(x);

ถูกรวบรวมลงในสิ่งนี้:

functionpointer SomeTrait_ConcreteType_vtable[] = { &method1, &method2, ... };
void needs_a_trait(void *x, functionpointer vtable[]) { vtable[1](x, 1); }
ConcreteType x = ...;
needs_a_trait(x, SomeTrait_ConcreteType_vtable);

นอกจากนี้ยังหมายความว่าข้อมูล vtable ไม่ได้ฝังอยู่ในวัตถุ หากคุณต้องการการอ้างอิงถึงเป็น "ตัวอย่างของลักษณะ" ที่จะประพฤติอย่างถูกต้องเมื่อยกตัวอย่างเช่นเก็บไว้ในโครงสร้างข้อมูลที่มีมากมายหลายชนิดหนึ่งสามารถสร้างตัวชี้ไขมัน (instance_pointer, trait_vtable)นี่คือความจริงทั่วไปของกลยุทธ์ข้างต้น


5

นี่คือคำตอบในความหมายของสุภาษิต "ถ้าคุณให้ปลาแก่ผู้ชายคุณให้อาหารเขาหนึ่งวันในขณะที่ถ้าคุณสอนเขาให้ปลาคุณจะให้อาหารเขาเพื่อชีวิต" เพราะคำถามของคุณนั้นกว้างมาก

1. การวิจัยแหล่งข้อมูลเปิด

Google สำหรับ "การเขียนโปรแกรมเชิงวัตถุประกอบ" แสดงรายการทรัพยากรที่เกี่ยวข้องที่แตกต่างกัน

เช่นการเขียนโปรแกรมเชิงวัตถุในการประกอบ Ethan J. Eldridge, 15 ธันวาคม 2011มาเป็นลิงค์ที่ 3 และดูดี

2. เรียนรู้จากโค้ดที่เขียนด้วยมือที่มีอยู่

คุณสามารถดูว่ามันทำงานอย่างไรโดยการศึกษาซอร์สโค้ดที่เขียนด้วยภาษาแอสเซมบลียอดนิยมบางภาษาที่มีการประกาศ OOP อย่างชัดเจนเช่น

3. เรียนรู้จากรูปแบบรหัสที่สร้างโดยคอมไพเลอร์

คุณสามารถดูว่ามันทำงานอย่างไรโดยการศึกษาไฟล์ภาษาแอสเซมบลีระดับกลางที่ผลิตโดยคอมไพเลอร์ OOP ที่คุณเลือก ทั้งคอมไพเลอร์ C ++ และ FreePascal สามารถกำหนดค่าเพื่อให้คุณสามารถดูว่าการถอดความรหัส OOP ระดับสูงลงในรหัสภาษาแอสเซมบลีเป็นอย่างไร

4. แก้ปริศนาด้วยสามัญสำนึกของคุณ

ตอนนี้มันสายเกินไปที่คุณจะรู้คำแนะนำจากคำตอบอื่น ๆ แล้ว แต่ก่อนที่อินเทอร์เน็ตจะง่ายต่อการค้นหาและก่อนที่จะมีเว็บไซต์ที่คุณสามารถรับคำตอบได้โดยไม่ต้องใช้ความพยายามใด ๆ ภายในไม่กี่ชั่วโมงฟรีจากอาสาสมัครบางคนที่เรียนรู้วิธีการที่ยากวิธีเดียวที่ทุกคนสามารถใช้ได้ฟรีคือ

ถามตัวเองว่า: "ฉันจะใช้มันอย่างไร"

บ่อยครั้งหลังจากกระบวนการคิดพื้นหลังหลายวันทำงานในใจของคุณและหลังจากทิ้งแบบร่างกระดาษหลายชุดคุณจะพบว่าโซลูชันที่คุณคิดขึ้นนั้นคล้ายกับโซลูชันที่โปรแกรมเมอร์คนอื่น ๆ ใช้งานและดำเนินการไปแล้ว


ตอนนี้เป็นความเห็นคำตอบของฉันตามไม่ได้ตอบคำถามของ OP โดยตรงและผู้ใช้ระดับสูงระดับสูงสามารถลงคะแนนฉันได้อย่างอิสระ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.