Więc zastanawiam się, czy ta technika jest naprawdę używana w praktyce? Powinienem go używać wszędzie, czy ostrożnie?
Oczywiście, że jest używany. Używam go w swoim projekcie, na prawie wszystkich zajęciach.
Powody używania idiomu PIMPL:
Zgodność binarna
Kiedy tworzysz bibliotekę, możesz dodawać / modyfikować pola XImpl
bez naruszania zgodności binarnej z klientem (co oznaczałoby awarie!). Ponieważ układ binarny X
klasy nie zmienia się po dodaniu nowych pól do Ximpl
klasy, można bezpiecznie dodawać nowe funkcje do biblioteki w aktualizacjach wersji pomocniczych.
Oczywiście możesz również dodać nowe publiczne / prywatne niewirtualne metody do X
/ XImpl
bez naruszania zgodności binarnej, ale jest to porównywalne ze standardową techniką nagłówka / implementacji.
Ukrywanie danych
Jeśli tworzysz bibliotekę, zwłaszcza tę zastrzeżoną, może być pożądane, aby nie ujawniać, jakie inne biblioteki / techniki implementacji zostały użyte do zaimplementowania publicznego interfejsu Twojej biblioteki. Albo z powodu problemów z własnością intelektualną, albo dlatego, że uważasz, że użytkownicy mogą ulec pokusie przyjęcia niebezpiecznych założeń dotyczących implementacji lub po prostu złamać hermetyzację, używając okropnych sztuczek castingowych. PIMPL rozwiązuje / łagodzi to.
Czas kompilacji
Czas kompilacji jest skrócony, ponieważ tylko plik źródłowy (implementacyjny) X
musi zostać przebudowany podczas dodawania / usuwania pól i / lub metod do XImpl
klasy (co jest mapowane na dodawanie prywatnych pól / metod w standardowej technice). W praktyce to powszechna operacja.
Przy standardowej technice nagłówka / implementacji (bez PIMPL), kiedy dodajesz nowe pole do X
, każdy klient, który kiedykolwiek przydzielił X
(na stosie lub na stercie), musi zostać ponownie skompilowany, ponieważ musi dostosować rozmiar alokacji. Cóż, każdy klient, który nigdy nie przydzieli X, również musi zostać ponownie skompilowany, ale to tylko narzut (wynikowy kod po stronie klienta będzie taki sam).
Co więcej, przy standardowym rozdzieleniu nagłówka / implementacji XClient1.cpp
należy ponownie skompilować, nawet jeśli prywatna metoda X::foo()
została dodana X
i X.h
zmieniona, nawet jeśli XClient1.cpp
nie można jej wywołać z powodów hermetyzacji! Podobnie jak powyżej, jest to czysty narzut i jest związany z tym, jak działają rzeczywiste systemy kompilacji C ++.
Oczywiście rekompilacja nie jest potrzebna, gdy po prostu modyfikujesz implementację metod (ponieważ nie dotykasz nagłówka), ale jest to porównywalne ze standardową techniką nagłówka / implementacji.
Czy ta technika jest zalecana do stosowania w systemach wbudowanych (gdzie wydajność jest bardzo ważna)?
To zależy od tego, jak potężny jest twój cel. Jednak jedyną odpowiedzią na to pytanie jest: zmierz i oceń, co zyskujesz, a co tracisz. Weź również pod uwagę, że jeśli nie publikujesz biblioteki przeznaczonej do użytku w systemach wbudowanych przez twoich klientów, obowiązuje tylko przewaga czasu kompilacji!
struct XImpl : public X
. Wydaje mi się to bardziej naturalne. Czy jest jakiś inny problem, który przegapiłem?