Idiom Pimpl
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 78 dari 104.
Idiom Pimpl idiom (Pointer to Implementation) adalah teknik yang menyembunyikan detail implementasi sebuah class dengan memindahkannya ke class terpisah yang dideklarasikan terlebih dahulu. Teknik ini mengurangi dependensi kompilasi dan menjaga agar anggota privat benar-benar tersembunyi dari file header.
Ide intinya sederhana: alih-alih mendeklarasikan anggota privat secara langsung di class-mu, kamu mendeklarasikan pointer ke class implementasi yang hanya didefinisikan di file sumber:
// Widget.h
#include <memory>
class Widget {
public:
Widget();
~Widget();
void doSomething();
private:
class Impl; // Deklarasi awal
std::unique_ptr<Impl> pImpl;
};// Widget.cpp
#include "Widget.h"
#include <iostream>
class Widget::Impl {
public:
int data = 42;
void process() { std::cout << "Processing: " << data << "\n"; }
};
Widget::Widget() : pImpl(std::make_unique<Impl>()) {}
Widget::~Widget() = default;
void Widget::doSomething() { pImpl->process(); }Manfaat utamanya adalah firewall kompilasi dan kompatibilitas biner. Saat kamu mengubah class Impl, hanya file sumber yang perlu dikompilasi ulang, bukan setiap file yang menyertakan header. Hal ini sangat mempercepat waktu build dalam proyek besar.
Perhatikan bahwa destruktor harus didefinisikan di file sumber (meskipun menggunakan default) karena unique_ptr memerlukan tipe lengkap Impl untuk menghapusnya. Ini adalah kesalahan umum saat pertama kali menggunakan Pimpl.
Tantangan
MudahMari buat penangan pesan aman menggunakan idiom Pimpl untuk menyembunyikan detail implementasi enkripsi dari file header. Ini menunjukkan cara Pimpl membuat penghalang kompilasi: siapa pun yang menyertakan header-mu tidak akan melihat cara kerja internal pemrosesan pesan.
Kamu akan menyusun kodemu dalam tiga file:
SecureMessage.h: Definisikan antarmuka publik untuk classSecureMessagemilikmu.Class-mu harus memiliki class
Implyang dideklarasikan secara forward dan sebuahstd::unique_ptryang menunjuk kepadanya. Antarmuka publik harus mencakup:- Konstruktor yang menerima
const std::string&untuk pesan asli - Destruktor, yang harus dideklarasikan di sini dan didefinisikan di file .cpp
- Method
setKey(int key)untuk menetapkan kunci enkripsi - Method
getEncrypted()yang mengembalikan pesan terenkripsi sebagaistd::string - Method
getOriginal()yang mengembalikan pesan asli
Header hanya boleh menampilkan antarmuka publik: detail implementasi tentang cara kerja enkripsi tidak boleh terlihat di sini.
- Konstruktor yang menerima
SecureMessage.cpp: Definisikan class bersarangImpldan implementasikan semua method.Class
Implmilikmu harus menyimpan pesan asli, kunci enkripsi (nilai awalnya 0), dan menangani logika enkripsi yang sebenarnya. Gunakan sandi Caesar sederhana untuk enkripsi: geser setiap karakter sebanyak nilai kunci. Contohnya, dengan kunci 3, 'a' menjadi 'd', dan 'z' berputar kembali menjadi 'c'.Enkripsi hanya boleh memengaruhi huruf kecil (a-z), sementara semua karakter lainnya tetap tidak berubah. Ingat untuk mendefinisikan destruktor di sini, meskipun definisinya default, karena
unique_ptrmemerlukan tipeImplyang lengkap.main.cpp: Baca dua input:- String pesan, yang dapat berisi spasi
- Kunci enkripsi berupa bilangan bulat
Buat object
SecureMessage, tetapkan kuncinya, lalu tampilkan hasilnya:- Cetak
Original:diikuti pesan asli - Cetak
Encrypted:diikuti pesan terenkripsi
Contohnya, dengan input hello world dan 3:
Original: hello world
Encrypted: khoor zruogDengan input xyz abc dan 5:
Original: xyz abc
Encrypted: cde fghPerhatikan bahwa file header tidak mengungkapkan apa pun tentang implementasi sandi Caesar: itulah keunggulan Pimpl. Jika nanti kamu menggantinya dengan algoritma enkripsi lain, hanya SecureMessage.cpp yang perlu dikompilasi ulang, bukan setiap file yang menyertakan header.
Coba sendiri
#include <iostream>
#include <string>
#include "SecureMessage.h"
int main() {
// Baca pesan (mungkin mengandung spasi)
std::string message;
std::getline(std::cin, message);
// Baca kunci enkripsi
int key;
std::cin >> key;
// TODO: Buat object SecureMessage dengan pesan tersebut
// TODO: Atur kunci enkripsi
// TODO: Cetak "Original: " diikuti pesan asli
// TODO: Cetak "Encrypted: " diikuti pesan terenkripsi
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