Web Technology Web Design Web Programming PHP Wordpress
Value and Reference Types
ก่อนอื่นต้องเข้าใจก่อนว่าอ็อบเจ็คที่สร้างจาก structs จะเป็น value types(รวมถึง Primitive types เช่น int, float, bool and char ด้วย) NFWจะจองหน่วยความจำไว้แหล่งเดียว(stack) ส่วนอ็อบเจ็คที่สร้างจาก classes จะเป็น reference types NFWจะจองหน่วยความจำไว้ 2 แหล่ง คือ heap สำหรับเก็บ อ็อบเจ็ค และ stack สำหรับเก็บตัวอ้างอิง
ตัวอย่างต่อไปนี้จะคือการประกาศอ็อบเจ็คโดยสมมติว่า Point คือ struct และ Form คือ class
โคดบรรทัดแรก ระบบจะทำการจองหน่วยความจำให้ p1 แหล่งเดียว แต่โคดบรรทัดที่สอง ระบบจองหน่วยความจำให้ f1 สองแหล่งด้วยกัน แหล่งที่หนึ่งสำหรับเก็บ Form อ็อบเจ็ค และ แหล่งที่สองสำหรับเก็บตัวอ้างอิง เพื่อให้เข้าใจได้ง่ายขึ้นเราจะเขียนโคดแบบยาวหน่อยดังนี้
ถ้าเราคัดลอกอ็อบเจ็คไปเก็บที่ตัวแปรใหม่ดังนี้
ข้อมูลจาก p1 จะถูกคัดลอกมาใส่ไว้ใน p2 อย่างอิสระโดยแยก fields กันอย่างชัดเจน แต่สำหรับ f2 จะถูกคัดลอกมาเฉพาะตัวอ้างอิงเท่านั้น ดังนั้น ทั้ง f1 และ f2 จะชี้ไปที่อ็อบเจ็ค(ใน heap)ตัวเดียวกัน
ในการส่งค่าพารามิเตอร์ไปให้เมธอด ในภาษา c# พารามิเตอร์แบบ value-type จะส่งเป็น value ไปให้เมธอด หมายความว่า ข้อมูลที่ส่งไปจะเป็นการส่งข้อมูลจริง ๆ (p2 ถูกคัดลอก) ขณะที่พารามิเตอร์แบบ reference-types จะส่งตัวอ้างอิงไปให้เมธอด ดังตัวอย่าง
การใส่ค่าให้ f เป็น null จะไม่มีผลกระทบต่อ myForm เพราะ f คัดลอกมาเฉพาะตัวอ้างอิง ไม่ได้คัดลอกอ็อบเจ็คมาเก็บไว้
การจัดสรรหน่วยความจำ
CLR (Common Language Runtime) จะจัดสรรหน่วยความจำให้อ็อบเจ็ค 2 แหล่งด้วยกัน คือ stack และ heap
stack มีโครงสร้างข้อมูลที่ใช้หลักการ เข้าก่อนออกหลัง เมื่อเมธอดถูกเรียก CLR จะทำการจองเนื้อที่ในหน่วยความจำใน stack บนสุด จากนั้นเมธอดก็ ผลัก(push)ข้อมูลเข้าไปใน stack เมื่อการใช้งานเมธอดเสร็จสมบูรณ์ CLR ก็จะลบหน่วยความจำที่จองออก(popping) ในทางตรงกันข้าม heap จะใช้โครงสร้างข้อมูลแบบ linklist ที่มีการจัดเก็บข้อมูลใน heap ที่ CLR ได้กันไว้จากหน่วยความจำ(แรม)ไว้ก่อนแล้ว ส่วนการจัดการกับหน่วยความจำที่ไม่มีความจำเป็นหรือไม่ได้ใช้แล้วจะมี garbage collector คอยจัดการเพื่อคืนหน่วยความจำให้ใน heap ให้ว่าง
เพื่อแสดงให้เห็นถึงการทำงานของ stack และ heap ให้พิจารณาตัวอย่างต่อไปนี้
ในเมธอดนี้ เราสร้างตัวแปรท้องถิ่นที่เก็บตัวอ้างอิงเพื่ออ้างอิงไปยังอ็อบเจ็ค ตัวแปรท้องถิ่นถูกจัดเก็บใน stack ขณะที่ อ็อบเจ็คถูกจัดเก็บไว้ใน heap

stack มีไว้สำหรับเก็บ
heap มีไว้สำหรับเก็บ
ตัวอย่าง Windows Forms
ตัวอย่างนี้เป็นตัวอย่างการสร้างวินโดว์ฟอร์มในวินโดว์แอพพลิเคชั่น เราจะใช้ types ของ 2 ตัว
ทั้งสองจะอยู่ในเนมสเปส System.Drawing

ต่อจากนั้นสร้างฟอร์มขึ้นมา Form จะอยู่ในเนมสเปส System.Windows.Forms
ใส่ค่า ขนาด และ แบบอักษร ให้ฟอร์มด้วยการถ่ายค่าจากอ็อบเจ็ค s และ f ให้กับฟอร์ม properties
ในหน่วยความจำจะมีลักษณะดังรูป

จะเห็นได้ว่า s จะถูกคัดลอกเนื้อหามาไว้ใน Form อ็อบเจ็คเลย ส่วน f จะถูกคัดลองตัวอ้างอิงมา หมายความว่า ถ้า s ถูกเปลี่ยนค่าจะไม่มีผลกระทบต่อ form แต่ถ้า f ถูกเปลี่ยนค่า(ที่ตัวมันอ้างถึง) form ก็จะต้องเปลี่ยนไปด้วย
callmebird is Bird's weblog. Bird is blogger who spend life for programming and web technology. This weblog provide web technology article for anyone who love web programming and web design.
Leave a reply