0Pricing
C++ Academy · บทเรียน

คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย

สร้างคอนสตรักเตอร์ย้ายและตัวดำเนินการกำหนดค่าแบบย้ายอย่างถูกต้อง

คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ความแตกต่างระหว่าง Lvalue กับ Rvalue
  2. รีเฟอเรนซ์ Rvalue และไวยากรณ์ &&
  3. std::move และ std::forward
  4. คอนสตรักเตอร์ย้ายและการกำหนดค่าแบบย้าย
← กลับไปที่ C++ Academy