Kita telah menempuh jarak yang jauh di Section ini: dari dua wilayah memori, melewati new/delete dan memory leak, hingga tiga smart pointer dan jaminan exception. Semua itu bermuara pada satu kesimpulan yang mungkin terdengar kontradiktif: cara terbaik mengelola memori di C++ adalah dengan hampir tidak pernah mengelolanya secara manual. Pustaka standar sudah menyediakan alat RAII untuk hampir setiap kebutuhan — container, string, dan smart pointer — sehingga pekerjaan alokasi dan pelepasan bisa diserahkan ke mereka. Chapter penutup ini merangkum aturan-aturan itu menjadi kebiasaan menulis yang bisa kita pakai setiap hari, lalu membuktikannya dengan program utuh yang tidak memuat satu new atau delete pun.
Aturan Modern C++ #
Aturan resminya sering disebut sebagai prinsip no naked new/delete: kode aplikasi tidak menulis new atau delete telanjang. Pecahannya menjadi empat lapis kebiasaan:
- Mulai dari container:
std::vector,std::string, danstd::arraymenyelesaikan mayoritas kebutuhan data — ukurannya bisa berubah, pelepasannya otomatis, dan kinerjanya sudah dioptimalkan. std::unique_ptrsebagai default kepemilikan tunggal: bila objek memang harus di heap dan umurnya melebihi blok, inilah pilihan pertama, bukannew/delete.std::shared_ptrhanya bila benar-benar dibagi: kepemilikan bersama harus terlihat dari desain, bukan dari keraguan memilih alat; hitung biaya blok kontrolnya.- Raw
new/deletehanya di dalam library: pemilik implementasi container, allocator, atau pustaka kelas lain boleh memakainya — tersembunyi di balik antarmuka RAII yang aman bagi pemakai.
Tabel Kebutuhan ke Alat #
| Kebutuhan | Alat modern | Penggantinya |
|---|---|---|
| Kumpulan elemen ukuran dinamis | std::vector<T> | new T[n] / delete[] |
| Teks | std::string / std::string_view | new char[n] |
| Objek heap satu pemilik | std::make_unique<T>(...) | new + delete |
| Objek heap banyak pemilik | std::make_shared<T>(...) | new + delete tersebar |
| Array heap satu pemilik | std::make_unique<T[]>(n) | new[] + delete[] |
| Melihat objek tanpa memiliki | T& / T* / std::weak_ptr | new yang dipegang lama |
Kolom pengganti di sebelah kanan adalah pola yang setiap barisnya pernah kita bahas dan uji di Section ini — bukan teori, melainkan pola yang sudah kita buktikan bisa bocor, dilompati exception, atau tertukar kurung sikunya.
Program Idiomatik Tanpa new/delete #
Program penutup ini menggabungkan hampir semua materi Section: struct dan vector dari Section Array dan String, kepemilikan lewat make_unique, dan nol baris pelepasan manual:
#include <iostream>
#include <memory>
#include <string>
#include <vector>
struct Produk {
std::string nama;
double harga;
};
std::vector<Produk> muatProduk() {
return {{"Buku", 45000.0}, {"Pensil", 3000.0}, {"Tas", 120000.0}};
}
int main() {
std::vector<Produk> daftar = muatProduk();
std::cout << "Daftar produk:\n";
for (const Produk& p : daftar) {
std::cout << " " << p.nama << ": Rp" << p.harga << "\n";
}
double total = 0.0;
for (const Produk& p : daftar) {
total += p.harga;
}
std::cout << "Total: Rp" << total << "\n";
// Satu-satunya kepemilikan yang memang dibutuhkan: unique_ptr,
// bukan new/delete manual.
auto laporan = std::make_unique<std::string>("Laporan penjualan");
std::cout << *laporan << " memuat " << daftar.size() << " produk\n";
return 0;
}Output yang Dihasilkan:
Daftar produk:
Buku: Rp45000
Pensil: Rp3000
Tas: Rp120000
Total: Rp168000
Laporan penjualan memuat 3 produkYang layak digarisbawahi dari program ini:
- Baris 12-14 (
muatProduk): vector dikembalikan dari fungsi tanpa kepura-puraan — pustaka mengelola alokasinya, dan perpindahannya memakai move yang murah. - Baris 18-21 (
for (const Produk& p : daftar)): akses dengan reference konstan — mengamati tanpa menyalin dan tanpa memegang kepemilikan apa pun. - Baris 30 (
std::make_unique<std::string>(...)): satu-satunya kepemilikan heap yang benar-benar dibutuhkan, dinyatakan eksplisit sebagaiunique_ptr. - Baris 32 (
return 0;): semua resource — elemen vector, string di dalam setiapProduk, dan objeklaporan— dilepas otomatis oleh destructor masing-masing.
Program sepanjang 32 baris itu mengelola puluhan alokasi heap di balik layar tanpa satu baris pelepasan. Kegagalan yang pernah kita buktikan di Section ini — kebocoran, double delete, kurung siku tertukar, exception melompati delete — tidak punya celah untuk terjadi di sini.
Kapan Manual Masih Layak #
Ada dua pengecualian yang jujur untuk dicatat. Pertama, saat menulis atau merawat pustaka dasar — allocator, container, binding ke kode C — new/delete memang bagian dari pekerjaannya, ditulis sekali di balik antarmuka yang aman. Kedua, saat mendiagnosis: membaca kode yang memakai new/delete adalah keterampilan nyata, karena kode lama di dunia industri masih memakainya, dan Section Debugging dan Code Quality akan menuntut kemampuan membaca kebocoran seperti yang kita uji dengan AddressSanitizer.
Section Manajemen Memori resmi berakhir di sini, dengan satu kebiasaan yang dibawa pulang: serahkan umur resource ke objek, dan biarkan compiler bekerja untuk kita. Section berikutnya, Standard Library, memperluas keluarga alat ini — dari container lain seperti std::map dan std::set hingga utilitas std::optional — semuanya dibangun di atas fondasi RAII yang baru saja kita kuasai.
Referensi: cppreference — RAII , cppreference — std::make_unique , cppreference — std::vector .