Post by Maciej SobczakPost by Zbyszek Malecw ogólności nie zgadzam się, że C++ daje ogromną swobodę
podziału programu na moduły.
Swobodę daje *ogromną*, gorzej ze wsparciem. ;-)
Post by Zbyszek MalecCzekam z utęsknieniem na jakąś sensowną
pakietyzację w C++.
O, jest szansa na ciekawy wątek. :-)
Czego brakuje w obecnych mechanizmach?
(uwaga: nie twierdzę, że niczego.)
Na przykład, przydałoby się coś, co pozwalałoby uniknąć preprocesora z
#include :).
Przede wszystkim problem z C++ polega na tym, że pakietyzacja w tym
wykonaniu jest bazowana na tym, co posiada język C (oczywiście to
niewiele zmienia, że jest to jedyny model wiązania modułów na poziomie
systemowym w popularnych systemach operacyjnych). To polega na tym, że
posiadamy jedynie pliki nagłówkowe, które mogą zawierać cokolwiek, a
następnie w plikach *.o mogą się zawierać tylko i wyłącznie definicje
obiektów POD oraz skompilowane wersje funkcji plus odwołania do innych
symboli - wszystko określone odpowiednią nazwą symbolu. Czyli podlegać
wiązaniu mogą tylko obiekty "płaskie" oraz funkcje. Cała reszta musi
jakoś się do tego upchnąć. Nie mogą zatem podlegać wiązaniu wzorce,
czy klasy.
To, co by się przydało na dobry początek, to takie pliki *.o, które
potrafiłyby zawierać w sobie definicje wzorców i klas. Tak, żeby można
było się do nich odwoływać w trakcie kompilacji, czy żeby nawet to
rozwiązywał linker. Nie mówię, że należy się pozbyć plików
nagłówkowych (zresztą to byłoby niemożliwe, jeśli nie chcemy
całkowicie uniemożliwiać włączania bibliotek C) - tą koncepcję można
wykorzystać do jawnego dołączania odpowiednich elementów określonych
bibliotek.
Oczywiście byłby tutaj problem ze zrobieniem na bazie tej koncepcji
wiązania dynamicznego. Nie bardzo sobie wyobrażam np. w jaki sposób
wzorzec w dll-ce miałby się skonkretyzować podczas ładowania - ale
niewykluczone, że to jest do rozwiązania w jakiś sposób. W każdym
razie, na dobry początek wystarczy, żeby mogło się to wiązać
statycznie.
Co np. uważam, że jest niepotrzebnie wsadzane do plików nagłówkowych i
ta konieczność wynika tylko z ograniczeń:
- klasy
- funkcje inline
- wzorce (w sensie, pełne ich definicje)
Spróbujmy zrobić małe porównanie. Jak wiemy, jedną z możliwości
symulowania klasy w języku C jest zdefiniowanie wszystkiego, co
potrzebne, w jednym pliku *.c. Zmienne globalne z odpowiadającym
extern w *.h to publiczne zmienne statyczne. Zmienne 'static' to
prywatne zmienne statyczne. Funkcje bez żadnych specjalnych
właściwości to metody statyczne. Jeśli ta klasa ma mieć instancje, to
powinna mieć swoją własną strukturę, która jest zdefiniowana w pliku
*.c, a w *.h posiada jedynie deklarację. Konstruktorem byłaby funkcja,
która zwraca taki obiekt przez wskaźnik na ową strukturę. Metody
takiej klasy to funkcje, które przyjmują ten wskaźnik jako pierwszy
argument. Jeśli metoda nie ma swojego nagłówka w pliku *.h, to jest
prywatna.
Jak więc definicja takiej niby klasy będzie zatem wyglądać w języku C?
Plik *.h musi zawierać:
- extern do zmiennych (publiczne pola statyczne)
- extern do funkcji (publiczne metody zwykłe i statyczne)
- deklarację struktury (żeby mieć nazwę typu)
Dostęp do innych informacji - takich np. jak rozmiar obiektu - można
dostarczyć również za pomocą odpowiedniej funkcji, jeśli twórca klasy
tak sobie zażyczy.
Jeśli ktoś chce przykład czegoś istniejącego, stworzonego wedle tej
zasady, proszę zajrzeć sobie do <dirent.h>.
Odnosząc to teraz do C++, w pliku nagłówkowym powinno wystarczyć
zadeklarowanie:
- metod publicznych i chronionych
- pól publicznych i chronionych (jako bonus - w wersji C akurat nie
jest to możliwe; tam dostęp do pól trzeba by dorobić dodatkowo za
pomocą odpowiednich metod)
- zapowiedzi wzorców - funkcje tylko same deklaracje, a klasy wedle
schemtatu powyżej
Cała reszta powinna się móc zawrzeć w plikach *.cc
Niestety zastanawiając się nad tym modelem przychodzi mi do głowy
jedynie takie coś: albo pliki nagłówkowe (i pełna definicja klasy w
pliku nagłówkowym wyłącznie), albo pełna definicja klasy w pliku *.cc
(i bez pliku nagłówkowego).