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 |
|---|---|---|
| Encapsulation | Menggabungkan data dan method dalam satu unit, menyembunyikan detail internal | Class dengan private members |
| Inheritance | Class anak mewarisi properti dan method dari class parent | Anjing extends Hewan |
| Polymorphism | Satu interface bisa digunakan untuk banyak bentuk | Method yang dioverride berbeda di setiap subclass |
| Abstraction | Menyembunyikan kompleksitas, hanya menampilkan yang penting | Abstract class dan interface |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β 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
#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
#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
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 |
#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
#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;
}
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)
#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.
#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
#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
#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
#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.
#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: