ฟังก์ชันพิเศษสำหรับสมาชิก
ในภาษาการเขียนโปรแกรมC++ ฟังก์ชันสมาชิกพิเศษ[ 1 ]คือฟังก์ชันที่คอมไพเลอร์จะสร้างขึ้นโดยอัตโนมัติหากมีการใช้งาน แต่ไม่ได้ประกาศอย่างชัดเจนโดยโปรแกรมเมอร์ ฟังก์ชันสมาชิกพิเศษที่สร้างขึ้นโดยอัตโนมัติ ได้แก่:
- คอนสตรัคเตอร์เริ่มต้นหากไม่มีการประกาศคอนสตรัคเตอร์อื่นไว้โดยชัดเจน
- คอนสตรัคเตอร์สำเนาหากไม่มีการประกาศคอนสตรัคเตอร์แบบย้ายและตัวดำเนินการกำหนดค่าแบบย้ายอย่างชัดเจน
- หากไม่มีการประกาศคอน สตรัคเตอร์แบบคัดลอก ตัวดำเนินการกำหนดค่าแบบคัดลอก ตัวดำเนินการกำหนดค่าแบบย้าย และตัวทำลายอย่างชัดเจน ให้ใช้ตัวดำเนินการย้าย (Move assignment operator)
- ตัวดำเนินการกำหนดค่าแบบคัดลอกหากไม่มีการประกาศตัวสร้างแบบย้ายและตัวดำเนินการกำหนดค่าแบบย้ายอย่างชัดเจน
- หากมีการประกาศตัวทำลาย (destructor) การสร้างตัวดำเนินการกำหนดค่าสำเนา (copy assignment operator) นั้นไม่แนะนำอีกต่อไป
- ตัวดำเนินการกำหนดค่าแบบย้ายหากไม่มีการประกาศตัวสร้างสำเนา ตัวดำเนินการกำหนดค่าสำเนา ตัวสร้างแบบย้าย และตัวทำลายอย่างชัดเจน
- ตัวทำลาย
ในกรณีเหล่านี้ ฟังก์ชันที่คอมไพเลอร์สร้างขึ้นจะดำเนิน การกับ สมาชิกแต่ละตัวตัวอย่างเช่น ฟังก์ชันทำลายที่คอมไพเลอร์สร้างขึ้นจะทำลายแต่ละซับออบเจ็กต์ (คลาสพื้นฐานหรือสมาชิก) ของออบเจ็กต์นั้น
ฟังก์ชันที่สร้างโดยคอมไพเลอร์จะเป็นpublicแบบไม่ใช่เสมือน[ 3 ]และตัวสร้างสำเนาและตัวดำเนินการกำหนดค่าจะได้รับconst&พารามิเตอร์ (และไม่ใช่รูปแบบทางกฎหมายทางเลือก ) [ 4 ]
ในC++03ก่อนการนำmove semantics มาใช้ (ใน C++11) ฟังก์ชันสมาชิกพิเศษประกอบด้วย: [ 5 ]
- คอนสตรัคเตอร์เริ่มต้น (หากไม่มีการประกาศคอนสตรัคเตอร์อื่นไว้โดยชัดเจน)
- ตัวสร้างสำเนา
- ผู้ดำเนินการมอบหมายสำเนา
- ตัวทำลาย
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงให้เห็นคลาสสองคลาส: Explicitคลาสหนึ่งที่ประกาศฟังก์ชันสมาชิกพิเศษทั้งหมดไว้อย่างชัดเจน และอีกคลาสหนึ่งคือ คลาสแบบไม่ระบุฟังก์ชันสมาชิก (Implicit ) ซึ่งไม่มีการประกาศฟังก์ชันสมาชิกพิเศษใดๆ ไว้เลย
import std ;โดยใช้std :: string ;คลาสExplicit { private : string message ; public : Explicit () { std :: println ( "Default constructor {}" ); }explicit Explicit ( string message ) : message { std :: move ( message )} { std :: println ( "Non-default constructor {}" , message ); }Explicit ( const Explicit & other ) { std :: println ( "Copy constructor {}" , message ); * this = other ; // เรียกใช้ตัวดำเนินการกำหนดค่าแบบคัดลอก}Explicit & operator = ( const Explicit & other ) { std :: println ( "คัดลอกตัวดำเนินการกำหนดค่า {}" , message ); if ( this != & other ) { message = other . message ; } return * this ; }Explicit ( Explicit && other ) noexcept { std :: println ( "Move constructor {}" , message ); * this = std :: move ( other ); // เรียกใช้ตัวดำเนินการกำหนดค่าแบบย้าย}Explicit & operator = ( Explicit && other ) noexcept { std :: println ( "Move assignment operator {}" , message ); if ( this != & other ) { message = std :: move ( other . message ); } return * this ; }~ Explicit () { std :: println ( "Destructor {}" , message ); } };class Implicit : public Explicit { private : Explicit member ; public : void spew () { std :: println ( "Implicit({}, {})" , message , member . message ); } };ลายเซ็น
ต่อไปนี้คือลายเซ็นของฟังก์ชันสมาชิกพิเศษ:
| การทำงาน | ไวยากรณ์สำหรับคลาสX |
|---|---|
| คอนสตรัคเตอร์เริ่มต้น | X(); |
| ตัวสร้างสำเนา | X(const X& other); |
| ย้ายคอนสตรัคเตอร์ | X(X&& other); |
| ผู้ดำเนินการมอบหมายสำเนา | X& operator=(const X& other); |
| ผู้ดำเนินการมอบหมายงานย้าย | X& operator=(X&& other); |
| ตัวทำลาย | ~X(); |