Siapa yang Boleh Menyentuh Datamu
Saat menulis class pertamamu, kemungkinan besar kamu membuka semua member ke dunia luar. Itu memang jalan, tetapi kamu membuang salah satu alasan utama class ada: enkapsulasi, yaitu menyembunyikan keadaan internal sebuah class sehingga bagian program lainnya hanya bisa berinteraksi dengannya lewat antarmuka yang terkendali. Access specifier adalah cara kamu menarik batas itu.
Jumlahnya tepat tiga: public, private, dan protected. Masing-masing memberi label pada member yang ada sesudahnya, dan label itu menentukan kode mana yang boleh membaca atau mengubahnya. Kalau benar, class-mu menjaga aturannya sendiri. Kalau salah, bug di mana saja bisa merusak keadaan objekmu.
Tiga Access Specifier
Access specifier adalah kata kunci yang diikuti titik dua. Setiap member yang dideklarasikan sesudahnya, sampai access specifier berikutnya, masuk ke level akses tersebut.
Hapus tanda komentar di baris terakhir, dan compiler menolak membangun program: balance bersifat private, jadi main tidak bisa mengutak-atiknya secara langsung. Justru itu intinya. Satu-satunya cara mengubah saldo adalah lewat deposit, artinya nanti kamu bisa menambahkan validasi (tidak boleh setoran negatif, pencatatan log, batasan) di satu tempat dan yakin validasi itu selalu berlaku.
Berikut rinciannya:
// reachable from...
// public anywhere (any code that has the object)
// private only the same class's own members (+ friends)
// protected the same class's members AND derived classes (+ friends)
class vs struct: Default-nya
Kamu boleh menulis blok access specifier sebanyak apa pun, dalam urutan apa pun. Akses member sebelum kamu menulis access specifier pertama bergantung pada apakah kamu memakai class atau struct:
- Di sebuah
class, member bersifatprivatesecara default. - Di sebuah
struct, member bersifatpublicsecara default.
Default itu adalah satu-satunya perbedaan antara kedua kata kunci tersebut di level bahasa. Sebuah struct bisa punya method, constructor, dan bagian private persis seperti class.
Konvensinya, struct dipakai untuk kumpulan data public yang sederhana dan class dipakai saat kamu menginginkan perilaku dan keadaan tersembunyi. Namun compiler tidak memaksakan hal itu, yang berbeda hanya default-nya.
Enkapsulasi dengan Getter dan Setter
Pola sehari-harinya begini: data masuk ke bagian private, dan method public memberi akses yang terkendali. Getter yang hanya membaca mengembalikan nilainya; setter memvalidasi dulu sebelum mengisi nilai. Di sinilah private terasa manfaatnya.
Karena celsius bersifat private, tidak ada cara menyelipkan nilai yang tidak valid. Setiap penulisan harus lewat setCelsius, yang menjaga aturan tersebut. Perhatikan bahwa getter-nya ditandai const: getter itu berjanji tidak mengubah objek, jadi kamu juga bisa memanggilnya pada objek const Temperature.
protected dan Pewarisan
protected baru berarti saat pewarisan (inheritance) ikut berperan. Bagi kode di luar, ia berperilaku seperti private, tetapi class turunan bisa mengaksesnya. Pakai untuk member yang memang dibutuhkan subclass, tetapi tetap tidak boleh diakses publik.
Kesalahan umum pemula adalah memakai protected untuk setiap member data "siapa tahu nanti subclass butuh". Itu diam-diam memperluas kontrak class-mu: sekarang setiap subclass bisa bergantung pada field tersebut, dan kamu tidak bisa lagi mengubahnya dengan bebas. Utamakan private, dan naikkan ke protected hanya saat class turunan benar-benar butuh aksesnya.
Jalan Pintas friend
Kadang satu fungsi atau class dari luar memang perlu melihat bagian dalam class-mu. Contoh klasiknya adalah operator overloading untuk <<, yang tidak bisa kamu jadikan member. Kata kunci friend memberi akses ke member private dan protected milikmu kepada satu entitas yang disebut namanya itu, dan tidak kepada yang lain.
friend adalah pengecualian yang disengaja dan sangat terarah: class itu sendiri menyebutkan dengan tepat siapa yang ia percaya, jadi tidak ada yang bisa memberi dirinya akses dari luar. Pakailah seperlunya. Kalau kamu mendapati dirimu menambahkan banyak friend, mungkin member tersebut memang tidak seharusnya private, atau desainmu perlu dipikirkan ulang.
Kesalahan Umum yang Perlu Dihindari
- Membuat semua member
public. Terasa mudah, tetapi kamu kehilangan semua validasi dan aturan yang diberikan enkapsulasi. Jadikan dataprivatedengan methodpublicsebagai pilihan awal. - Lupa default dari
class.class Foo { int x; };membuatxbersifat private, jadifoo.x = 5tidak akan bisa dikompilasi. Kalau yang kamu maksud adalah kumpulan data sederhana, pakaistructatau tambahkan labelpublic:. - Terlalu sering memakai
protected. Batasnya lebih lemah daripadaprivatedan hanya relevan dalam pewarisan. Memakainya di mana-mana membuat subclass terikat pada field yang mungkin ingin kamu ubah. - Menganggap
privatesebagai fitur keamanan. Ini aturan saat kompilasi yang mencegah akses tidak sengaja, bukan enkripsi. Byte-nya tetap ada di memori;privateadalah soal desain yang rapi, bukan kerahasiaan.
Berikutnya: Struct
Sekarang kamu tahu bahwa struct sebenarnya hanyalah class yang member-nya public secara default. Halaman berikutnya, struct, membahas kapan default public itu justru yang kamu inginkan, yaitu kumpulan ringan untuk mengelompokkan nilai yang saling terkait, dan bagaimana struct dipakai dalam C++ yang idiomatis bersama class yang lengkap.
Pertanyaan yang sering diajukan
Apa perbedaan public, private, dan protected di C++?
Member public bisa diakses dari mana saja. Member private hanya bisa diakses dari dalam class itu sendiri (dan dari friend-nya). protected mirip private, tetapi class turunan juga boleh mengakses member tersebut. Menurut konvensi, data disimpan sebagai private dan perilaku dibuka lewat method public.
Apakah member bersifat private secara default di C++?
Di sebuah class, ya: semuanya private sampai kamu menulis access specifier. Di sebuah struct, default-nya public. Default itulah satu-satunya perbedaan nyata antara class dan struct di C++; keduanya bisa punya method, constructor, dan access specifier.
Apa fungsi kata kunci friend di C++?
friend memberi satu fungsi atau class tertentu akses ke member private dan protected milikmu. Ini pengecualian enkapsulasi yang disengaja dan sempit: class itu sendiri menyebutkan dengan tepat siapa yang ia percaya, jadi akses tidak pernah diberikan secara diam-diam.