Menu
CoddyTech

Konstruktor Pindah

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 21 dari 104.

Move constructor memindahkan sumber daya dari object sementara, bukan menyalinnya. Sementara copy constructor menggandakan data, move constructor "mengambil" sumber daya tersebut, sehingga object sumber tetap berada dalam keadaan valid tetapi kosong. Hal ini menghindari penyalinan mendalam yang mahal saat object sumber akan segera dihapus.

Konstruktor pemindahan menerima referensi rvalue, yang ditulis dengan &&:

class Buffer {
    int* data;
    size_t size;
public:
    Buffer(size_t s) : size(s), data(new int[s]) {}
    
    // Konstruktor pemindahan
    Buffer(Buffer&& other) noexcept {
        data = other.data;       // Ambil alih pointer
        size = other.size;
        other.data = nullptr;    // Biarkan sumber dalam keadaan valid
        other.size = 0;
    }
    
    ~Buffer() { delete[] data; }
};

Perbedaan utama dari menyalin: kita tidak mengalokasikan memori baru. Kita cukup mengambil alih memori yang sudah ada dan mengatur pointer sumber ke nullptr agar destruktornya tidak menghapus data kita.

Konstruktor move dipanggil saat melakukan inisialisasi dari object sementara atau saat menggunakan std::move():

Buffer createBuffer() {
    return Buffer(1000);    // Konstruktor move digunakan (nilai kembalian)
}

Buffer b1(1000);
Buffer b2(std::move(b1));   // Move eksplisit, b1 sekarang kosong

Tandai move constructor sebagai noexcept jika memungkinkan. Ini memberi tahu compiler bahwa operasi tersebut tidak akan melempar exception, sehingga memungkinkan optimasi penting pada container seperti std::vector.

challenge icon

Tantangan

Mudah

Mari buat sistem paket data yang menunjukkan cara move constructor memindahkan kepemilikan resource secara efisien. Kamu akan membuat class DataPacket yang mengelola array byte yang dialokasikan secara dinamis, lalu mengimplementasikan move constructor yang "mencuri" data alih-alih menyalinnya.

Kamu akan membuat dua file untuk mengatur kodemu:

  • DataPacket.h: Definisikan class DataPacket yang mengelola payload data integer. Class-mu harus memiliki:
    • Member private: pointer ke array integer (payload), size untuk jumlah elemen, dan packetId (string) untuk mengidentifikasi paket
    • Constructor berparameter yang menerima ID paket dan ukuran, mengalokasikan array, lalu mengisinya dengan nilai dari 0 hingga size-1. Cetak "Packet <id> created with size <size>"
    • Move constructor bertanda noexcept yang memindahkan kepemilikan payload dari object sumber. Cetak "Packet <id> moved". Pastikan object sumber tetap dalam keadaan kosong yang valid (nullptr, size 0)
    • Destructor yang membebaskan memori jika pointer tidak null, lalu mencetak "Packet <id> destroyed"
    • Method getSize() yang mengembalikan size saat ini
    • Method getId() yang mengembalikan ID paket
    • Method getSum() yang mengembalikan jumlah semua elemen dalam payload (kembalikan 0 jika payload null)
  • main.cpp: Tunjukkan move construction dengan membaca ID paket dan size dari input. Lalu:
    • Buat DataPacket bernama original dengan nilai input
    • Cetak "Original - ID: <id>, Size: <size>, Sum: <sum>"
    • Buat paket baru bernama transferred dengan memindahkan dari original menggunakan std::move()
    • Cetak "After move:"
    • Cetak "Original - ID: <id>, Size: <size>, Sum: <sum>"
    • Cetak "Transferred - ID: <id>, Size: <size>, Sum: <sum>"

Format inputnya adalah:

  • Baris pertama: ID paket (string)
  • Baris kedua: size (integer)

Setelah pemindahan, paket original harus memiliki size 0 dan sum 0 (karena datanya telah dipindahkan), sedangkan paket transferred harus memiliki semua data semula. Ini menunjukkan cara move semantics menghindari deep copy yang mahal dengan hanya memindahkan kepemilikan pointer.

Sertakan header file-mu di main.cpp menggunakan #include "DataPacket.h" dan jangan lupa menyertakan <utility> untuk std::move().

Coba sendiri

#include <iostream>
#include <string>
#include <utility>
#include "DataPacket.h"

using namespace std;

int main() {
    // Baca input
    string packetId;
    int size;
    cin >> packetId;
    cin >> size;

    // TODO: Buat DataPacket bernama 'original' dengan nilai input

    // TODO: Cetak "Original - ID: <id>, Size: <size>, Sum: <sum>"

    // TODO: Buat paket baru bernama 'transferred' dengan memindahkan dari original
    // Petunjuk: Gunakan std::move()

    // TODO: Cetak "After move:"

    // TODO: Cetak "Original - ID: <id>, Size: <size>, Sum: <sum>"

    // TODO: Cetak "Transferred - ID: <id>, Size: <size>, Sum: <sum>"

    return 0;
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler C++ online