Kata kunci const yang sudah kita kuasai pada Chapter const dan constexpr menjadi lebih bernuansa saat digabung dengan pointer, karena pointer punya dua hal yang bisa dikunci: isi pointer (alamat yang disimpan) dan nilai objek yang ditunjuknya. Mengunci salah satunya, keduanya, atau tidak sama sekali menghasilkan tiga bentuk deklarasi yang tampak mirip tetapi berbeda perilaku. Chapter ini membedah ketiganya dan memberi kita satu trik membaca yang andal: membaca deklarasi dari kanan ke kiri.
Pointer to Const: Nilai Terkunci, Pointer Bebas #
Deklarasi const int* pc membuat objek yang ditunjuk tidak boleh diubah melalui pointer ini, sementara pc tetap boleh berpindah menunjuk objek lain.
#include <iostream>
int main() {
int a = 10;
int b = 20;
// 1. pointer to const: nilai lewat pointer tidak boleh diubah,
// tetapi pointer boleh berpindah sasaran
const int* pc = &a;
std::cout << "*pc awal : " << *pc << "\n";
pc = &b; // sah: pointer berpindah
std::cout << "*pc baru : " << *pc << "\n";
b = 55; // sah: diubah lewat jalur non-const (variabel b)
std::cout << "b = 55 -> *pc : " << *pc << "\n";
// 2. const pointer: pointer terkunci pada satu sasaran,
// tetapi nilai sasarannya boleh diubah
int* const cp = &a;
*cp = 77; // sah: mengubah nilai a
std::cout << "*cp setelah *cp = 77 : " << *cp << "\n";
// 3. const pointer to const: pointer dan nilai sama-sama terkunci
const int* const cpc = &b;
std::cout << "*cpc : " << *cpc << "\n";
return 0;
}Output yang Dihasilkan:
*pc awal : 10
*pc baru : 20
b = 55 -> *pc : 55
*cp setelah *cp = 77 : 77
*cpc : 55Bagian yang penting kita pahami:
- Baris 11-13 (
pc = &b;):pcberpindah dariakebtanpa keluhan — inilah kebebasan yang masih dimiliki pointer to const.*pckini bernilai 20. - Baris 14-15 (
b = 55;): nilai di balik*pcberubah menjadi 55, tetapi bukan lewatpc. Objekbsendiri tidak konst, jadi mengubahnya langsung sah.const int*hanya mengunci jalur akses lewat pointer tersebut — fakta yang sering mengejutkan pemula. - Baris 19-21 (
int* const cp = &a;): posisiconstsetelah*mengunci pointer.*cp = 77sah karena nilai boleh diubah, tetapicptidak akan pernah bisa menunjukb. - Baris 24-25 (
const int* const cpc): keduaconstdipasang, keduanya terkunci: nilai tidak bisa diubah lewatcpc, dancpctidak bisa berpindah.
Membaca Deklarasi dari Kanan ke Kiri #
Cara menentukan makna deklarasi pointer-const apa pun: mulai dari nama variabel, lalu baca ke kanan dulu, baru ke kiri. Tabel berikut merangkum tiga bentuknya:
| Deklarasi | Dibaca dari kanan ke kiri | Pointer berpindah? | Nilai lewat pointer diubah? |
|---|---|---|---|
const int* pc | “pc adalah pointer ke int yang const” | bisa | tidak bisa |
int* const cp | “cp adalah pointer const ke int” | tidak bisa | bisa |
const int* const cpc | “cpc adalah pointer const ke int yang const” | tidak bisa | tidak bisa |
Trik praktisnya: posisi const sebelum * mengunci nilai (pointer to const); posisi const sesudah * mengunci pointer (const pointer). Bentuk yang sama dengan int const* pc — const sebelum int atau sesudahnya — bermakna identik; yang menentukan adalah posisinya relatif terhadap *.
Pelanggarannya Terdeteksi saat Kompilasi #
Keunggulan terbesar const adalah setiap pelanggaran ditangkap compiler, jauh sebelum program dijalankan. Potongan berikut memakai kembali variabel di atas:
*pc = 99; // nilai terkunci lewat pointer to const
cp = &b; // pointer const tidak boleh berpindah
error: assignment of read-only location '* pc'
error: assignment of read-only variable 'cp'Dua pesan read-only itu jelas menyebut apa yang dilanggar: lokasi yang dibaca-saja pada kasus pertama, variabel yang dibaca-saja (pointer cp) pada kasus kedua. Perhatikan bahwa pelanggaran seperti ini tidak mungkin lolos menjadi bug runtime — inilah alasan menambahkan const semampu kita disebut “murah” dan sangat dianjurkan.
Kapan Memakai yang Mana #
Pilihan bentuknya mengikuti niat kita:
const T* p(paling sering): fungsi menerima objek lewat pointer tetapi berjanji tidak mengubahnya — seperti parameterconst int* arrpada Chapter sebelumnya. Juga lazim untuk membaca data yang sebaiknya tidak tersentuh.T* const p: pointer yang tidak boleh kehilangan sasarannya, misalnya penunjuk tetap ke buffer atau konfigurasi yang diset sekali saat inisialisasi. Padanannya yang lebih modern dan lebih disukai: cukup pakai reference atauconstexpr.const T* const p: kombinasi keduanya, untuk data yang benar-benar dibaca-saja lewat satu penunjuk tetap.
Kita kini menguasai pointer dalam segala variasi konstnya. Saatnya memakainya di tempat yang paling sering ditemui programmer: sebagai parameter fungsi — membawa nilai keluar dari fungsi, bukan hanya masuk.
Referensi: cppreference — cv qualifier (const) , cppreference — pointer .