Menu
CoddyTech

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.

challenge icon

Tantangan

Mudah

Mari 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 class SecureMessage milikmu.

    Class-mu harus memiliki class Impl yang dideklarasikan secara forward dan sebuah std::unique_ptr yang 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 sebagai std::string
    • Method getOriginal() yang mengembalikan pesan asli

    Header hanya boleh menampilkan antarmuka publik: detail implementasi tentang cara kerja enkripsi tidak boleh terlihat di sini.

  • SecureMessage.cpp: Definisikan class bersarang Impl dan implementasikan semua method.

    Class Impl milikmu 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_ptr memerlukan tipe Impl yang lengkap.

  • main.cpp: Baca dua input:
    1. String pesan, yang dapat berisi spasi
    2. Kunci enkripsi berupa bilangan bulat

    Buat object SecureMessage, tetapkan kuncinya, lalu tampilkan hasilnya:

    1. Cetak Original: diikuti pesan asli
    2. Cetak Encrypted: diikuti pesan terenkripsi

Contohnya, dengan input hello world dan 3:

Original: hello world
Encrypted: khoor zruog

Dengan input xyz abc dan 5:

Original: xyz abc
Encrypted: cde fgh

Perhatikan 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;
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler C++ online