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 kosongTandai 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.
Tantangan
MudahMari 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 classDataPacketyang mengelola payload data integer. Class-mu harus memiliki:- Member private: pointer ke array integer (
payload),sizeuntuk jumlah elemen, danpacketId(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
noexceptyang 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)
- Member private: pointer ke array integer (
main.cpp: Tunjukkan move construction dengan membaca ID paket dan size dari input. Lalu:- Buat
DataPacketbernamaoriginaldengan nilai input - Cetak
"Original - ID: <id>, Size: <size>, Sum: <sum>" - Buat paket baru bernama
transferreddengan memindahkan darioriginalmenggunakanstd::move() - Cetak
"After move:" - Cetak
"Original - ID: <id>, Size: <size>, Sum: <sum>" - Cetak
"Transferred - ID: <id>, Size: <size>, Sum: <sum>"
- Buat
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;
}
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