RAII di C++
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 16 dari 104.
RAII (Resource Acquisition Is Initialization) adalah idiom dasar C++ yang mengaitkan pengelolaan resource dengan masa hidup object. Gagasannya sederhana: dapatkan resource di constructor, lalu lepaskan di destructor.
Saat sebuah object dibuat, object tersebut memperoleh sumber daya apa pun yang dibutuhkannya. Saat object keluar dari cakupan, destructor-nya otomatis melepaskan sumber daya tersebut. Ini menjamin pembersihan meskipun terjadi exception.
class FileHandler {
std::FILE* file;
public:
FileHandler(const char* filename) {
file = std::fopen(filename, "r"); // Dapatkan sumber daya
}
~FileHandler() {
if (file) std::fclose(file); // Lepaskan sumber daya
}
};Dengan RAII, kamu tidak akan pernah lupa membersihkan:
void processFile() {
FileHandler handler("data.txt"); // Sumber daya diperoleh
// Gunakan file...
// Jika terjadi pengecualian di sini, destructor tetap berjalan!
} // Sumber daya dilepaskan secara otomatisSmart pointer adalah contoh sempurna penerapan RAII. unique_ptr memperoleh kepemilikan atas memori heap di constructor-nya dan menghapusnya di destructor-nya. Kamu sudah menggunakan RAII tanpa menyadarinya!
RAII berlaku untuk semua sumber daya: memori, handle file, koneksi jaringan, mutex, atau koneksi database. Dengan membungkus sumber daya dalam object, C++ memastikan pembersihan yang deterministik dan menghilangkan seluruh kategori bug seperti kebocoran dan handle yang menggantung.
Tantangan
MudahMari buat pengelola koneksi yang menunjukkan RAII dengan menangani siklus hidup koneksi seperti jaringan secara otomatis. Saat koneksi dibuat, koneksi itu harus "open", dan saat keluar dari cakupan, koneksi itu harus otomatis "close": tidak perlu pembersihan manual!
Kamu akan membuat dua file untuk mengatur kodemu:
Connection.h: Definisikan classConnectionyang mengelola resource koneksi menggunakan prinsip RAII. Class ini harus memiliki:- Atribut privat
connectionId(string) untuk mengidentifikasi koneksi - Atribut privat
isOpen(bool) untuk melacak status koneksi - Konstruktor yang menerima ID koneksi, menetapkan
isOpenke true, dan mencetak"Opening connection: <id>" - Destruktor yang memeriksa apakah koneksi terbuka, menutupnya dengan menetapkan
isOpenke false, dan mencetak"Closing connection: <id>" - Method
send(string message)yang mencetak"[<id>] Sending: <message>"jika koneksi terbuka - Method
getId()yang mengembalikan ID koneksi
- Atribut privat
main.cpp: Tunjukkan cara RAII memastikan pembersihan otomatis dengan membaca ID koneksi dan pesan dari input. Lalu:- Buat cakupan menggunakan kurung kurawal
{ } - Di dalam cakupan itu, buat object
Connectiondi stack dengan ID dari input - Gunakan koneksi untuk mengirim pesan dari input
- Akhiri cakupan tersebut, koneksi akan otomatis ditutup
- Setelah cakupan berakhir, cetak
"Connection out of scope"
- Buat cakupan menggunakan kurung kurawal
Keunggulan RAII adalah kamu tidak perlu mengingat untuk menutup koneksi: destruktor menanganinya secara otomatis saat object keluar dari cakupan. Pola ini mencegah kebocoran resource, bahkan jika terjadi sesuatu yang tidak terduga di kodemu.
Sertakan file header-mu di main.cpp menggunakan #include "Connection.h".
Coba sendiri
#include <iostream>
#include <string>
#include "Connection.h"
using namespace std;
int main() {
string connectionId;
string message;
// Baca input
cin >> connectionId;
cin.ignore();
getline(cin, message);
// TODO: Buat scope menggunakan kurung kurawal { }
// Di dalam scope:
// - Buat object Connection di stack dengan connectionId
// - Gunakan koneksi untuk mengirim pesan
// Biarkan scope berakhir (destructor akan dipanggil secara otomatis)
// TODO: Setelah scope berakhir, cetak "Connection out of scope"
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