Bagikan melalui


Menyalin konstruktor dan menyalin operator penugasan (C++)

Catatan

Mulai dari C++11, dua jenis penugasan didukung dalam bahasa: penugasan salin dan pindahkan penetapan. Dalam artikel ini "penugasan" berarti penugasan salin kecuali dinyatakan sebaliknya secara eksplisit. Untuk informasi tentang pemindahan penetapan, lihat Memindahkan Konstruktor dan Memindahkan Operator Penugasan (C++).

Operasi penugasan dan operasi inisialisasi menyebabkan objek disalin.

  • Penugasan: Saat satu nilai objek ditetapkan ke objek lain, objek pertama disalin ke objek kedua. Jadi, kode ini menyalin nilai b ke dalam a:

    Point a, b;
    ...
    a = b;
    
  • Inisialisasi: Inisialisasi terjadi saat Anda mendeklarasikan objek baru, saat Anda meneruskan argumen fungsi menurut nilai, atau saat Anda mengembalikan berdasarkan nilai dari fungsi.

Anda dapat menentukan semantik "salin" untuk objek jenis kelas. Misalnya, pertimbangkan kode ini:

TextFile a, b;
a.Open( "FILE1.DAT" );
b.Open( "FILE2.DAT" );
b = a;

Kode sebelumnya dapat berarti "salin konten FILE1. DAT ke FILE2. DAT" atau itu bisa berarti "abaikan FILE2. DAT dan buat b handel kedua untuk FILE1.DAT." Anda harus melampirkan semantik penyalinan yang sesuai ke setiap kelas, sebagai berikut:

  • Gunakan operator operator= penugasan yang mengembalikan referensi ke jenis kelas dan mengambil satu parameter yang diteruskan oleh const referensi—misalnya ClassName& operator=(const ClassName& x);.

  • Gunakan konstruktor salinan.

Jika Anda tidak mendeklarasikan konstruktor salinan, kompilator menghasilkan konstruktor salinan yang bijaksana untuk Anda. Demikian pula, jika Anda tidak mendeklarasikan operator penugasan salinan, kompilator menghasilkan operator penugasan salinan yang bijaksana untuk Anda. Mendeklarasikan konstruktor salinan tidak menekan operator penetapan salinan yang dihasilkan kompilator, dan sebaliknya. Jika Anda menerapkan salah satu dari keduanya, kami sarankan Anda mengimplementasikan yang lain juga. Ketika Anda mengimplementasikan keduanya, arti kodenya jelas.

Konstruktor salin mengambil argumen jenis ClassName&, di mana ClassName adalah nama kelas. Contoh:

// spec1_copying_class_objects.cpp
class Window
{
public:
    Window( const Window& );            // Declare copy constructor.
    Window& operator=(const Window& x); // Declare copy assignment.
    // ...
};

int main()
{
}

Catatan

Buat jenis argumen const ClassName& konstruktor salinan jika memungkinkan. Ini mencegah konstruktor salinan secara tidak sengaja mengubah objek yang disalin. Ini juga memungkinkan Anda menyalin dari const objek.

Konstruktor salinan yang dihasilkan compiler

Konstruktor salinan yang dihasilkan kompilator, seperti konstruktor salinan yang ditentukan pengguna, memiliki argumen tunggal jenis "referensi ke nama kelas." Pengecualian adalah ketika semua kelas dasar dan kelas anggota memiliki konstruktor salinan yang dinyatakan sebagai mengambil argumen tunggal dari jenis constnama kelas&. Dalam kasus seperti itu, argumen konstruktor salinan yang dihasilkan kompilator juga const.

Ketika jenis argumen ke konstruktor salinan tidak const, inisialisasi dengan menyalin const objek menghasilkan kesalahan. Kebalikannya tidak benar: Jika argumen adalah const, Anda dapat menginisialisasi dengan menyalin objek yang bukan const.

Operator penugasan yang dihasilkan kompilator mengikuti pola yang sama untuk const. Mereka mengambil satu argumen jenis ClassName& kecuali operator penugasan di semua kelas dasar dan anggota mengambil argumen jenis const ClassName&. Dalam hal ini, operator penugasan yang dihasilkan untuk kelas mengambil const argumen.

Catatan

Ketika kelas dasar virtual diinisialisasi oleh konstruktor salinan, baik yang dihasilkan kompilator atau yang ditentukan pengguna, kelas tersebut hanya diinisialisasi sekali: pada saat dibangun.

Implikasinya mirip dengan konstruktor salinan. Ketika jenis argumen bukan const, penetapan dari const objek menghasilkan kesalahan. Pembalikan tidak benar: Jika const nilai ditetapkan ke nilai yang bukan const, penetapan berhasil.

Untuk informasi selengkapnya tentang operator penugasan yang kelebihan beban, lihat Penugasan.