Saya melihat banyak kode sumber yang menggunakan idiom PImpl di C ++. Saya berasumsi bahwa tujuannya adalah untuk menyembunyikan data / tipe / implementasi pribadi, sehingga dapat menghapus ketergantungan, dan kemudian mengurangi waktu kompilasi dan header menyertakan masalah.
Tetapi antarmuka / kelas abstrak murni di C ++ juga memiliki kemampuan ini, mereka juga dapat digunakan untuk menyembunyikan data / tipe / implementasi. Dan untuk membiarkan pemanggil melihat antarmuka saat membuat objek, kita dapat mendeklarasikan metode pabrik di header antarmuka.
Perbandingannya adalah:
Biaya :
Cara antarmuka biaya lebih rendah, karena Anda bahkan tidak perlu mengulangi implementasi fungsi public wrapper
void Bar::doWork() { return m_impl->doWork(); }
, Anda hanya perlu mendefinisikan tanda tangan di antarmuka.Dipahami dengan baik :
Teknologi antarmuka lebih baik dipahami oleh setiap pengembang C ++.
Kinerja :
Cara kinerja antarmuka tidak lebih buruk daripada idiom PImpl, keduanya merupakan akses memori tambahan. Saya menganggap kinerjanya sama.
Berikut ini adalah kodesemu untuk mengilustrasikan pertanyaan saya:
// Forward declaration can help you avoid include BarImpl header, and those included in BarImpl header.
class BarImpl;
class Bar
{
public:
// public functions
void doWork();
private:
// You don't need to compile Bar.cpp after changing the implementation in BarImpl.cpp
BarImpl* m_impl;
};
Tujuan yang sama dapat diimplementasikan menggunakan antarmuka:
// Bar.h
class IBar
{
public:
virtual ~IBar(){}
// public functions
virtual void doWork() = 0;
};
// to only expose the interface instead of class name to caller
IBar* createObject();
Jadi apa gunanya PImpl?
Impl
kelas tidak akan merusakABI
, tetapi menambahkan fungsi publik di antarmuka akan merusakABI
.