Episode ini membedah fungsi secara menyeluruh: deklarasi versus definisi, overloading, default arguments, inline dan constexpr, pemisahan header dan source dengan linkage, serta function pointers, lambda, dan std::function untuk fungsi sebagai nilai.

Fungsi adalah unit dasar modularitas di C++. Episode 3 memperkenalkan fungsi sederhana; episode 5 memperdalamnya: bagaimana deklarasi dan definisi berbeda, bagaimana overloading memungkinkan satu nama untuk banyak bentuk, dan bagaimana C++ modern mengubah fungsi menjadi warga kelas satu.
Di akhir episode ini, kalian akan membangun proyek multi-file dengan header yang benar, memahami linkage yang menjadi sumber banyak error linker, dan memakai lambda untuk logika kecil yang tidak perlu fungsi bernama.
Deklarasi memberi tahu compiler bahwa sebuah fungsi ada beserta tipenya. Definisi menyediakan tubuh fungsi. Satu fungsi boleh dideklarasikan berkali-kali tetapi hanya boleh didefinisikan sekali dalam satu program:
cat > fungsi2.cpp <<'EOF'
#include <iostream>
int tambah(int a, int b);
int tambah(int a, int b);
int tambah(int a, int b) {
return a + b;
}
int main() {
std::cout << tambah(3, 4) << "\n";
}
EOF
g++ -std=c++20 fungsi2.cpp -o fungsi2
./fungsi2Deklarasi int tambah(int a, int b); muncul dua kali tanpa masalah, sedangkan definisi hanya satu kali. Pola ini memungkinkan header berisi deklarasi dan source berisi definisi.
Parameter bisa diberi nilai default yang dipakai saat argumen tidak diberikan. Aturannya: parameter berdefault diletakkan di akhir daftar parameter. Pemanggilan sapa("Arman") memakai nilai default, dan pemanggilan kedua menimpanya dengan nilai eksplisit.
Overloading memungkinkan beberapa fungsi dengan nama sama tetapi parameter berbeda. Compiler memilih versi yang tepat berdasarkan tipe argumen — inilah alasan adanya name mangling yang dibahas di episode 2:
cat > overload.cpp <<'EOF'
#include <iostream>
int luas(int sisi) {
return sisi * sisi;
}
double luas(double panjang, double lebar) {
return panjang * lebar;
}
int main() {
std::cout << luas(5) << "\n";
std::cout << luas(2.5, 4.0) << "\n";
}
EOF
g++ -std=c++20 overload.cpp -o overload
./overloadOverloading hanya dibedakan oleh tipe parameter, bukan tipe kembalian. Fungsi luas(int) dan luas(double, double) hidup berdampingan dengan aman.
Fungsi inline disarankan agar compiler menyalin tubuhnya langsung ke titik pemanggilan, menghindari overhead pemanggilan. constexpr membuat fungsi dihitung saat kompilasi jika semua argumennya konstanta — constexpr int hasil = pangkatDua(9) memaksa perhitungan dilakukan saat kompilasi. Gunakan constexpr untuk fungsi yang bisa dihitung lebih awal — hemat runtime tanpa mengubah hasil.
Setiap file .cpp adalah satu translation unit yang dikompilasi sendiri. Linkage menghubungkan simbol antar unit: fungsi bernama global ber-linkage eksternal (bisa dipakai unit lain), dan static memberi linkage internal.
Proyek multi-file dipisah menjadi header (deklarasi) dan source (definisi):
cat > kalkulator.hpp <<'EOF'
#ifndef KALKULATOR_HPP
#define KALKULATOR_HPP
int tambah(int a, int b);
int kali(int a, int b);
#endif
EOF
cat > kalkulator.cpp <<'EOF'
#include "kalkulator.hpp"
int tambah(int a, int b) { return a + b; }
int kali(int a, int b) { return a * b; }
EOF
cat > main.cpp <<'EOF'
#include "kalkulator.hpp"
#include <iostream>
int main() {
std::cout << tambah(2, 3) << " " << kali(2, 3) << "\n";
}
EOF
g++ -std=c++20 main.cpp kalkulator.cpp -o app
./appPerintah g++ -std=c++20 main.cpp kalkulator.cpp -o app mengkompilasi dua source file lalu meng-link-nya menjadi satu executable. #include "kalkulator.hpp" memakai tanda kutip karena header berada di direktori lokal. Include guard #ifndef KALKULATOR_HPP mencegah header diproses dua kali.
Sebuah fungsi memiliki alamat, dan alamat itu bisa disimpan di variabel. Function pointer memungkinkan fungsi dikirim sebagai argumen — tipe int (*fn)(int, int) menunjuk ke fungsi yang menerima dua int dan mengembalikan int. Ini pola callback klasik, meski sekarang lebih sering digantikan lambda.
Lambda mendefinisikan fungsi anonim tepat di tempat ia dipakai. std::function menyimpan callable apa pun — lambda, function pointer, atau functor — dengan tipe seragam:
cat > lambda.cpp <<'EOF'
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
int main() {
auto kali2 = [](int x) { return x * 2; };
std::cout << kali2(5) << "\n";
std::vector<int> angka{3, 1, 4, 1, 5};
std::sort(angka.begin(), angka.end(),
[](int a, int b) { return a > b; });
std::function<int(int)> fn = kali2;
std::cout << fn(6) << "\n";
}
EOF
g++ -std=c++20 lambda.cpp -o lambda
./lambdaLambda [](int x) { return x * 2; } menangkap variabel sekitar dalam kurung siku dan menerima parameter dalam kurung biasa. std::sort(angka.begin(), angka.end(), [](int a, int b){:bash} ...) memakai lambda sebagai pembanding. Detail lebih dalam dibahas di episode 16.
Inti yang harus dibawa pulang:
inline menghindari overhead pemanggilan, constexpr menghitung saat kompilasi.std::function memperlakukan fungsi sebagai nilai.Di episode 6 selanjutnya kita akan membahas object-oriented programming — class dan object, constructor dan destructor, access specifiers dan encapsulation, inheritance dan polymorphism dengan virtual functions, abstract class dan interface pattern, serta smart pointers untuk kepemilikan objek.