Pada chapter-chapter sebelumnya, setiap object yang kita buat harus diisi manual: kita memanggil buka() untuk rekening atau menugaskan panjang dan lebar satu per satu. Cara ini rapuh — siapa pun yang lupa mengisi bisa memakai object dengan data yang belum lengkap. C++ menyediakan constructor, fungsi khusus yang dijalankan secara otomatis tepat saat object dibuat, sehingga object tidak pernah sempat hidup dalam keadaan kosong. Chapter ini membahas cara menulisnya dan bagaimana satu class bisa punya beberapa constructor sekaligus.
Apa itu Constructor #
Constructor adalah member function yang tugasnya menginisialisasi object: mengisi data member agar state awalnya valid. Ia punya tiga ciri yang membedakannya dari fungsi biasa. Pertama, namanya persis sama dengan nama class — constructor dari class Produk pasti bernama Produk. Kedua, ia tidak punya return type, bahkan bukan void; kita tidak menulis apa pun sebelum namanya. Ketiga, dan paling penting, ia dipanggil otomatis oleh compiler pada saat object dibuat — kita tidak pernah memanggilnya lewat . seperti fungsi biasa.
Karena dijalankan otomatis, constructor adalah satu-satunya tempat yang dijamin dieksekusi untuk setiap object. Inilah posisi strategisnya: semua aturan awal — nilai default, validasi argumen, pencatatan ke log — tinggal kita tulis di sana sekali. Lupakan constructor, dan setiap pembuatan object harus mengandalkan disiplin pemanggil yang tidak selalu ada.
Beberapa Constructor dalam Satu Class #
Sering kali object perlu dibuat dengan berbagai tingkat kelengkapan: ada yang dibuat lengkap, ada yang sengaja dibuat kosong untuk diisi belakangan. C++ mengizinkan kita menulis beberapa constructor dalam satu class, asalkan daftar parameternya berbeda jumlah atau tipe — persis konsep function overloading yang sudah kita kenal. Compiler kemudian memilih constructor yang cocok berdasarkan argumen yang kita kirim saat pembuatan object.
class Produk {
public:
Produk(); // constructor tanpa parameter
Produk(const std::string& n); // constructor satu parameter
Produk(const std::string& n, double h, int s);
};Ketiga constructor di atas hidup berdampingan dan saling melengkapi. Tidak ada yang “menang” — keputusan diambil baris demi baris di titik pembuatan object. Inilah yang membuat API class nyaman dipakai: pemanggil bebas memilih tingkat detail yang ia butuhkan.
Contoh: Tiga Constructor yang Dipilih Compiler #
Program berikut mendefinisikan ketiga constructor Produk, lengkap dengan jejak cetak agar kita melihat constructor mana yang benar-benar dieksekusi:
#include <iostream>
#include <string>
class Produk {
public:
std::string nama; // tanpa in-class initializer
int stok = 0; // in-class initializer: nilai default
double harga = 0.0;
// Constructor 1: tanpa parameter
Produk() {
nama = "Tanpa Nama";
std::cout << "Produk() dipanggil\n";
}
// Constructor 2: satu parameter
Produk(const std::string& n) {
nama = n;
std::cout << "Produk(nama) dipanggil\n";
}
// Constructor 3: tiga parameter
Produk(const std::string& n, double h, int s) {
nama = n;
harga = h;
stok = s;
std::cout << "Produk(nama, harga, stok) dipanggil\n";
}
void cetak() {
std::cout << nama << " | Rp" << harga << " | stok " << stok << "\n";
}
};
int main() {
Produk a; // memanggil Produk()
Produk b("Kopi Gayo"); // memanggil Produk(const std::string&)
Produk c("Gula Pasir", 15500.0, 40);
a.cetak();
b.cetak();
c.cetak();
return 0;
}Output yang Dihasilkan:
Produk() dipanggil
Produk(nama) dipanggil
Produk(nama, harga, stok) dipanggil
Tanpa Nama | Rp0 | stok 0
Kopi Gayo | Rp0 | stok 0
Gula Pasir | Rp15500 | stok 40Mari kita bedah:
- Baris 11-15 (
Produk() { ... }): constructor tanpa parameter. Baris pertama output membuktikan ia dijalankan otomatis saatProduk a;dieksekusi — tidak ada satu pun pemanggilan eksplisit dimain(). - Baris 18-22 (
Produk(const std::string& n)): constructor satu parameter. Parameter dilewatkan sebagaiconst std::string&agar string tidak disalin secara tidak perlu — kebiasaan baik yang sudah kita kenal dari materi fungsi. - Baris 25-33 (
Produk(const std::string& n, double h, int s)): constructor paling lengkap; ia mengisi seluruh data member dari argumen pemanggil. - Baris 41-43 (pembuatan
a,b,c): compiler memilih constructor berdasarkan argumen — nol argumen keProduk(), satu string ke overload kedua, tiga nilai ke overload ketiga. Tiga baris jejak pertama pada output adalah buktinya. - Baris 45-47 (pemanggilan
cetak()): memperlihatkan state akhir. Perhatikanb: constructor keduanya hanya mengisinama, sehinggahargadanstokmemakai in-class initializer dari baris 7-8 — hasilnyaRp0danstok 0, bukan nilai acak.
Jejak cetak di constructor pada contoh ini adalah alat belajar. Pada kode produksi, constructor biasanya diam saja dan hanya mengisi data — tetapi pola “cetak untuk membuktikan urutan” akan terus kita pakai, misalnya saat membahas destructor.
Sekarang kita punya constructor tanpa parameter dan constructor berparameter. Chapter berikutnya memfokuskan pada yang pertama: default constructor, termasuk pertanyaan yang sering mengganggu — apa yang terjadi bila kita tidak menulisnya sama sekali.
Rujukan resmi: Constructors (cppreference) .