Menu
CoddyTech

Konstruktor Salin

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

Constructor salin membuat object baru sebagai salinan dari object yang sudah ada. Constructor ini dipanggil saat kamu menginisialisasi object dari object lain dengan tipe yang sama, mengirimkan object berdasarkan nilai, atau mengembalikan object berdasarkan nilai.

Konstruktor salinan menerima referensi const ke objek dari class yang sama. Parameter ini harus berupa referensi: meneruskan other berdasarkan nilai akan memerlukan salinan itu sendiri, sehingga konstruktor salinan akan terus dipanggil tanpa henti. Parameter ini bertipe const karena membuat salinan tidak boleh mengubah objek asli:

class Player {
    std::string name;
    int health;
public:
    Player(std::string n, int h) : name(n), health(h) {}
    
    // Konstruktor penyalin
    Player(const Player& other) {
        name = other.name;
        health = other.health;
    }
};

Player original("Hero", 100);
Player copy = original;    // Konstruktor penyalin dipanggil
Player another(original);  // Juga memanggil konstruktor penyalin

Jika kamu tidak mendefinisikan konstruktor salinan, compiler akan membuatnya dan melakukan salinan dangkal: setiap nilai anggota disalin secara langsung. Cara ini berfungsi dengan baik untuk tipe sederhana, tetapi menimbulkan masalah saat class-mu mengelola memori dinamis.

class Buffer {
    int* data;
    size_t size;
public:
    Buffer(size_t s) : size(s) {
        data = new int[size];
    }
    
    // Konstruktor penyalinan mendalam
    Buffer(const Buffer& other) : size(other.size) {
        data = new int[size];              // Alokasikan memori baru
        for (size_t i = 0; i < size; i++)
            data[i] = other.data[i];       // Salin isinya
    }
    
    ~Buffer() { delete[] data; }
};

Tanpa konstruktor salin khusus, kedua objek akan menunjuk ke memori yang sama. Saat salah satunya dihancurkan, objek lainnya akan memiliki pointer yang menggantung. Salinan mendalam mengalokasikan memori baru dan menyalin data sebenarnya, sehingga setiap objek memiliki sumber dayanya sendiri.

challenge icon

Tantangan

Mudah

Mari buat sistem riwayat pesan yang menunjukkan pentingnya penyalinan mendalam saat class-mu mengelola memori dinamis. Kamu akan membuat class MessageLog yang menyimpan pesan dalam array yang dialokasikan secara dinamis, lalu menerapkan konstruktor salin yang tepat agar setiap salinan memiliki memorinya sendiri yang independen.

Kamu akan membuat dua file untuk mengatur kodemu:

  • MessageLog.h: Definisikan class MessageLog yang mengelola kumpulan pesan menggunakan memori dinamis. Class-mu harus memiliki:
    • Anggota private: pointer ke array string untuk menyimpan pesan, capacity untuk jumlah maksimum pesan, dan count untuk jumlah pesan saat ini
    • Konstruktor berparameter yang menerima kapasitas, mengalokasikan array di heap, dan menginisialisasi count ke 0
    • Konstruktor salin yang melakukan penyalinan mendalam: mengalokasikan memori baru dan menyalin semua pesan dari object sumber
    • Destruktor yang membebaskan memori yang dialokasikan dan mencetak "MessageLog destroyed"
    • Method addMessage(string msg) yang menambahkan pesan jika masih ada ruang
    • Method getCount() yang mengembalikan jumlah pesan saat ini
    • Method getMessage(int index) yang mengembalikan pesan pada indeks yang diberikan
  • main.cpp: Tunjukkan bahwa konstruktor salinmu membuat salinan yang independen. Baca nilai kapasitas dan dua pesan dari input, lalu:
    • Buat MessageLog bernama original dengan kapasitas dari input
    • Tambahkan kedua pesan ke original
    • Buat salinan bernama backup menggunakan konstruktor salin
    • Tambahkan pesan ketiga "New message" hanya ke original
    • Cetak "Original count: <count>"
    • Cetak "Backup count: <count>"
    • Cetak semua pesan dari backup, satu pesan per baris

Format inputnya adalah:

  • Baris pertama: kapasitas (integer)
  • Baris kedua: pesan pertama (string)
  • Baris ketiga: pesan kedua (string)

Jika penyalinan mendalammu diterapkan dengan benar, backup seharusnya memiliki 2 pesan, sedangkan original memiliki 3 pesan. Ini membuktikan bahwa keduanya memiliki memori yang independen. Tanpa konstruktor salin yang tepat, keduanya akan berbagi array yang sama dan perubahan pada salah satunya akan memengaruhi yang lain!

Sertakan file header-mu di main.cpp menggunakan #include "MessageLog.h".

Coba sendiri

#include <iostream>
#include <string>
#include "MessageLog.h"
using namespace std;

int main() {
    // Baca input
    int capacity;
    cin >> capacity;
    cin.ignore();
    
    string msg1, msg2;
    getline(cin, msg1);
    getline(cin, msg2);

    // TODO: Buat MessageLog bernama 'original' dengan kapasitas dari input

    // TODO: Tambahkan kedua pesan ke original

    // TODO: Buat salinan bernama 'backup' menggunakan konstruktor penyalin

    // TODO: Tambahkan "New message" hanya ke original

    // TODO: Cetak "Original count: <count>"

    // TODO: Cetak "Backup count: <count>"

    // TODO: Cetak semua pesan dari backup, satu per baris

    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