Python

πŸ—οΈ C++ Object-Oriented Programming: Panduan Lengkap

Tutorial lengkap belajar C++ OOP dari dasar β€” class, object, inheritance, polymorphism, template, STL, dan quiz interaktif dengan contoh kode praktis

1. Pengenalan Object-Oriented Programming

Object-Oriented Programming (OOP) adalah paradigma pemrograman yang mengorganisasi kode ke dalam bentuk "objek" yang memiliki data (atribut) dan perilaku (method). C++ adalah bahasa yang mendukung OOP secara penuh, dikembangkan oleh Bjarne Stroustrup pada tahun 1979 sebagai ekensi dari C.

OOP memungkinkan kita memodelkan dunia nyata ke dalam kode β€” misalnya, sebuah "Mobil" memiliki warna dan merek (atribut), serta bisa bergerak dan berhenti (method). Pendekatan ini membuat kode lebih terorganisasi, reusable, dan mudah di-maintain.

Empat Pilar OOP

Pilar Penjelasan Contoh
EncapsulationMenggabungkan data dan method dalam satu unit, menyembunyikan detail internalClass dengan private members
InheritanceClass anak mewarisi properti dan method dari class parentAnjing extends Hewan
PolymorphismSatu interface bisa digunakan untuk banyak bentukMethod yang dioverride berbeda di setiap subclass
AbstractionMenyembunyikan kompleksitas, hanya menampilkan yang pentingAbstract class dan interface
Diagram: Konsep OOP
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              EMPAT PILAR OOP DI C++                     β”‚
β”‚                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Encapsulationβ”‚  β”‚ Inheritance β”‚  β”‚ Polymorphism  β”‚  β”‚
β”‚  β”‚             β”‚  β”‚             β”‚  β”‚               β”‚  β”‚
β”‚  β”‚ private:    β”‚  β”‚  Hewan      β”‚  β”‚ shape.area()  β”‚  β”‚
β”‚  β”‚  data       β”‚  β”‚   β”œβ”€β”€ Kucingβ”‚  β”‚  β†’ lingkaran  β”‚  β”‚
β”‚  β”‚ protected:  β”‚  β”‚   └── Anjingβ”‚  β”‚  β†’ persegi    β”‚  β”‚
β”‚  β”‚  internal   β”‚  β”‚             β”‚  β”‚  β†’ segitiga   β”‚  β”‚
β”‚  β”‚ public:     β”‚  β”‚             β”‚  β”‚               β”‚  β”‚
β”‚  β”‚  interface  β”‚  β”‚             β”‚  β”‚               β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                Abstraction                        β”‚  β”‚
β”‚  β”‚  Interface / Abstract class β€” hanya expose API     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. Class dan Object

Class adalah blueprint (cetak biru) untuk membuat objek. Class mendefinisikan atribut (data) dan method (fungsi) yang dimiliki oleh objek. Object adalah instance (hasil) dari class.

Membuat Class Pertama

C++ β€” Class Dasar
#include <iostream>
#include <string>
using namespace std;

class Mahasiswa {
public:
    // Atribut (data members)
    string nama;
    int umur;
    float ipk;

    // Method (member functions)
    void tampilkan() {
        cout << "Nama: " << nama << endl;
        cout << "Umur: " << umur << " tahun" << endl;
        cout << "IPK: " << ipk << endl;
    }

    bool lulus() {
        return ipk >= 2.0;
    }
};

int main() {
    // Membuat object dari class
    Mahasiswa mhs1;
    mhs1.nama = "Budi Santoso";
    mhs1.umur = 20;
    mhs1.ipk = 3.75;
    mhs1.tampilkan();
    cout << "Lulus: " << (mhs1.lulus() ? "Ya" : "Tidak") << endl;

    cout << endl;

    // Object kedua
    Mahasiswa mhs2;
    mhs2.nama = "Ani Putri";
    mhs2.umur = 21;
    mhs2.ipk = 3.90;
    mhs2.tampilkan();

    // Array of objects
    Mahasiswa kelas[3];
    kelas[0] = {"Andi", 19, 3.50};
    kelas[1] = {"Sari", 20, 3.80};
    kelas[2] = {"Dedi", 21, 2.90};

    cout << "\n=== Daftar Kelas ===" << endl;
    for (int i = 0; i < 3; i++) {
        cout << i+1 << ". ";
        kelas[i].tampilkan();
        cout << "---" << endl;
    }

    return 0;
}

