2012-11-07 16 views
5

Szukałem kilku źródeł implementacji STL (SGI, STLport, libC++) i zobaczyłem kilka wzorców projektowych, które wydają się wspólne dla wszystkich lub większości implementacji, ale nie mogłem znaleźć żadnego powodu. Zakładam, że nie musi być dobrym reson, i chcą wiedzieć, co to jest:Uzasadnienie projektu za STL

  1. Wiele klas, w tym vector i list_iterator między innymi, zostały zaimplementowane jako 2 klasy, na przykład list_iterator_base z częścią funkcji, a następnie list_iterator, która dziedziczy list_iterator_base z resztą interfejsu. O co chodzi? Wydaje się, że można to zrobić tak łatwo w jednej klasie.

  2. Wygląda na to, że iteratory nie korzystają z klasy iterator. Czy za korzystanie z niej jest pewna kara za wydajność?

To są 2 pytania, które znalazłem w szybkim tempie. Jeśli ktokolwiek wie o dobrym źródle wyjaśniającym uzasadnienie implementacji STL, z przyjemnością się o tym dowiem.

+0

"Jumbo shrimp". –

+0

Należy zauważyć, że pod względem technicznym biblioteka STL i biblioteka standardowa (stdlib) są różne. Ten ostatni był w przeważającej części wyprowadzony z pierwszego, kiedy został dodany do oficjalnego standardu językowego. Prawie nikt nie używa już "prawdziwego" STL, ale zamiast tego używa implementacji standardowej biblioteki (np. LibC++). Wiele osób odnosi się do stdlib jako STL i tak jest zwykle dobrze, ale dla twojego pytania rozróżnienie zmienia znaczenie. – GManNickG

+0

@DaveNewton Nie rozumiem twojego komentarza. – baruch

Odpowiedz

7

Odpowiedzi są dość proste:

  1. STL jest wszystko na temat programowania generycznego. Kluczową ideą nie jest powtarzanie kodu. Bezpośrednim celem jest nie zduplikowanie kodu źródłowego, ale okazuje się, że nie ma powielania kodu binarnego. W związku z tym jest dość powszechne, że czynniki składowe STL często używają części i wykorzystują je. Łącza dla klasy listy lub niezależne od typu atrybuty wektora to tylko dwa przykłady. Wektory są nawet wielowarstwowe: niektóre części są całkowicie niezależne od typu (np. Rozmiar), inne potrzebują tylko samego typu (np. Wszystkie akcesory, iteratory itp.), A niektóre części muszą wiedzieć jak zajmować się alokacją zasobów (np. wstawianie i niszczenie musi wiedzieć o używanym alokatorze).
  2. Okazuje się, że std::iterator<...> tak naprawdę nie działa: typy zdefiniowane w klasach bazowych w zależności od parametrów szablonu nie są bezpośrednio dostępne w szablonie klasy pochodzącym z takiej podstawy. Oznacza to, że typy muszą być kwalifikowane za pomocą klasy bazowej i muszą być oznaczone jako typy przy użyciu typename. Co gorsza, użytkownicy mogliby teoretycznie przydzielić obiekty klasy pochodnej i zwolnić je przez wskaźnik do std::iterator<...> (tak, byłoby to głupotą). Oznacza to, że nie ma korzyści, ale potencjalna wada, to jest najlepiej jej unikać.

To powiedziawszy, nie jestem świadomy żadnego dobrego zasobu obejmującego techniki wdrażania bibliotek generycznych. Większość szczegółów zastosowanych w implementacjach STL zostało niezależnie wynalezionych przez wiele osób, ale literatura dotycząca programowania ogólnego jest nadal stosunkowo rzadka. Nie sądzę, aby któryś z artykułów opisujących STL omawiał techniki implementacji: zwykle koncentrują się na szczegółach projektu. Biorąc pod uwagę, że niewiele osób zdaje się rozumieć, czym jest STL, nie jest wielkim zaskoczeniem, że autorzy koncentrują się raczej na opisywaniu tego, czym jest STL, a nie na sposobie jego implementacji.

+0

Odnośnie punktu 2: Jeśli to nawet nie działa, dlaczego to się dzieje? Dlaczego kiedykolwiek został dodany do standardowej biblioteki? – baruch

Powiązane problemy