C++ ile PIMPL IDIOM Nedir?
Herkese merhabalar, bu yazımızda sizlerle C++ programlama dilinde bizlere dciddi derecede kolaylık sağlayan PIMPL Idiom hakkında konuşacağız ve örnekler yapacağız.Hadi Başlayalım
C++ programlarında header dosyalarında sınıfların değişkenleri ve fonksiyonları tanımlanır. Bu yüzden header dosyalarında herhangi bir değişiklik yapıldığında, ilgili header dosyasını include eden bütün sınıflar yeniden derlenir. Büyük projelerde bu durum fazlaca vakit kaybına sebep olmaktadır. PIMPL Idiom tekniği sayesinde sınıfların kendi implementasyonlarını böleriz ve sadece ilgili sınıfın derlenmesini sağlarız. Bu sayede vakit kaybı önlenmiş olmaktadır.
Ayrıca PIMPL Idiom ile sınıf içerisindeki private tanımlamaları diğer sınıflardan tam olarak izole edebilmekteyiz. Bu sayede ilgili header dosyası değiştiğinde ilgili bütün sınıfın yeniden derlenmesi yerine sadece değişiklik yapılan implementasyon sınıfı yeniden derlenecektir. İlgili implementasyon sınıfına ise tanımlanan bir pointer aracılığı ile erişebileceğiz.
Ayrıca tanımlanan bir constructor ve destructor metodları yardımı ile de PIMPL sınıfının pointer tanımlamasını akıllı pointer haline getiririz ve derleyici copy constructor mantığı ile onada bir constructor ve destructor tanımlar. Ek olarak yazmaya gerek kalmaz.
PIMPL Idiom Pointer to Implementation ifadesinin kısaltılmış halidir. Pimpl Idiom ile aynı sınıfa include eden sınıfların private Implementasyonları ayrılır ve kendi implementasyon sınıflarında tanımlanırlar. Beraberinde bir pointer aracılığı ile erişim sağlanmasına olanak tanınır.
PIMPL Idiom nasıl uygulanır.
Şimdi örneğimize geçelim.
theclass.h
#include <iostream>
#include <QString>
//unique_ptr için gerekli olan kütüphane
#include <memory>
using namespace std;
//Sınıf prototip tanımlaması
class TheClassImpl;
class TheClass
{
public:
//Default constructor ve Destructor
explicit TheClass();
~TheClass();
//Copy Constructor
TheClass(const TheClass& rhs);
TheClass& operator=(const TheClass& rhs);
//Getter ve Setter metodlar
void set(QString name, QString surname);
QString get() const;
private:
const TheClassImpl* Pimpl() const { return pimpl.get(); }
TheClassImpl* Pimpl() { return pimpl.get(); }
std::unique_ptr<TheClassImpl> pimpl;
};
Bu tanımlamada unique_ptr kullanmamızın amacı programın hayat döngüsü boyunca bellekten silinmeden hep aynı adresinde tutulmasını sağlamaktır.
Şimdi sınıfımızın tanımlamalarını ve implementasyon sınıfımızın tanımlamalarını yapalım.
theclass.cpp
#include "theclass.h"
class TheClassImpl
{
private:
QString name;
QString surname;
public:
~TheClassImpl() = default;
void setNameSurname(QString _name, QString _surname)
{
name = _name;
surname = _surname;
}
QString getNameSurname() const
{
return name + " "+ surname;
}
};
TheClass::TheClass() : pimpl(new TheClassImpl()){ }
TheClass::~TheClass() = default;
TheClass::TheClass(const TheClass& rhs) : pimpl(new TheClassImpl(*rhs.pimpl))
{}
TheClass& TheClass::operator=(const TheClass& rhs) {
if (this != &rhs)
pimpl.reset(new TheClassImpl(*rhs.pimpl));
return *this;
}
void TheClass::set(QString name, QString surname)
{
Pimpl()->setNameSurname(name, surname);
}
QString TheClass::get() const
{
return Pimpl()->getNameSurname();
}
Burada implementasyon sınıfının tanımlaması yapıldı ve kullanacak oluğumuz sınıftan ilgili metodlar yazılarak getter ve setter metodları çağrıldı. Bu metodlar üzerinden PIMPL sınıfına erişilerek gerekli işlemler yapıldı.
Son olarak main fonksiyonumuzdan sınıfımızı çağırarak kullanımı görmüş olalım.
main.cpp
#include <QCoreApplication>
#include <iostream>
#include "theclass.h"
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
system("title C++ PIMPL IDIOM Example - Thecodeprogram");
cout << "C++ ile PIMPL IDIOM örneğine hoşgeldiniz..." << endl << endl;
TheClass *mc = new TheClass();
mc->set("Burak Hamdi", "TUFAN");
QString v = mc->get();
cout << v.toUtf8().constData() << endl << endl;
return a.exec();
}
PIMPL Tekniğinin avantajları:
PIMPL Tekniğinin Dezavantajları
Bu yazımızda buraya kadar.
Burak Hamdi TUFAN
Comments