3. Constructor dan Destructor

Constructor adalah method khusus yang otomatis dipanggil saat object dibuat. Destructor dipanggil saat object dihapus dari memori.

Constructor

C++ β€” Constructor & Destructor
#include <iostream>
#include <string>
using namespace std;

class RekeningBank {
private:
    string pemilik;
    double saldo;
    string noRekening;
    bool aktif;

public:
    // Default constructor
    RekeningBank() : pemilik("Unknown"), saldo(0.0), noRekening("000"), aktif(true) {
        cout << "Rekening default dibuat" << endl;
    }

    // Parameterized constructor
    RekeningBank(string p, double s, string no)
        : pemilik(p), saldo(s), noRekening(no), aktif(true) {
        cout << "Rekening " << noRekening << " dibuat" << endl;
    }

    // Copy constructor
    RekeningBank(const RekeningBank& other)
        : pemilik(other.pemilik + " (copy)"), saldo(other.saldo),
          noRekening(other.noRekening + "-C"), aktif(other.aktif) {
        cout << "Copy constructor dipanggil" << endl;
    }

    // Destructor
    ~RekeningBank() {
        cout << "Rekening " << noRekening << " ditutup (destructor)" << endl;
    }

    // Method
    void setor(double jumlah) {
        if (jumlah > 0) {
            saldo += jumlah;
            cout << "Setor Rp" << jumlah << " berhasil" << endl;
        }
    }

    void tarik(double jumlah) {
        if (jumlah > 0 && jumlah <= saldo) {
            saldo -= jumlah;
            cout << "Tarik Rp" << jumlah << " berhasil" << endl;
        } else {
            cout << "Saldo tidak cukup!" << endl;
        }
    }

    void info() const {
        cout << "=== Rekening " << noRekening << " ===" << endl;
        cout << "Pemilik : " << pemilik << endl;
        cout << "Saldo   : Rp" << saldo << endl;
        cout << "Status  : " << (aktif ? "Aktif" : "Nonaktif") << endl;
    }
};

int main() {
    // Default constructor
    RekeningBank r1;
    r1.info();

    cout << endl;

    // Parameterized constructor
    RekeningBank r2("Budi", 1000000, "ACC-001");
    r2.setor(500000);
    r2.tarik(200000);
    r2.info();

    cout << endl;

    // Copy constructor
    RekeningBank r3 = r2;  // atau RekeningBank r3(r2);
    r3.info();

    // Destructor dipanggil otomatis saat object keluar scope

    return 0;
}
// Output urutan destructor terbalik dari urutan pembuatan
πŸ’‘ Initializer List

Gunakan initializer list (: member(value)) di constructor karena lebih efisien daripada assignment di dalam body. Ini terutama penting untuk const members dan reference members yang harus diinisialisasi saat pembuatan.

4. Encapsulation

Encapsulation adalah konsep menyembunyikan data internal dan hanya menyediakan akses melalui method publik. Ini melindungi data dari perubahan yang tidak diinginkan.

Access Modifiers

Modifier Dalam Class Subclass Luar Class
privateβœ… Ya❌ Tidak❌ Tidak
protectedβœ… Yaβœ… Ya❌ Tidak
publicβœ… Yaβœ… Yaβœ… Ya
C++ β€” Encapsulation
#include <iostream>
#include <string>
using namespace std;

class AkunUser {
private:
    string username;
    string password_hash;  // Disimpan dalam bentuk hash
    int loginAttempts;
    bool locked;

    // Private method β€” helper internal
    string hashPassword(string pwd) {
        // Simulasi hash sederhana
        unsigned long hash = 5381;
        for (char c : pwd) {
            hash = ((hash << 5) + hash) + c;
        }
        return to_string(hash);
    }

public:
    // Constructor
    AkunUser(string user, string pwd)
        : username(user), loginAttempts(0), locked(false) {
        password_hash = hashPassword(pwd);
    }

    // Getter β€” akses data secara terkontrol
    string getUsername() const {
        return username;
    }

    bool isLocked() const {
        return locked;
    }

    int getLoginAttempts() const {
        return loginAttempts;
    }

    // Setter dengan validasi
    void setPassword(string oldPwd, string newPwd) {
        if (hashPassword(oldPwd) == password_hash && newPwd.length() >= 8) {
            password_hash = hashPassword(newPwd);
            cout << "Password berhasil diubah!" << endl;
        } else {
            cout << "Gagal: Password lama salah atau baru terlalu pendek" << endl;
        }
    }

    // Business logic
    bool login(string pwd) {
        if (locked) {
            cout << "Akun terkunci!" << endl;
            return false;
        }
        if (hashPassword(pwd) == password_hash) {
            loginAttempts = 0;
            cout << "Login berhasil!" << endl;
            return true;
        }
        loginAttempts++;
        if (loginAttempts >= 3) {
            locked = true;
            cout << "Akun dikunci setelah 3 kali gagal!" << endl;
        }
        cout << "Password salah. Percobaan: " << loginAttempts << endl;
        return false;
    }
};

int main() {
    AkunUser user("budi123", "rahasia");
    cout << "Username: " << user.getUsername() << endl;

    user.login("salah");     // Percobaan 1
    user.login("salah");     // Percobaan 2
    user.login("salah");     // Percobaan 3 β€” akun terkunci!
    user.login("rahasia");   // Sudah terkunci

    cout << "Terkunci: " << (user.isLocked() ? "Ya" : "Tidak") << endl;

    // user.password_hash; // ERROR: private, tidak bisa diakses

    return 0;
}

5. Inheritance

Inheritance memungkinkan class anak (derived) mewarisi atribut dan method dari class parent (base). Ini mengurangi duplikasi kode dan membangun hierarki class.

Single Inheritance

C++ β€” Inheritance
#include <iostream>
#include <string>
using namespace std;

// Base class
class Hewan {
protected:
    string nama;
    int umur;

public:
    Hewan(string n, int u) : nama(n), umur(u) {
        cout << "Hewan " << nama << " dibuat" << endl;
    }

    virtual ~Hewan() {
        cout << "Hewan " << nama << " dihapus" << endl;
    }

    virtual void suara() const {
        cout << nama << " bersuara..." << endl;
    }

    void info() const {
        cout << "Nama: " << nama << ", Umur: " << umur << " tahun" << endl;
    }
};

// Derived class
class Kucing : public Hewan {
private:
    string warna;

public:
    Kucing(string n, int u, string w) : Hewan(n, u), warna(w) {}

    void suara() const override {
        cout << nama << " bersuara: Meow! Meow!" << endl;
    }

    void bermainBenang() const {
        cout << nama << " bermain benang!" << endl;
    }
};

class Anjing : public Hewan {
private:
    string ras;

public:
    Anjing(string n, int u, string r) : Hewan(n, u), ras(r) {}

    void suara() const override {
        cout << nama << " bersuara: Guk! Guk!" << endl;
    }

    void menggong() const {
        cout << nama << " menggong rumah!" << endl;
    }
};

// Multilevel inheritance
class HewanPeliharaan : public Hewan {
protected:
    string pemilik;

public:
    HewanPeliharaan(string n, int u, string p) : Hewan(n, u), pemilik(p) {}

    void infoPemilik() const {
        cout << nama << " milik " << pemilik << endl;
    }
};

class KucingPersia : public HewanPeliharaan {
private:
    bool pedigree;

public:
    KucingPersia(string n, int u, string p, bool ped)
        : HewanPeliharaan(n, u, p), pedigree(ped) {}

    void suara() const override {
        cout << nama << " (Persia) bersuara: Purr~" << endl;
    }

    void infoLengkap() const {
        infoPemilik();
        cout << "Ras: Persia, Pedigree: " << (pedigree ? "Ya" : "Tidak") << endl;
    }
};

int main() {
    Kucing k1("Kitty", 3, "Putih");
    k1.info();
    k1.suara();
    k1.bermainBenang();

    cout << endl;

    Anjing a1("Buddy", 5, "Golden Retriever");
    a1.info();
    a1.suara();
    a1.menggong();

    cout << endl;

    KucingPersia kp("Mochi", 2, "Ibu Lisa", true);
    kp.infoLengkap();
    kp.suara();

    return 0;
}
⚠️ Virtual Destructor

Selalu gunakan virtual pada destructor di base class jika class memiliki virtual functions. Tanpa virtual destructor, object yang dihapus melalui pointer base class tidak akan memanggil destructor derived class, menyebabkan memory leak.

6. Polymorphism

Polymorphism (banyak bentuk) memungkinkan satu interface digunakan untuk tipe data yang berbeda. Di C++, ada dua jenis: compile-time (function/operator overloading) dan runtime (virtual functions).

Runtime Polymorphism (Virtual Functions)

C++ β€” Polymorphism
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;

class Bentuk {
protected:
    string nama;

public:
    Bentuk(string n) : nama(n) {}
    virtual ~Bentuk() = default;

    // Pure virtual function β€” MUS diimplementasikan oleh subclass
    virtual double luas() const = 0;
    virtual double keliling() const = 0;

    // Virtual function dengan default implementation
    virtual void tampilkan() const {
        cout << "Bentuk: " << nama << endl;
        cout << "Luas: " << luas() << endl;
        cout << "Keliling: " << keliling() << endl;
    }
};

class Lingkaran : public Bentuk {
private:
    double r;

public:
    Lingkaran(double r) : Bentuk("Lingkaran"), r(r) {}

    double luas() const override {
        return 3.14159 * r * r;
    }

    double keliling() const override {
        return 2 * 3.14159 * r;
    }
};

class Persegi : public Bentuk {
private:
    double sisi;

public:
    Persegi(double s) : Bentuk("Persegi"), sisi(s) {}

    double luas() const override {
        return sisi * sisi;
    }

    double keliling() const override {
        return 4 * sisi;
    }
};

class Segitiga : public Bentuk {
private:
    double alas, tinggi, sisi1, sisi2, sisi3;

public:
    Segitiga(double a, double t, double s1, double s2, double s3)
        : Bentuk("Segitiga"), alas(a), tinggi(t),
          sisi1(s1), sisi2(s2), sisi3(s3) {}

    double luas() const override {
        return 0.5 * alas * tinggi;
    }

    double keliling() const override {
        return sisi1 + sisi2 + sisi3;
    }
};

// Fungsi yang menggunakan polymorphism
void cetakInfo(const Bentuk& b) {
    b.tampilkan();
    cout << "---" << endl;
}

int main() {
    // Polymorphism dengan pointer base class
    vector<unique_ptr<Bentuk>> bentuk;
    bentuk.push_back(make_unique<Lingkaran>(7));
    bentuk.push_back(make_unique<Persegi>(5));
    bentuk.push_back(make_unique<Segitiga>(6, 8, 6, 8, 10));

    cout << "=== Menggunakan Polymorphism ===" << endl;
    double totalLuas = 0;
    for (const auto& b : bentuk) {
        b->tampilkan();
        totalLuas += b->luas();
        cout << "---" << endl;
    }
    cout << "Total Luas: " << totalLuas << endl;

    return 0;
}

7. Abstract Class dan Interface

Abstract class adalah class yang memiliki minimal satu pure virtual function dan tidak bisa diinstansiasi langsung. Interface di C++ adalah abstract class yang seluruh method-nya pure virtual.

C++ β€” Abstract & Interface
#include <iostream>
#include <string>
#include <vector>
using namespace std;

// Interface β€” semua method pure virtual
class IPlayable {
public:
    virtual ~IPlayable() = default;
    virtual void play() = 0;
    virtual void pause() = 0;
    virtual void stop() = 0;
    virtual string getInfo() const = 0;
};

class IDownloadable {
public:
    virtual ~IDownloadable() = default;
    virtual void download(const string& path) = 0;
    virtual double getSize() const = 0;
};

// Multiple inheritance dari interface
class Musik : public IPlayable, public IDownloadable {
private:
    string judul;
    string artis;
    double durasi;
    double fileSize;

public:
    Musik(string j, string a, double d, double fs)
        : judul(j), artis(a), durasi(d), fileSize(fs) {}

    void play() override {
        cout << "β–Ά Memainkan: " << judul << " - " << artis << endl;
    }

    void pause() override {
        cout << "⏸ " << judul << " dijeda" << endl;
    }

    void stop() override {
        cout << "⏹ " << judul << " dihentikan" << endl;
    }

    string getInfo() const override {
        return judul + " - " + artis + " (" + to_string((int)durasi) + "s)";
    }

    void download(const string& path) override {
        cout << "⬇ Download " << judul << " ke " << path << endl;
    }

    double getSize() const override {
        return fileSize;
    }
};

class Video : public IPlayable, public IDownloadable {
private:
    string judul;
    string resolusi;
    double durasi;
    double fileSize;

public:
    Video(string j, string r, double d, double fs)
        : judul(j), resolusi(r), durasi(d), fileSize(fs) {}

    void play() override {
        cout << "β–Ά Memainkan video: " << judul << " [" << resolusi << "]" << endl;
    }

    void pause() override { cout << "⏸ Video dijeda" << endl; }
    void stop() override { cout << "⏹ Video dihentikan" << endl; }

    string getInfo() const override {
        return judul + " [" + resolusi + "]";
    }

    void download(const string& path) override {
        cout << "⬇ Download video " << judul << " ke " << path << endl;
    }

    double getSize() const override { return fileSize; }
};

int main() {
    Musik m1("Bohemian Rhapsody", "Queen", 354, 5.2);
    Video v1("Tutorial C++", "1080p", 1200, 450.0);

    // Polymorphism via interface
    vector<IPlayable*> playlist;
    playlist.push_back(&m1);
    playlist.push_back(&v1);

    cout << "=== Playlist ===" << endl;
    for (auto* item : playlist) {
        cout << item->getInfo() << endl;
        item->play();
    }

    // Download via interface
    vector<IDownloadable*> downloads;
    downloads.push_back(&m1);
    downloads.push_back(&v1);

    cout << "\n=== Download ===" << endl;
    for (auto* item : downloads) {
        cout << "Ukuran: " << item->getSize() << " MB" << endl;
        item->download("/downloads/");
    }

    return 0;
}

8. Template

Template memungkinkan menulis kode generik yang bekerja dengan tipe data apapun. Ini adalah fitur generic programming di C++ yang sangat powerful.

Function Template

C++ β€” Template
#include <iostream>
#include <string>
using namespace std;

// Function template β€” bekerja dengan tipe apapun
template <typename T>
T maksimum(T a, T b) {
    return (a > b) ? a : b;
}

