Belajar C++ - Object-Oriented Programming
Episode 6 of 24

Belajar C++ - Object-Oriented Programming

Episode ini membahas object-oriented programming di C++: class dan object, constructor dan destructor, access specifiers dan encapsulation, inheritance dan polymorphism dengan virtual functions, abstract class dan interface pattern, serta smart pointers.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

C++ lahir dari gagasan yang diwariskan C: kontrol penuh atas memori. Tapi Stroustrup menambahkan sesuatu yang mengubah segalanya — class. Dengan class, kalian bisa memodelkan data dan perilaku menjadi satu kesatuan yang disebut object.

Episode 6 membahas inti object-oriented programming di C++: bagaimana class dibentuk, bagaimana constructor dan destructor mengatur siklus hidup object, bagaimana encapsulation menjaga integritas data, dan bagaimana inheritance serta virtual functions memungkinkan polymorphism — satu interface untuk banyak implementasi.

Class, Object, Constructor, dan Destructor

Mendefinisikan Class

Class adalah cetak biru; object adalah wujud nyata dari cetak biru itu. Sebuah class menggabungkan data (member variable) dan perilaku (member function):

Class pertama
cat > mobil.cpp <<'EOF'
#include <iostream>
#include <string>
 
class Mobil {
public:
    Mobil(std::string merek, int tahun)
        : merek_(merek), tahun_(tahun) {}
 
    void info() const {
        std::cout << merek_ << " tahun " << tahun_ << "\n";
    }
 
private:
    std::string merek_;
    int tahun_;
};
 
int main() {
    Mobil avanza("Avanza", 2021);
    avanza.info();
}
EOF
g++ -std=c++20 mobil.cpp -o mobil
./mobil

Constructor Mobil(std::string merek, int tahun) menginisialisasi member lewat initializer list. avanza.info() memanggil member function pada object avanza. Fungsi const member ditandai const untuk menjamin tidak mengubah object.

Destructor dan Siklus Hidup

Destructor dijalankan otomatis saat object keluar dari scope. Inilah kunci manajemen resource ala C++: jika object membuka file atau mengalokasikan memori, destructor menutup dan membebaskannya. Pembersihan terjadi di titik yang pasti dan deterministik — tidak ada garbage collector. Ketika object dibuat, constructor membangunnya; ketika keluar dari scope, destructor otomatis membersihkannya. Pola "resource diikat ke umur object" ini bernama RAII dan menjadi fondasi manajemen memori di episode 7.

Access Specifiers dan Encapsulation

Public, Private, dan Protected

Access specifiers mengatur siapa yang bisa mengakses member. public bisa diakses siapa saja, private hanya dari dalam class, dan protected juga dari class turunan. Encapsulation memakai ini untuk menyembunyikan detail internal:

Encapsulation
cat > akun.cpp <<'EOF'
#include <iostream>
 
class Rekening {
public:
    explicit Rekening(double saldoAwal) : saldo_(saldoAwal) {}
 
    void setor(double jumlah) {
        if (jumlah > 0) saldo_ += jumlah;
    }
 
    double saldo() const { return saldo_; }
 
private:
    double saldo_;
};
 
int main() {
    Rekening r(1000.0);
    r.setor(500.0);
    std::cout << "Saldo: " << r.saldo() << "\n";
}
EOF
g++ -std=c++20 akun.cpp -o akun
./akun

saldo_ bersifat private, jadi kalian tidak bisa menulis r.saldo_ = 999999; dari luar. Satu-satunya jalan adalah lewat method setor yang memvalidasi input — di sinilah nilai encapsulation: data selalu dalam keadaan konsisten.

Inheritance dan Polymorphism

Virtual Functions

Virtual functions memungkinkan perilaku berbeda untuk class berbeda meski dipanggil melalui base pointer. Inilah polymorphism — satu interface, banyak implementasi. virtual pada destructor base memastikan destructor derived ikut dijalankan:

Polymorphism
cat > hewan.cpp <<'EOF'
#include <iostream>
#include <vector>
#include <memory>
 
class Hewan {
public:
    virtual ~Hewan() = default;
    virtual void suara() const = 0;
};
 
class Anjing : public Hewan {
public:
    void suara() const override { std::cout << "Guk guk\n"; }
};
 
class Kucing : public Hewan {
public:
    void suara() const override { std::cout << "Meow\n"; }
};
 
int main() {
    std::vector<std::unique_ptr<Hewan>> koleksi;
    koleksi.push_back(std::make_unique<Anjing>());
    koleksi.push_back(std::make_unique<Kucing>());
 
    for (const auto& h : koleksi) {
        h->suara();
    }
}
EOF
g++ -std=c++20 hewan.cpp -o hewan
./hewan

virtual void suara() const = 0 adalah pure virtual function — class yang memilikinya disebut abstract class dan tidak bisa di-instantiate. Derived class Anjing dan Kucing wajib mengimplementasikannya dengan override. Kontainer memegang std::unique_ptr<Hewan> agar polymorphism bekerja dan memori terkelola otomatis.

Abstract Class dan Interface Pattern

Interface Pattern

Dalam C++, interface dibentuk dengan abstract class yang hanya berisi pure virtual functions — mirip interface di Java. Ini memisahkan kontrak dari implementasi. Kode client cukup bergantung pada interface, sehingga implementasi bisa diganti tanpa menyentuh pemanggil.

Polymorphism dengan unique_ptr dan make_unique adalah pola kepemilikan modern: pointer disimpan sebagai base, dan saat kontainer dihancurkan, seluruh objek beserta memorinya dibebaskan otomatis.

Warning

Jika sebuah class punya virtual function, destructor-nya wajib virtual — jika tidak, penghancuran lewat base pointer melewatkan destructor derived class.

Smart Pointers dan Kepemilikan

unique_ptr dan shared_ptr

Smart pointers membungkus alokasi dinamis agar tidak perlu delete manual. std::unique_ptr memiliki satu pemilik saja, std::shared_ptr membagi kepemilikan dengan reference counting, dan std::weak_ptr mengamati tanpa memiliki. Sejak C++11, smart pointer hampir menggantikan new dan delete manual. Contohnya, std::make_unique<Laporan> mengalokasikan dan mem-construct objek dalam satu langkah. Saat pemiliknya keluar dari scope, destructor Laporan dipanggil otomatis — tidak ada delete manual, tidak ada kebocoran.

Penutup

Inti yang harus dibawa pulang:

  • Class adalah cetak biru, object adalah wujudnya.
  • Constructor menginisialisasi, destructor membersihkan resource.
  • public, private, dan protected mengatur akses member.
  • Encapsulation menjaga data tetap konsisten melalui method.
  • Virtual functions dan abstract class mewujudkan polymorphism.
  • unique_ptr dan shared_ptr mengelola kepemilikan secara otomatis.

Di episode 7 selanjutnya kita akan membahas memory dan resource management — pointer dan reference, pointer arithmetic, alokasi dinamis dengan new dan delete beserta smart pointer, pola RAII, serta bug memori umum seperti use-after-free, double-free, dan dangling pointer.