Jadi, saya bertanya-tanya apakah teknik ini benar-benar digunakan dalam praktek? Haruskah saya menggunakannya di mana-mana, atau dengan hati-hati?
Tentu saja itu digunakan. Saya menggunakannya dalam proyek saya, di hampir setiap kelas.
Alasan untuk menggunakan idiom PIMPL:
Kompatibilitas biner
Saat Anda mengembangkan pustaka, Anda dapat menambah / memodifikasi bidang XImpl
tanpa merusak kompatibilitas biner dengan klien Anda (yang berarti macet!). Karena tata letak biner X
kelas tidak berubah ketika Anda menambahkan bidang baru ke Ximpl
kelas, aman untuk menambahkan fungsionalitas baru ke perpustakaan dalam pembaruan versi kecil.
Tentu saja, Anda juga dapat menambahkan metode publik / swasta non-virtual ke X
/ XImpl
tanpa melanggar kompatibilitas biner, tetapi itu setara dengan header standar / teknik implementasi.
Menyembunyikan data
Jika Anda sedang mengembangkan perpustakaan, terutama yang eksklusif, mungkin diinginkan untuk tidak mengungkapkan apa perpustakaan / teknik implementasi lain yang digunakan untuk mengimplementasikan antarmuka publik perpustakaan Anda. Baik karena masalah Kekayaan Intelektual, atau karena Anda percaya bahwa pengguna mungkin tergoda untuk mengambil asumsi berbahaya tentang implementasi atau hanya memecahkan enkapsulasi dengan menggunakan trik casting yang mengerikan. PIMPL memecahkan / mengurangi itu.
Waktu kompilasi
Waktu kompilasi berkurang, karena hanya file sumber (implementasi) yang X
perlu dibangun kembali ketika Anda menambahkan / menghapus bidang dan / atau metode ke XImpl
kelas (yang memetakan untuk menambahkan bidang / metode pribadi dalam teknik standar). Dalam praktiknya, ini adalah operasi yang umum.
Dengan header standar / teknik implementasi (tanpa PIMPL), ketika Anda menambahkan bidang baru X
, setiap klien yang pernah mengalokasikan X
(baik di stack, atau di heap) perlu dikompilasi ulang, karena harus menyesuaikan ukuran alokasi. Yah, setiap klien yang tidak pernah mengalokasikan X juga perlu dikompilasi ulang, tetapi itu hanya overhead (kode yang dihasilkan di sisi klien akan sama).
Terlebih lagi, dengan header standar / pemisahan implementasi XClient1.cpp
perlu dikompilasi ulang bahkan ketika metode pribadi X::foo()
ditambahkan X
dan X.h
diubah, meskipun XClient1.cpp
tidak mungkin memanggil metode ini karena alasan enkapsulasi! Seperti di atas, ini murni overhead dan terkait dengan bagaimana sistem C ++ membangun kehidupan nyata bekerja.
Tentu saja, kompilasi ulang tidak diperlukan ketika Anda hanya memodifikasi implementasi metode (karena Anda tidak menyentuh header), tetapi itu setara dengan header standar / teknik implementasi.
Apakah teknik ini direkomendasikan untuk digunakan dalam sistem embedded (di mana kinerjanya sangat penting)?
Itu tergantung pada seberapa kuat target Anda. Namun satu-satunya jawaban untuk pertanyaan ini adalah: mengukur dan mengevaluasi apa yang Anda dapatkan dan kehilangan. Juga, pertimbangkan bahwa jika Anda tidak menerbitkan perpustakaan yang dimaksudkan untuk digunakan dalam sistem embedded oleh klien Anda, hanya keuntungan waktu kompilasi yang berlaku!
struct XImpl : public X
. Itu terasa lebih alami bagi saya. Apakah ada masalah lain yang saya lewatkan?