template <typename T>
void tukar(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

// Template dengan multiple type parameters
template <typename T, typename U>
auto tambah(T a, U b) -> decltype(a + b) {
    return a + b;
}

// Class template
template <typename T>
class Tumpukan {
private:
    static const int MAX = 100;
    T data[MAX];
    int top;

public:
    Tumpukan() : top(-1) {}

    void push(const T& item) {
        if (top < MAX - 1) {
            data[++top] = item;
        } else {
            cout << "Stack penuh!" << endl;
        }
    }

    T pop() {
        if (top >= 0) {
            return data[top--];
        }
        cout << "Stack kosong!" << endl;
        return T();
    }

    T peek() const {
        if (top >= 0) return data[top];
        return T();
    }

    bool kosong() const { return top == -1; }
    int ukuran() const { return top + 1; }
};

// Template specialization
template <>
class Tumpukan<string> {
private:
    static const int MAX = 100;
    string data[MAX];
    int top;

public:
    Tumpukan() : top(-1) {}

    void push(const string& item) {
        if (top < MAX - 1) {
            data[++top] = item;
            cout << "Push string: \"" << item << "\"" << endl;
        }
    }

    string pop() {
        if (top >= 0) return data[top--];
        return "";
    }

    bool kosong() const { return top == -1; }
    int ukuran() const { return top + 1; }
};

int main() {
    // Function template
    cout << "Max(10, 20) = " << maksimum(10, 20) << endl;
    cout << "Max(3.14, 2.71) = " << maksimum(3.14, 2.71) << endl;
    cout << "Max('a', 'z') = " << maksimum('a', 'z') << endl;

    int x = 5, y = 10;
    tukar(x, y);
    cout << "Setelah tukar: x=" << x << ", y=" << y << endl;

    cout << "tambah(3, 4.5) = " << tambah(3, 4.5) << endl;

    // Class template
    Tumpukan<int> s;
    s.push(10);
    s.push(20);
    s.push(30);
    cout << "Pop: " << s.pop() << endl;  // 30
    cout << "Peek: " << s.peek() << endl;  // 20
    cout << "Ukuran: " << s.ukuran() << endl;  // 2

    Tumpukan<double> sd;
    sd.push(3.14);
    sd.push(2.71);

    // Template specialization
    Tumpukan<string> ss;
    ss.push("Hello");
    ss.push("World");

    return 0;
}

9. Standard Template Library (STL)

STL adalah kumpulan class template dan fungsi yang menyediakan struktur data dan algoritma umum. STL terdiri dari empat komponen: Containers, Iterators, Algorithms, dan Functors.

Containers

C++ β€” STL Containers
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <string>
using namespace std;

int main() {
    // ===== VECTOR β€” dynamic array =====
    vector<int> v = {5, 3, 8, 1, 9};
    v.push_back(10);
    v.push_back(7);

    cout << "Vector: ";
    for (int x : v) cout << x << " ";
    cout << endl;
    cout << "Size: " << v.size() << ", Front: " << v.front()
         << ", Back: " << v.back() << endl;

    // ===== LIST β€” doubly linked list =====
    list<string> l = {"apel", "jeruk", "mangga"};
    l.push_front("pisang");
    l.push_back("anggur");

    cout << "\nList: ";
    for (const auto& s : l) cout << s << " ";
    cout << endl;

    // ===== MAP β€” key-value pairs =====
    map<string, int> nilai;
    nilai["Budi"] = 85;
   nilai["Ani"] = 92;
    nilai["Dedi"] = 78;

    cout << "\nMap:" << endl;
    for (const auto& [nama, skor] : nilai) {
        cout << "  " << nama << ": " << skor << endl;
    }

    // Cari di map
    auto it = nilai.find("Ani");
    if (it != nilai.end()) {
        cout << "Ani ditemukan: " << it->second << endl;
    }

    // ===== SET β€” unique elements =====
    set<int> s = {3, 1, 4, 1, 5, 9, 2, 6, 5};
    cout << "\nSet (sorted, unique): ";
    for (int x : s) cout << x << " ";
    cout << endl;

    // ===== STACK β€” LIFO =====
    stack<string> st;
    st.push("Browser");
    st.push("Code Editor");
    st.push("Terminal");
    cout << "\nStack (LIFO):" << endl;
    while (!st.empty()) {
        cout << "  " << st.top() << endl;
        st.pop();
    }

    // ===== QUEUE β€” FIFO =====
    queue<string> q;
    q.push("Antrian 1");
    q.push("Antrian 2");
    q.push("Antrian 3");
    cout << "\nQueue (FIFO):" << endl;
    while (!q.empty()) {
        cout << "  " << q.front() << endl;
        q.pop();
    }

    // ===== UNORDERED_MAP β€” hash map (O(1) lookup) =====
    unordered_map<string, string> ibukota;
    ibukota["Indonesia"] = "Jakarta";
    ibukota["Jepang"] = "Tokyo";
    ibukota["Amerika"] = "Washington D.C.";

    cout << "\nIbukota:" << endl;
    for (const auto& [negara, kota] : ibukota) {
        cout << "  " << negara << " β†’ " << kota << endl;
    }

    return 0;
}

Algoritma STL

C++ β€” STL Algorithms
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

int main() {
    vector<int> v = {5, 3, 8, 1, 9, 2, 7, 4, 6};

    // Sort
    sort(v.begin(), v.end());
    cout << "Sorted: ";
    for (int x : v) cout << x << " ";
    cout << endl;

    // Sort descending
    sort(v.begin(), v.end(), greater<int>());
    cout << "Descending: ";
    for (int x : v) cout << x << " ";
    cout << endl;

    // Binary search (harus sorted ascending)
    sort(v.begin(), v.end());
    cout << "Binary search 5: " << (binary_search(v.begin(), v.end(), 5) ? "Ada" : "Tidak") << endl;

    // Find
    auto it = find(v.begin(), v.end(), 8);
    if (it != v.end()) {
        cout << "Found 8 at index: " << distance(v.begin(), it) << endl;
    }

    // Count
    cout << "Count > 5: " << count_if(v.begin(), v.end(), [](int x){ return x > 5; }) << endl;

    // Min/Max
    cout << "Min: " << *min_element(v.begin(), v.end()) << endl;
    cout << "Max: " << *max_element(v.begin(), v.end()) << endl;

    // Accumulate (sum)
    int total = accumulate(v.begin(), v.end(), 0);
    cout << "Sum: " << total << endl;

    // Transform β€” apply function to each element
    vector<int> doubled(v.size());
    transform(v.begin(), v.end(), doubled.begin(), [](int x){ return x * 2; });
    cout << "Doubled: ";
    for (int x : doubled) cout << x << " ";
    cout << endl;

    // Remove duplicates
    vector<int> dup = {1, 1, 2, 2, 3, 3, 4, 4, 5};
    dup.erase(unique(dup.begin(), dup.end()), dup.end());
    cout << "Unique: ";
    for (int x : dup) cout << x << " ";
    cout << endl;

    // For_each with lambda
    cout << "ForEach: ";
    for_each(v.begin(), v.end(), [](int x){
        if (x % 2 == 0) cout << x << " ";
    });
    cout << endl;

    return 0;
}

10. Operator Overloading

Operator overloading memungkinkan mendefinisikan perilaku operator untuk class custom. Ini membuat class bisa digunakan secara intuitif seperti tipe data built-in.

C++ β€” Operator Overloading
#include <iostream>
#include <cmath>
using namespace std;

class Vektor2D {
private:
    double x, y;

public:
    Vektor2D(double x = 0, double y = 0) : x(x), y(y) {}

    // Operator + (binary)
    Vektor2D operator+(const Vektor2D& other) const {
        return Vektor2D(x + other.x, y + other.y);
    }

    // Operator - (binary)
    Vektor2D operator-(const Vektor2D& other) const {
        return Vektor2D(x - other.x, y - other.y);
    }

    // Operator * (scalar multiplication)
    Vektor2D operator*(double scalar) const {
        return Vektor2D(x * scalar, y * scalar);
    }

    // Operator ==
    bool operator==(const Vektor2D& other) const {
        return x == other.x && y == other.y;
    }

    // Operator <
    bool operator<(const Vektor2D& other) const {
        return magnitude() < other.magnitude();
    }

    // Operator [] untuk akses komponen
    double operator[](int index) const {
        if (index == 0) return x;
        if (index == 1) return y;
        throw out_of_range("Index harus 0 atau 1");
    }

    // Operator ++ (prefix)
    Vektor2D& operator++() {
        x++; y++;
        return *this;
    }

    // Operator ++ (postfix)
    Vektor2D operator++(int) {
        Vektor2D temp = *this;
        x++; y++;
        return temp;
    }

    // Operator << (friend β€” output stream)
    friend ostream& operator<<(ostream& os, const Vektor2D& v) {
        os << "(" << v.x << ", " << v.y << ")";
        return os;
    }

    double magnitude() const {
        return sqrt(x * x + y * y);
    }

    double dot(const Vektor2D& other) const {
        return x * other.x + y * other.y;
    }
};

int main() {
    Vektor2D a(3, 4);
    Vektor2D b(1, 2);

    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "a + b = " << (a + b) << endl;
    cout << "a - b = " << (a - b) << endl;
    cout << "a * 2 = " << (a * 2) << endl;
    cout << "a == b: " << (a == b ? "Ya" : "Tidak") << endl;
    cout << "a[0]=" << a[0] << ", a[1]=" << a[1] << endl;
    cout << "|a| = " << a.magnitude() << endl;
    cout << "a . b = " << a.dot(b) << endl;

    Vektor2D c = a;
    cout << "++c = " << ++c << endl;
    cout << "c++ = " << c++ << endl;
    cout << "c sekarang = " << c << endl;

    return 0;
}

11. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang C++ OOP:

Pertanyaan 1: Apa fungsi dari keyword virtual pada method di base class?

a) Membuat method bisa diakses dari luar class
b) Memungkinkan runtime polymorphism β€” method dioverride di derived class
c) Membuat method berjalan lebih cepat
d) Menghapus method dari memory

Pertanyaan 2: Apa perbedaan antara vector dan list di STL?

a) Vector menggunakan linked list, list menggunakan array
b) Vector akses random O(1), list insert/delete di tengah O(1)
c) List lebih cepat dari vector dalam semua kasus
d) Tidak ada perbedaan

Pertanyaan 3: Apa yang terjadi jika class memiliki pure virtual function?

a) Class bisa diinstansiasi langsung
b) Class menjadi abstract β€” tidak bisa diinstansiasi, harus diimplementasikan oleh subclass
c) Class menjadi error saat kompilasi
d) Method pure virtual diabaikan

Pertanyaan 4: Kapan destructor base class harus dideklarasikan virtual?

a) Selalu, di semua class
b) Ketika class memiliki virtual functions dan object dihapus via pointer base class
c) Hanya untuk class template
d) Tidak pernah, destructor tidak bisa virtual

Pertanyaan 5: Apa output dari kode berikut?
vector<int> v = {3,1,4}; sort(v.begin(), v.end()); cout << v[0];

a) 3
b) 1
c) 4
d) Error
πŸ” Zoom
100%
🎨 Tema