คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย
สร้างคอนสตรักเตอร์ย้ายและตัวดำเนินการกำหนดค่าแบบย้ายอย่างถูกต้อง
คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
สมาชิกพิเศษสองอย่าง
ตัวสร้างการย้าย และ ตัวดำเนินการกำหนดค่าแบบย้าย ทำให้คลาสของคุณรับช่วงการครอบครองทรัพยากรของอินสแตนซ์อื่นได้โดยไม่ต้องคัดลอก
ลายเซ็น
ทั้งสองอย่างรับการอ้างอิง rvalue ของชนิดเดียวกัน
class String {
public:
String(String&& other) noexcept; // move ctor
String& operator=(String&& other) noexcept; // move assign
};การเขียนตัวสร้างการย้าย
ขโมยทรัพยากรของต้นทาง แล้วปล่อยให้ต้นทางอยู่ในสถานะว่างที่ถูกต้อง
String(String&& other) noexcept
: data_(other.data_), size_(other.size_) {
other.data_ = nullptr;
other.size_ = 0;
}การเขียนตัวดำเนินการกำหนดค่าแบบย้าย
มีสามขั้นตอน: คืนทรัพยากรปัจจุบัน ขโมยทรัพยากรจากต้นทาง และปล่อยให้ต้นทางว่าง
String& operator=(String&& other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
size_ = other.size_;
other.data_ = nullptr;
other.size_ = 0;
}
return *this;
}เหตุใด noexcept จึงสำคัญ
กำกับการดำเนินการย้ายด้วย noexcept เมื่อทำได้ คอนเทนเนอร์มาตรฐานอย่าง std::vector จะใช้การย้ายเมื่อปรับขนาดก็ต่อเมื่อการย้ายนั้นเป็น noexcept มิฉะนั้นจะเปลี่ยนไปใช้การคัดลอกเพื่อความปลอดภัยต่อข้อยกเว้น
กฎห้าอย่าง
หากคุณเขียนสิ่งใดสิ่งหนึ่งจากห้าอย่างนี้ ให้พิจารณาทั้งห้าอย่าง:
- ตัวทำลาย
- ตัวสร้างการคัดลอก
- การกำหนดค่าแบบคัดลอก
- ตัวสร้างการย้าย
- การกำหนดค่าแบบย้าย
กฎศูนย์
ยิ่งไปกว่านั้น คือไม่ต้องเขียนสิ่งเหล่านี้เลย จัดเก็บสมาชิกเป็นชนิด RAII (เวกเตอร์ สตริง และพอยน์เตอร์อัจฉริยะ) ค่าเริ่มต้นที่คอมไพเลอร์สร้างขึ้นจะทำงานได้อย่างถูกต้องและมีประสิทธิภาพ
class Widget {
std::string name_;
std::vector<int> data_;
// No need for destructor, copy, or move — compiler does the right thing
};เมื่อคอมไพเลอร์สร้างการย้าย
คอมไพเลอร์จะสร้างสมาชิกการย้ายแบบค่าเริ่มต้นก็ต่อเมื่อ:
- ไม่มีตัวสร้างการคัดลอก การกำหนดค่าสำหรับการคัดลอก ตัวทำลาย หรือสมาชิกการย้ายที่ผู้ใช้ประกาศไว้
- สมาชิกและคลาสฐานทั้งหมดรองรับการย้ายด้วยตนเอง
การย้ายแบบค่าเริ่มต้นและการลบออก
คุณสามารถขอให้สร้างหรือห้ามการย้ายที่คอมไพเลอร์สร้างขึ้นได้อย่างชัดเจน
class Widget {
public:
Widget(Widget&&) = default;
Widget& operator=(Widget&&) = default;
// or
Widget(Widget&&) = delete;
};หลังการย้าย
ออบเจ็กต์ที่ถูกย้ายออกจะอยู่ในสถานะ ถูกต้องแต่ไม่ระบุแน่ชัด คุณสามารถ:
- ทำลายออบเจ็กต์นั้น
- กำหนดค่าใหม่ให้กับออบเจ็กต์นั้น
- เรียกการดำเนินการใด ๆ ที่ไม่มีเงื่อนไขก่อนหน้า เช่น size(), empty(), clear()
กรณีการใช้งาน
ความหมายเชิงการย้ายช่วยเพิ่มความเร็วให้กับ:
- การคืนค่าออบเจ็กต์ขนาดใหญ่ เมื่อ RVO ไม่ทำงาน
- การใส่ออบเจ็กต์ขนาดใหญ่ลงในคอนเทนเนอร์ เช่น push_back ของค่า rvalue
- การสร้างชนิดข้อมูลที่จัดการทรัพยากรด้วยตนเอง
ตรวจสอบความเข้าใจ
เหตุใดจึงควรทำเครื่องหมายตัวสร้างการย้ายและตัวดำเนินการกำหนดค่าการย้ายด้วย noexcept?
สรุป
ตัวสร้างการย้ายและตัวดำเนินการกำหนดค่าการย้ายจะขโมยทรัพยากรจากค่า rvalue ที่กำลังจะหมดอายุ ทำเครื่องหมายด้วย noexcept เพื่อเพิ่มความเร็วให้คอนเทนเนอร์ ปฏิบัติตามกฎห้าข้อ หรือที่ดีกว่านั้นคือกฎศูนย์ โดยประกอบชนิด RAII มาตรฐานเข้าด้วยกัน
คำถามที่พบบ่อย
บทเรียน “คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย”
สร้างคอนสตรักเตอร์ย้ายและตัวดำเนินการกำหนดค่าแบบย้ายอย่างถูกต้อง คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ความแตกต่างระหว่าง Lvalue กับ Rvalue
- รีเฟอเรนซ์ Rvalue และไวยากรณ์ &&
- std::move และ std::forward
- คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย