Wstęp do programowania 2
Transkrypt
Wstęp do programowania 2
Wstęp do programowania 2 wykład 6 typy dostępu – c.d Agata Półrola Wydział Matematyki UŁ 2005/2006 http://www.math.uni.lodz.pl/~polrola Przykład wykorzystania typów dostępu zob. pakiet rodzajowy listapak (lista sortowana) type box; type wsk_box is access box; type box is record dane: integer; nast: wsk_box; end record; Deklaracja stałych Można deklarować stałe typu dostępu c: constant wsk_box := new box'(0,null); przy deklaracji konieczne jest nadanie wartości początkowej ‘bycie stałą’ oznacza w tym przypadku, że wartość typu dostępu musi cały czas odwoływać się do tego samego obiektu wartość ‘wskazywanego’ obiektu można zmienić c: constant wsk_box := new box'(0,null); l:wsk_box:=new box'(1,null); c.all := l.all; --c:=l; -- niepoprawne sposób obsługi stałych typu dostępu wyjaśnia również sposób przekazywania elementów typu dostępu jako parametrów podprogramów function suma(p: wsk_box) return integer is pom:wsk_box :=p; s: integer :=0; begin while pom /= null loop s := s + pom.dane; end loop; return s; end suma; Przekazywanie parametrów podprogram operuje na kopii zmiennej będącej parametrem w przypadku parametru w trybie ‘out’ jego wartość jest kopiowana do podprogramu, aby zapobiec losowym odwołaniom Pool-specific access types Poznane dotychczas typy dostępu są typami „pool-specific” nowe obiekty są alokowane w obszarze pamięci (storage pool) skojarzonym z danym typem dostępu obszar skojarzony z typem dostępu przestaje istnieć gdy skończy się zasięg widoczności tego typu obiekty do których odwołujemy się za pomocą „pool – specific access types” muszą być obiektami zaalokowanymi za pomocą new b:box; w: wsk_box := b; -- niepoprawne Ograniczenie to nie występuje w przypadku tzw. ogólnych typów dostępu (general access types) W przypadku gdy zaalokowany obiekt przestaje być dostępny (nie odwołuje się do niego żadna wartość typu dostępu) zajmowana przez niego pamięć może zostać automatycznie zwolniona (garbage collection). w praktyce jest to zaimplementowane w niewielu kompilatorach w1: wsk_int_1 := new integer'(2); w2: wsk_int_2 := new integer'(4) w1.all := w2.all; -- w1 := w2; -- niedozwolone Nie ma możliwości konwersji jednego „pool-specific access type” na inny (nawet w pokazany wyżej sposób). Wartość typu dostępu może odwoływać się tylko do obiektów w „swoim” obszarze. Sposoby inicjowania zmiennej a: array(1..10) of wsk_box := (1..10 => new box); -- alokacja 10 obiektów b1,b2: wsk_box := new box; -- alokacja 2 obiektów nn: wsk_box := new box'(1,null); ll: wsk_box := new box'(nn.all); i: integer := 2; nnn: wsk_int := new integer'(i); Zakresy Typy dostępu mogą odwoływać się do: podtypów type wsk_pos is access positive; type wsk_pos1 is access integer range 1 .. integer'last; wp : wsk_pos := new positive'(10); wp1 : wsk_pos := new integer'(10); wp2 : wsk_pos := new integer'(0); -- Constraint_Error tablic zawężonych lub niezawężonych type tab is array (integer range <>,integer range <>) of float; type wsk_tab is access tab; wt,wt1 : wsk_tab; -- przy alokacji trzeba podać rozmiar: wt := new tab'(1..10 => (1..10 => 0.0)); wt1 := new tab(1..5,1..5); -- niedozwolone: wt1 := new tab; wt, wt1 mogą odwoływać się do tablic różnego rozmiaru po zaalokowaniu rozmiar tablicy nie może być zmieniany subtype wsk_tab_3 is wsk_tab(1..3,1..3); wt3: wsk_tab_3; -- odpowiednik wt33 : wsk_tab(1..3,1..3); subtype tab3 is tab(1..3,1..3); wt3 := new tab3; wt33 := new tab3'(others=>(others=>0.0)); Odwołanie do elementów tablic: wt := new tab'(1..10 => (1..10 => 0.0)); wt1 := new tab(1..5,1..5); wt(1,1) := 0.1; wt.all := (others=> (others=> 0.1)); Typy dostępu mogą odwoływać się do innych typów dostępu type wsk_int is access integer; wi: wsk_int := new integer'(4); type wsk_wsk is access wsk_int; www: wsk_wsk; begin www:=new wsk_int; www.all := wi; put(www.all.all); www.all.all := 2; General access types Dotychczas poznane typy dostępu umożliwiały operacje na elementach tworzonych dynamicznie (alokowanych za pomocą new) Typy dostępu mogą służyć do odwoływania się do obiektów zadeklarowanych statycznie. Są to tzw. ogólne typy dostępu (general access types). type wsk_int_G is access all integer; i: aliased integer:=0; wii: wsk_int_G; wii:=i'access; można czytać i modyfikować wartość zmiennej „i” za pomocą zmiennej typu dostepu w deklaracji typu dostępu używamy słowa „all”, zmienne do których odwołujemy się w powyższy sposób deklarujemy jako „aliased” ostrzeżenie dla programisty (zmienna może być modyfikowana niebezpośrednio) informacja dla kompilatora (nie należy przydzielać miejsca na zmienną w niestandardowy sposób uniemożliwiający późniejsze odwołanie) Ograniczenie dostepu Możemy ograniczyć dostęp do zmiennej tak, aby zmienne (i stałe) były „tylko do odczytu” type wsk_int_C is access constant integer; i: aliased integer; ic: aliased constant integer := 1212; wii: wsk_int_C; wii:=i'access; -- dostep do zmiennej wii:=ic'access; -- dostep do stalej Dostęp do elementów tablic składowe tablicy również mogą być zadeklarowane jako „aliased” tabi : array(1..100) of aliased integer; type wsk_int_G is access all integer; wii:= wsk_int_G; wii:= tabi(i)'access; Dostęp do pól rekordu można również deklarować jako „aliased” pola rekordu type komorka is record i: aliased integer; j: integer; end record; type wsk_int_G is access all integer; wii:= wsk_int_G; k: komorka; wii:=k.i'access; Konwersja typów konwersja dla „pool-specific access types” nie jest dozwolona konwersja między „general access type” jest możliwa: wskazywane typy muszą być takie same zakresy podtypów muszą być zgodne typ dostępu „tylko do odczytu” nie może być przekonwertowany na typ dostępu do zmiennej „pool-specific type” może być przekonwertowany do „general access type”, ale nie odwrotnie