Banyak fungsi punya parameter yang hampir selalu diisi nilai yang sama — level akses umumnya 1, satuan umumnya persen, bahasa umumnya Indonesia. Memaksa pemanggil mengetik argumen itu setiap kali berarti menambah kebisingan tanpa informasi baru. C++ menjawab kebutuhan ini dengan default argument: nilai bawaan yang tertulis pada deklarasi parameter dan otomatis dipakai bila pemanggil tidak menyediakan argumennya. Pada Chapter ini kita mencoba fiturnya, membedah aturan posisinya yang cukup tegas, menata letak bawaan pada prototipe, dan menandai jebakan nilai bawaan yang tidak stabil.
Parameter dengan Nilai Bawaan #
Default argument ditulis dengan tanda sama dengan pada deklarasi parameter: std::string nama = "Tamu". Bila pemanggil mengirim argumen, nilai bawaan diremehkan; bila tidak, bawaan yang masuk. Perhatikan fungsi sapa dengan dua bawaan dan hitungPajak dengan satu:
#include <iostream>
#include <string>
// Parameter dengan nilai bawaan (default argument)
void sapa(std::string nama = "Tamu", std::string bahasa = "Indonesia") {
std::cout << "Halo " << nama << ", sapaan bahasa " << bahasa << "\n";
}
// Parameter kedua punya bawaan; parameter pertama wajib diisi
double hitungPajak(double harga, double persen = 11.0) {
return harga * persen / 100.0;
}
int main() {
sapa(); // dua-duanya memakai bawaan
sapa("Budi"); // nama eksplisit, bahasa bawaan
sapa("Alice", "Inggris"); // semua argumen eksplisit
std::cout << "Pajak 100000: " << hitungPajak(100000.0) << "\n";
std::cout << "Pajak 100000 (5%): " << hitungPajak(100000.0, 5.0) << "\n";
return 0;
}Output yang Dihasilkan:
Halo Tamu, sapaan bahasa Indonesia
Halo Budi, sapaan bahasa Indonesia
Halo Alice, sapaan bahasa Inggris
Pajak 100000: 11000
Pajak 100000 (5%): 5000Tiga pemanggilan sapa memperlihatkan seluruh kemungkinannya: tanpa argumen sama sekali, sebagian argumen, dan argumen lengkap — satu fungsi untuk tiga kebutuhan. Pemetaannya tetap berbasis posisi seperti pada Chapter Parameter dan Argumen: sapa("Budi") mengisi parameter PERTAMA, sehingga "Budi" masuk ke nama dan bahasa tetap "Indonesia". Default argument juga cocok untuk konfigurasi yang benar-benar lazim: hitungPajak(100000.0) dengan PPN 11 persen terbaca ringkas, dan kasus khusus tinggal menambah argumen kedua.
Aturan: Bawaan Harus dari Kanan #
Karena pemetaan argumen berbasis posisi, ada aturan yang tidak bisa ditawar: parameter dengan nilai bawaan harus mengelompok DI UJUNG KANAN daftar parameter. Kalau tidak, pemanggil tidak punya cara “melewati” parameter berbawaan untuk mengisi parameternya — posisi tidak bisa dilompati. Deklarasi berikut kami jalankan sungguhan untuk menangkap penolakan compiler:
#include <string>
void buatAkun(std::string email, int level = 1, std::string nama);Pesan galat g++-nya: error: default argument missing for parameter 3 of 'void buatAkun(std::string, int, std::string)', disertai catatan ...following parameter 2 which has a default argument. Compiler menegaskan bahwa parameter 3 tidak boleh tanpa bawaan karena parameter di depannya sudah punya. Perbaikannya hanya satu bentuk: parameter berbawaan ditaruh berurutan di kanan — void buatAkun(std::string email, std::string nama, int level = 1); — sehingga pemanggil yang hanya mengisi email dan nama tetap sah.
Konsekuensi praktis dari aturan kanan ini: urutan parameter sebaiknya disusun dari yang WAJIB ke yang opsional. Parameter paling sering diisi berada di kiri, parameter berbawaan menutup daftar di kanan.
Bawaan pada Deklarasi, Bukan Definisi #
Saat fungsi punya prototipe terpisah, nilai bawaan cukup ditulis SEKALI — pada deklarasi. Pengulangan bawaan pada definisinya ditolak compiler, dan kami buktikan dengan potongan nyata berikut:
void sapa(std::string nama = "Tamu");
void sapa(std::string nama = "Tamu") {
std::cout << "Halo " << nama << "\n";
}Pesan galatnya: error: default argument given for parameter 1 of 'void sapa(std::string)' [-fpermissive] dengan catatan previous specification in 'void sapa(std::string)' here. Aturan ini menjaga satu sumber kebenaran: nilai bawaan hanya dinyatakan satu tempat, sehingga tidak ada dua deklarasi yang menjanjikan bawaan berbeda. Program versi benarnya seperti berikut — prototipe memegang bawaan, definisi menulis parameternya polos:
#include <iostream>
#include <string>
// Prototipe dengan default argument: bawaan cukup ditulis DI SINI
void sapa(std::string nama = "Tamu");
int main() {
sapa();
sapa("Budi");
return 0;
}
// Definisi tanpa pengulangan default argument
void sapa(std::string nama) {
std::cout << "Halo " << nama << "!\n";
}Output yang Dihasilkan:
Halo Tamu!
Halo Budi!Pola ini menyiapkan langkah ke praktik profesional: bila prototipe pindah ke header seperti yang kita latih pada Chapter Deklarasi dan Function Prototype, nilai bawaan ikut pindah ke sana — dan itulah yang benar, karena pemanggil di file lain hanya melihat deklarasi, bukan definisi. Bila tidak ada prototipe sama sekali, menulis bawaan pada definisi juga sah.
Rujukan resmi: cppreference: default arguments . Fitur ini punya saudara yang juga mengubah bentuk pemanggilan: function overloading — satu nama, banyak bentuk fungsi.