PIMPL Idiom (PImpl idiyomu) - 1

12:12 , ,
"Pointer based IMPlementation" veya daha yaygın/kısa ismiyle PImpl bir C++ programlama tekniğidir. Neden böyle bir kullanım yöntemi geliştirilmiştir derseniz:
  • Derleme bağımlılıkları azaltarak yapılacak değişikliklerden kullanıcı kodlarını en az etkilenmesini sağlama
  • Kaynak kodun dış dünyaya açılmasını önleme
gibi iki temel ihtiyacı karşılaması içindir. Bunun için temelde bir pointer ve bir sınıf kullanılmaktadır.

PImpl bir yönüyle compiler firewall'u gibi calışmaktadır 
Bu noktada programlamaya ilişkin iki temel kavram açıklamak gerekir:
  • Başlık dosyası (Header file, .h,.hpp, ...) : hangi sınıfları/fonksiyonları dış dünyaya açtığınızı ve nasıl kullanılacağını gösterir. Dış dünyayla paylaşılması gereken dosyadır.
  • Binary dosyalar (.lib, .dll, .a, .so, ...) : .c, .cpp, .cxx, ... dosyaların derlenmiş halleri ve başlık dosyaları ile birlikte verilecek 2. dosyadır.
.h gibi başlık dosyaları 3. kişilere verilmesi gereken ve içine yazılan her şeyi karşı tarafın açık bir şekilde görebileceği dosyalardır. Bu nedenle PImpl idiyomu bize kısaca başlık dosyasına daha az kaynak kod yazmamıza (yaptığınız implementasyonun detaylarını gizlemek ve başlık dosyalarında çok sık değişiklik yapmamaya çalışmak) olanak sağlayan idiyomdur.

cripto.h başlık dosyası
Yukarıdaki kodda görüleceği üzere sınıfın dış dünyaya açtığı iki tane fonksiyon bulunmakta ve PImpl idiyomunu gerçekleştirmek için private bölüme iki temel bildirim yapılmış.

cripto.cpp kaynak kod dosyası
Yukarıdaki kaynak kodun kullanıcı tarafından görülemeyeceğini düşünürsek yaptığımız ikinci bir sınıf kodunun hiç bir şekilde (reverse edilmediğini varsayarsak :) dışarıya sızmayacağı ve cripto.cpp dosyasında yapılacak bir değişiklik için kullanıcı tarafında bir derleme işlemine gerek olmamakta, sadece yeni derlenmiş .so benzeri dosyanın paylaşılması yeterli olacaktır.

cripto.cpp kaynak kod dosyası (Devam)
Yukarıdaki kodda dikkat çekmek istediğim nokta ise constructor tanımlaması yapılırken pImpl'ye atama yapıldığının gözden kaçmamasıdır. Atama işlemini unutmanız halinde program segmentation fault ile sonlanacaktır.

main.cpp kaynak kod dosyası
Yazdığımız yukarıdaki kodda tamamen tasarımsal olarak 2 farklı şekilde nesne tanımlaması yapılabilmekte ve buna ilişkin test amaçlı yazdığımız kod görülmektedir.

Note:

  • Yardımcı olması açısından Linux için derleme parametreleri:
    g++ -std=c++11 -O2 -Wall -c cripto.cpp
    g++ -std=c++11 -O2 -Wall main.cpp cripto.o -o pimpl
    ./pimpl