Fungsi Virtual Murni
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 59 dari 104.
Fungsi virtual murni adalah fungsi virtual yang tidak memiliki implementasi di class dasar. Fungsi ini dideklarasikan dengan menetapkan = 0 pada deklarasi fungsi. Ini memberi tahu kompiler bahwa class turunan wajib menyediakan implementasinya sendiri.
class Shape {
public:
virtual double area() = 0; // Fungsi virtual murni
virtual ~Shape() = default;
};Berbeda dengan fungsi virtual biasa yang menyediakan perilaku default, fungsi virtual murni menetapkan kontrak: setiap class turunan konkret harus mengimplementasikan fungsi ini agar dapat dibuat instance-nya. Class dasar hanya menyatakan apa yang harus dilakukan, bukan bagaimana.
class Circle : public Shape {
double radius;
public:
Circle(double r) : radius(r) {}
double area() override {
return 3.14159 * radius * radius;
}
};
class Rectangle : public Shape {
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() override {
return width * height;
}
};Circle dan Rectangle harus mengimplementasikan area() karena fungsi tersebut bersifat virtual murni di Shape. Jika class turunan gagal mengimplementasikan semua fungsi virtual murni, class tersebut juga menjadi abstrak dan tidak dapat dibuat sebagai instance.
Fungsi virtual murni penting ketika base class tidak dapat menyediakan implementasi default yang bermakna. Setiap bentuk memiliki luas, tetapi tidak ada cara yang masuk akal untuk menghitung "luas bentuk umum" tanpa mengetahui tipe bentuk yang spesifik.
Tantangan
MudahMari kita bangun sistem pemrosesan pembayaran yang menunjukkan cara fungsi virtual murni menegakkan kontrak untuk berbagai metode pembayaran. Kamu akan membuat class dasar abstrak yang menentukan hal yang harus dilakukan setiap pemroses pembayaran, lalu menerapkan tipe pembayaran konkret yang memenuhi kontrak tersebut.
Kamu akan mengatur kodemu dalam tiga file:
PaymentProcessor.h: Definisikan class abstrakPaymentProcessoryang menjadi cetak biru untuk semua metode pembayaran. Class ini harus memiliki:- Member
std::string accountIdyang dilindungi - Konstruktor yang menginisialisasi ID akun
- Method virtual murni
processPayment(double amount): setiap tipe pembayaran harus menerapkannya dengan cara yang berbeda - Method virtual murni
getProcessorName()yang mengembalikanstd::string - Destruktor virtual
- Member
PaymentMethods.h: Terapkan dua pemroses pembayaran konkret yang mewarisiPaymentProcessor:CreditCardProcessor:- Member
double feePercentageprivat (tarif biaya transaksi) - Konstruktor yang menerima ID akun dan persentase biaya
- Terapkan
processPayment()untuk menghitung biaya (amount * feePercentage / 100), lalu mencetak:Credit Card [<accountId>]: Charged $<amount> (Fee: $<fee>) - Terapkan
getProcessorName()untuk mengembalikan"CreditCard"
BankTransferProcessor:- Member
std::string bankNameprivat - Konstruktor yang menerima ID akun dan nama bank
- Terapkan
processPayment()untuk mencetak:Bank Transfer [<accountId>] via <bankName>: Transferred $<amount> - Terapkan
getProcessorName()untuk mengembalikan"BankTransfer"
- Member
main.cpp: Baca empat input (masing-masing pada baris terpisah):- ID akun kartu kredit
- Persentase biaya kartu kredit (double)
- ID akun bank
- Nama bank
Buat kedua pemroses pembayaran dan simpan dalam array berisi pointer
PaymentProcessor*. Proses pembayaran sebesar100.0melalui setiap pemroses, dengan menampilkan nama pemroses sebelum setiap transaksi:Processing with <processorName>: <processPayment output>Cetak satu baris kosong di antara pemroses. Hapus object yang dialokasikan secara dinamis setelah selesai.
Contohnya, dengan input CC-4521, 2.5, BA-7890, dan National Bank:
Processing with CreditCard:
Credit Card [CC-4521]: Charged $100 (Fee: $2.5)
Processing with BankTransfer:
Bank Transfer [BA-7890] via National Bank: Transferred $100Karena PaymentProcessor memiliki fungsi virtual murni, kamu tidak dapat membuat instance-nya secara langsung: hanya implementasi konkret yang memenuhi kontrak yang dapat dibuat. Ini memastikan setiap metode pembayaran menyediakan logika pemrosesan spesifiknya sendiri.
Coba sendiri
#include <iostream>
#include <string>
#include "PaymentMethods.h"
using namespace std;
int main() {
// Baca input
string ccAccountId;
double feePercentage;
string bankAccountId;
string bankName;
getline(cin, ccAccountId);
cin >> feePercentage;
cin.ignore();
getline(cin, bankAccountId);
getline(cin, bankName);
// TODO: Buat array berisi 2 pointer PaymentProcessor*
// TODO: Buat object CreditCardProcessor dan BankTransferProcessor
// dan simpan keduanya dalam array
// TODO: Lakukan perulangan pada array dan untuk setiap processor:
// 1. Cetak "Processing with <processorName>:"
// 2. Panggil processPayment dengan jumlah 100.0
// 3. Cetak baris kosong di antara processor (bukan setelah yang terakhir)
// TODO: Hapus object yang dialokasikan secara dinamis
return 0;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar-Dasar OOP
File EksternalBuild dan Kompilasi C++File Header dan File SourceNamespace dan CakupanPengantar OOP dalam C++class vs objectPointer 'this'method (Fungsi Anggota)Atribut (Anggota Data)Dasar Ctor dan DtorRingkasan: Kalkulator Sederhana4Properti class
Anggota instance vs staticGetter dan setterFungsi anggota constKata kunci mutableMethod dan variabel staticFungsi dan class friendRangkuman, Pengelola Rekening Bank7Pewarisan
Pewarisan DasarTingkat Akses pada PewarisanUrutan Pemanggilan Ctor & DtorPenimpaan methodFungsi Virtual & VTablePewarisan BergandaPewarisan VirtualRangkuman: Hierarki Karyawan2Manajemen Memori
Memori Stack vs HeapPointer dan ReferenceMemori Dinamis (new/delete)Smart Pointer di C++RAII di C++Rangkuman: Pengelola Array Dinamis5Enkapsulasi
Penentu Akses dalam C++Penentu Akses secara MendalamPenyembunyian Informasistruct vs classNested dan Inner classRangkuman, Sistem Catatan Siswa8Polimorfisme
Polimorfisme saat Compile vs RuntimeOverloading FungsiMeninjau Kembali Fungsi VirtualFungsi Virtual MurniKelas AbstrakDesain Interface di C++Casting Dinamis & RTTIRangkuman: Kalkulator Bentuk3Konstruktor & Destruktor
Konstruktor DefaultKonstruktor BerparameterKonstruktor SalinKonstruktor PindahDaftar Inisialisasi KonstruktorKonstruktor DelegasiKupas Tuntas DestruktorAturan Tiga, Lima, dan NolRangkuman: class String6Overloading Operator
Pengantar Overloading OperatorOverloading Operator AritmetikaOverloading Operator PerbandinganOperator StreamOverloading Operator PenugasanOverloading Operator [] dan ()Operator Konversi TipeRingkasan, class Matrix9Template
Template FungsiTemplate classSpesialisasi TemplateTemplate VariadikDasar SFINAE & Type TraitsRangkuman, Container GenerikLatihan sendiri: Compiler C++ online