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.
Tantangan
MudahMari 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 classDynamicStringyang menyimpan string bergaya C menggunakan memori dinamis. Class-mu harus mengelola:- Pointer
char*privat untuk data string size_tprivat 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).- Pointer
main.cpp: Baca tiga string dari input (masing-masing pada baris terpisah). Buat tiga objectDynamicString:str1dengan input pertama,str2dengan input kedua, danstr3dengan input ketiga.Demonstrasikan operator assignment-mu:
- Cetak keadaan awal ketiga string
- Gunakan copy assignment:
str1 = str2; - Cetak str1 dan str2 setelah copy assignment (keduanya harus memiliki konten yang sama)
- Gunakan move assignment:
str2 = std::move(str3); - 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;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar-Dasar OOP
File EksternalBuild dan Kompilasi C++File Header dan File SourceNamespace dan CakupanPengantar OOP dalam C++class vs objectPointer 'this'method (Fungsi Anggota)Atribut (Anggota Data)Dasar Ctor dan DtorRingkasan: Kalkulator Sederhana4Properti class
Anggota instance vs staticGetter dan setterFungsi anggota constKata kunci mutableMethod dan variabel staticFungsi dan class friendRangkuman, Pengelola Rekening Bank7Pewarisan
Pewarisan DasarTingkat Akses pada PewarisanUrutan Pemanggilan Ctor & DtorPenimpaan methodFungsi Virtual & VTablePewarisan BergandaPewarisan VirtualRangkuman: Hierarki Karyawan2Manajemen Memori
Memori Stack vs HeapPointer dan ReferenceMemori Dinamis (new/delete)Smart Pointer di C++RAII di C++Rangkuman: Pengelola Array Dinamis5Enkapsulasi
Penentu Akses dalam C++Penentu Akses secara MendalamPenyembunyian Informasistruct vs classNested dan Inner classRangkuman, Sistem Catatan Siswa8Polimorfisme
Polimorfisme saat Compile vs RuntimeOverloading FungsiMeninjau Kembali Fungsi VirtualFungsi Virtual MurniKelas AbstrakDesain Interface di C++Casting Dinamis & RTTIRangkuman: Kalkulator Bentuk3Konstruktor & Destruktor
Konstruktor DefaultKonstruktor BerparameterKonstruktor SalinKonstruktor PindahDaftar Inisialisasi KonstruktorKonstruktor DelegasiKupas Tuntas DestruktorAturan Tiga, Lima, dan NolRangkuman: class String6Overloading Operator
Pengantar Overloading OperatorOverloading Operator AritmetikaOverloading Operator PerbandinganOperator StreamOverloading Operator PenugasanOverloading Operator [] dan ()Operator Konversi TipeRingkasan, class Matrix9Template
Template FungsiTemplate classSpesialisasi TemplateTemplate VariadikDasar SFINAE & Type TraitsRangkuman, Container GenerikLatihan sendiri: Compiler C++ online