Menu
CoddyTech

Overloading Operator Penugasan

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

Operator penugasan salin (=) dipanggil saat kamu menugaskan satu object yang sudah ada ke object lainnya. Berbeda dengan constructor salin (yang membuat object baru), operator penugasan bekerja dengan object yang sudah ada dan mungkin memiliki sumber daya yang perlu dibersihkan terlebih dahulu.

class Buffer {
    int* data;
    size_t size;
    
public:
    Buffer(size_t s) : size(s), data(new int[s]) {}
    ~Buffer() { delete[] data; }
    
    Buffer& operator=(const Buffer& other) {
        if (this != &other) {              // 1. Periksa penugasan ke diri sendiri
            delete[] data;                  // 2. Bersihkan sumber daya yang sudah ada
            size = other.size;              // 3. Salin data
            data = new int[size];
            for (size_t i = 0; i < size; ++i)
                data[i] = other.data[i];
        }
        return *this;                       // 4. Kembalikan *this
    }
};

Pemeriksaan penugasan ke diri sendiri (this != &other) sangat penting. Tanpanya, b = b; akan menghapus data sebelum mencoba menyalinnya, sehingga menyebabkan perilaku yang tidak terdefinisi.

Operator ini mengembalikan *this melalui referensi agar kamu dapat merangkai operasi seperti a = b = c;. Ini sesuai dengan perilaku tipe bawaan.

Untuk class yang mengelola resource, kamu sering kali akan mengimplementasikan operator penugasan salin dan pindah:

Buffer& operator=(Buffer&& other) noexcept {
    if (this != &other) {
        delete[] data;           // Bersihkan sumber daya saat ini
        data = other.data;       // Ambil alih sumber daya
        size = other.size;
        other.data = nullptr;    // Biarkan sumber tetap dalam keadaan valid
        other.size = 0;
    }
    return *this;
}

Operator penugasan pemindahan memindahkan kepemilikan, bukan menyalin, sehingga operasi seperti vec[0] = createBuffer(); menjadi jauh lebih efisien.

challenge icon

Tantangan

Mudah

Mari buat class DynamicString yang mengelola array karakter yang dialokasikan secara dinamis dan menangani assignment antarobjek yang sudah ada dengan benar. Ini adalah skenario praktis saat kamu perlu memindahkan data string dengan aman dari satu object ke object lain tanpa kebocoran memori atau pointer yang menggantung.

Kamu akan membuat dua file untuk mengatur kodemu:

  • DynamicString.h: Definisikan class DynamicString yang menyimpan string bergaya C menggunakan memori dinamis. Class-mu harus mengelola:
    • Pointer char* privat untuk data string
    • size_t privat untuk panjang string
    • Constructor yang menerima const char* dan membuat salinan mendalam
    • Destructor yang membebaskan memori yang dialokasikan dengan benar
    • Operator copy assignment yang melakukan salinan mendalam dengan perlindungan terhadap assignment ke diri sendiri
    • Operator move assignment yang memindahkan kepemilikan secara efisien
    • Method c_str() yang mengembalikan string internal (const)
    • Method length() yang mengembalikan panjang string (const)

    Operator copy assignment-mu harus mengikuti empat langkah penting: periksa apakah terjadi assignment ke diri sendiri, bersihkan resource yang ada, salin data baru, lalu kembalikan *this. Operator move assignment harus mengambil pointer dari sumber dan membiarkan sumber dalam keadaan kosong yang valid (nullptr dengan panjang 0).

  • main.cpp: Baca tiga string dari input (masing-masing pada baris terpisah). Buat tiga object DynamicString: str1 dengan input pertama, str2 dengan input kedua, dan str3 dengan input ketiga.

    Demonstrasikan operator assignment-mu:

    1. Cetak keadaan awal ketiga string
    2. Gunakan copy assignment: str1 = str2;
    3. Cetak str1 dan str2 setelah copy assignment (keduanya harus memiliki konten yang sama)
    4. Gunakan move assignment: str2 = std::move(str3);
    5. Cetak str2 setelah move assignment, serta panjang str3 (seharusnya 0 setelah dipindahkan)

    Format output:

    Initial:
    str1: <value>
    str2: <value>
    str3: <value>
    After copy (str1 = str2):
    str1: <value>
    str2: <value>
    After move (str2 = std::move(str3)):
    str2: <value>
    str3 length: 0

Gunakan <cstring> untuk strlen dan strcpy. Tandai operator move assignment-mu sebagai noexcept. Sertakan <utility> di main.cpp untuk std::move. Jangan lupa header guard di file header-mu.

Coba sendiri

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

using namespace std;

int main() {
    // Baca tiga string dari input
    string input1, input2, input3;
    getline(cin, input1);
    getline(cin, input2);
    getline(cin, input3);

    // Buat tiga object DynamicString
    DynamicString str1(input1.c_str());
    DynamicString str2(input2.c_str());
    DynamicString str3(input3.c_str());

    // TODO: Tampilkan keadaan awal ketiga string
    // Format:
    // Initial:
    // str1: <value>
    // str2: <value>
    // str3: <value>

    // TODO: Gunakan penugasan salin: str1 = str2;

    // TODO: Tampilkan str1 dan str2 setelah penugasan salin
    // Format:
    // After copy (str1 = str2):
    // str1: <value>
    // str2: <value>

    // TODO: Gunakan penugasan pindah: str2 = std::move(str3);

    // TODO: Tampilkan str2 setelah pemindahan dan panjang str3
    // Format:
    // After move (str2 = std::move(str3)):
    // str2: <value>
    // str3 length: 0

    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