Discussion:
Pytanie dot. TObjectList
(Wiadomość utworzona zbyt dawno temu. Odpowiedź niemożliwa.)
Tadeusz Bodalski
2006-03-26 09:32:51 UTC
Permalink
Pytam, bo w helpie nic na ten temat nie znalazłem.
O oto mój problem:

Napisałem klasę TMojaKlasa, pochodną TObjectList do przechowywania
kilku obiektów typu np. TJakasKlasa;

np.
TMojaKlasa = class(TObjectList)
constructor Create;
destructor Destroy;
...
....
end;

destruktora napisałem tak:

destructor TMojaKlasa.Destroy
begin
for i:=0 to count-1 do (Items[i] as TJakasKlasa).Free;
inherited;
end;

Podczas niszczenia, tzn. wywołania TMojaKlasa.Free wywala błąd.
(a konkretnie podczas wywoływania dziedziczonego destruktora, tzn.
program wywala się na "inherited");

Jeśli w destruktorze usunę pierwszą linię, tzn. niszczenie przechowywanych
obiektów - nie wywala błędu. I moje pytanie:

- czy TObjecList sam niszczy przechowywane obiekty?
- jeśli tak, to dlaczego wywala błąd jeśli ja je sam najpierw zniszczę?

Tadek
Sorrow
2006-03-26 10:19:31 UTC
Permalink
Post by Tadeusz Bodalski
Napisałem klasę TMojaKlasa, pochodną TObjectList do przechowywania
kilku obiektów typu np. TJakasKlasa;
- czy TObjecList sam niszczy przechowywane obiekty?
Konstruktor TObjectList o ile kojarzę ma parametr ownsObjects, który
domyślnie jest true.
Odpowiedź na pytanie zależy zatem od wartości tego parametru. Jeśli go
pomijasz, to tak - sam niszczy.
Post by Tadeusz Bodalski
- jeśli tak, to dlaczego wywala błąd jeśli ja je sam najpierw zniszczę?
Pewnie szczegóły implementacji TObjectList, bo nic innego nie przychodzi mi
do głowy.

Pozdrawiam,
Sorrow.
NoBy
2006-03-26 10:48:44 UTC
Permalink
Post by Tadeusz Bodalski
destructor TMojaKlasa.Destroy
begin
for i:=0 to count-1 do
// tak powinno być dobrze
FreeAndNil(Items[i] as TJakasKlasa)
Post by Tadeusz Bodalski
inherited;
end;
Tyle że lepiej chyba jak poniżej

destructor TMojaKlasa.Destroy
begin
// jeżeli już koniecznie chcesz zniszczyć obiekty z listy
// nie respektując właściwości OwnsObjects
OwnsObjects:= true;
inherited
end;

A tak właściwie to zalecaną praktyką jest

TMyObjectList = class(TObject)
private
fObjects: TObjectList;
// ...
end;

zamiast dziedziczenia po TObjectList. IMO słusznie (przynajmniej w
typowych zastosowaniach).
--
NoBy MD5: 486cf5eee849c8de7bb630e4aaa8b761
NoBy
2006-03-26 10:50:02 UTC
Permalink
Post by Tadeusz Bodalski
destructor TMojaKlasa.Destroy
begin
for i:=0 to count-1 do
// tak powinno być dobrze
FreeAndNil(Items[i])
Post by Tadeusz Bodalski
inherited;
end;
Tyle że lepiej chyba jak poniżej

destructor TMojaKlasa.Destroy
begin
// jeżeli już koniecznie chcesz zniszczyć obiekty z listy
// nie respektując właściwości OwnsObjects
OwnsObjects:= true;
inherited
end;

A tak właściwie to zalecaną praktyką jest

TMyObjectList = class(TObject)
private
fObjects: TObjectList;
// ...
end;

zamiast dziedziczenia po TObjectList. IMO słusznie (przynajmniej w
typowych zastosowaniach).
--
NoBy MD5: 486cf5eee849c8de7bb630e4aaa8b761
Tygrys
2006-03-26 11:15:02 UTC
Permalink
Post by NoBy
A tak właściwie to zalecaną praktyką jest
TMyObjectList = class(TObject)
private
fObjects: TObjectList;
// ...
end;
zamiast dziedziczenia po TObjectList. IMO słusznie (przynajmniej w
typowych zastosowaniach).
A kto tak zaleca i dlaczego?

Tygrys
Zeman
2006-03-26 11:38:28 UTC
Permalink
Post by Tygrys
Post by NoBy
A tak właściwie to zalecaną praktyką jest
TMyObjectList = class(TObject)
private
fObjects: TObjectList;
// ...
end;
zamiast dziedziczenia po TObjectList. IMO słusznie (przynajmniej w
typowych zastosowaniach).
A kto tak zaleca i dlaczego?
Wlasnie - podobnie jak Tygrys jestem ciekaw dlaczego ?

Pozwiodronka,
Zeman.
NoBy
2006-03-26 21:21:12 UTC
Permalink
Post by Zeman
Post by Tygrys
A kto tak zaleca i dlaczego?
Wlasnie - podobnie jak Tygrys jestem ciekaw dlaczego ?
Głównie enkapsulacja. Dziedzicząc po TObjectList udostępnia się
wszystkie jego publiczne właściwości i metody. Jeżeli nie dodaje się
do TObjectList żadnych dodatkowych funkcjonalności, tylko składuje
się obiekty jakiegoś pojedyńczego typu (chyba zdecydowana większość
zastosowań), to dostęp w klasie potomnej do sekcji public TObjectList
jest raczej niepożądany.

Można też upublicznić tylko potrzebne właściwości i metody i trochę
je dostosować do rodzaju składowanych obiektów.

TMyClass = class(TObject)
private
fObjects: TObjectList;

public
property Items[Index: Integer]: TKonkretnaKlasa; default;
function Add(AObject: TKonkretnaKlasa): Integer;
// chyba lepiej mieć TKonkretnaKlasa zamiast TObject?
// względnie TKonkretnaKlasaBazowa zamiast TObject

// przy dziedziczeniu jest tu
// property List: PPointerList;
// to chyba niezbyt dobrze?
// property OwnsObjects: Boolean;
// też chyba często też jest tu raczej niepożądane?

// ...

end;

A kto pisze? OIDP to na BDNie było o tym obszerniej napisane w
jakichś (chyba nawet dwóch) artykułach. Z.G. na About Delphi
Programming też chyba coś o tym pisał, ale ZTCP to właśnie powołując
się na w.w artykuły.
--
NoBy MD5: 486cf5eee849c8de7bb630e4aaa8b761
Tygrys
2006-03-27 07:22:55 UTC
Permalink
Post by NoBy
Post by Zeman
Post by Tygrys
A kto tak zaleca i dlaczego?
Wlasnie - podobnie jak Tygrys jestem ciekaw dlaczego ?
Głównie enkapsulacja. Dziedzicząc po TObjectList udostępnia się
wszystkie jego publiczne właściwości i metody. Jeżeli nie dodaje się
do TObjectList żadnych dodatkowych funkcjonalności, tylko składuje
się obiekty jakiegoś pojedyńczego typu (chyba zdecydowana większość
zastosowań), to dostęp w klasie potomnej do sekcji public TObjectList
jest raczej niepożądany.
To bardzo zależy, co chcesz osiągnąć. Jeżeli chcesz mieć funkcjonalność
TObject list to lepiej odziedziczyć, bo dodajesz tylko nowe funkcje
specyficzne dla Twojej klasy.

Jeżeli chcesz natomiast zawęzić funkcjonalność, to oczywiście możesz użyć
enkapsulacji, ale wtedy wszystkie właściwości Twojej klasy musisz napisać
sam. I do każdego odwołania do obiektu wewnętrznego dokładasz dodatkowy czas
na przejście Twoich metod.

Nie jest złotą regułą wybór tego drugiego rozwiązania, zależy to bardzo od
celu, jaki dana klasa ma spełnić.

Np. zobacz: TObjectList dziedziczy z TList a TStringList zawiera wewnętrznie
TList.
Post by NoBy
Można też upublicznić tylko potrzebne właściwości i metody i trochę
je dostosować do rodzaju składowanych obiektów.
TMyClass = class(TObject)
private
fObjects: TObjectList;
public
property Items[Index: Integer]: TKonkretnaKlasa; default;
function Add(AObject: TKonkretnaKlasa): Integer;
// chyba lepiej mieć TKonkretnaKlasa zamiast TObject?
// względnie TKonkretnaKlasaBazowa zamiast TObject
To samo można uzystać przez dziedziczenie (zobacz TObjectList)
Post by NoBy
// przy dziedziczeniu jest tu
// property List: PPointerList;
// to chyba niezbyt dobrze?
Daje bardzo szybki dostęp go obiektów z listy, to czy to dobrze czy źle
zależy od przeznaczenia klasy.
Post by NoBy
// property OwnsObjects: Boolean;
// też chyba często też jest tu raczej niepożądane?
Jw, zależy do czego jest klasa.
Post by NoBy
A kto pisze? OIDP to na BDNie było o tym obszerniej napisane w
jakichś (chyba nawet dwóch) artykułach. Z.G. na About Delphi
Programming też chyba coś o tym pisał, ale ZTCP to właśnie powołując
się na w.w artykuły.
Traktuj to jako wskazówkę, a nie jako przykazanie.

Tygrys
NoBy
2006-03-27 17:34:12 UTC
Permalink
Post by Tygrys
Zeman pisze w
Post by Zeman
Wlasnie - podobnie jak Tygrys jestem ciekaw dlaczego ?
Głównie enkapsulacja. Dziedzicząc po TObjectList udostępnia się
wszystkie jego publiczne właściwości i metody. Jeżeli nie
dodaje się do TObjectList żadnych dodatkowych funkcjonalności,
tylko składuje się obiekty jakiegoś pojedyńczego typu (chyba
zdecydowana większość zastosowań), to dostęp w klasie potomnej
do sekcji public TObjectList jest raczej niepożądany.
To bardzo zależy, co chcesz osiągnąć. Jeżeli chcesz mieć
funkcjonalność TObject list to lepiej odziedziczyć, bo dodajesz
tylko nowe funkcje specyficzne dla Twojej klasy.
Tutaj chyba jeszcze ze mną nie polemizujesz?
Post by Tygrys
Jeżeli chcesz natomiast zawęzić funkcjonalność, to oczywiście
możesz użyć enkapsulacji, ale wtedy wszystkie właściwości Twojej
klasy musisz napisać sam.
Funkcjonalności TObjectList nie zawężam. A jeżeli chodzi ci o
zawężanie funkcjonalności "mojej" klasy to:
- Zawężanie funkcjonalności jednocześnie zmniejsza ilość właściwości
i metod, które muszę sam dopisać;
- Właściwości i metod które muszę dopisać, jest w większości wypadków
mniej, niż gdybym poprawiał właściwości i metody przy dziedziczeniu -
w obu przypadkach dopisuję function Add(AObject: TMyClass): Integer;
- Jeżeli zawężam, to _chcę_ enkapsulować.
Post by Tygrys
I do każdego odwołania do obiektu
wewnętrznego dokładasz dodatkowy czas na przejście Twoich metod.
Hmm...

function Add(aObject: TMyClass): Integer;
begin
Result:= fMyList.Add(aObject)
end;

function Add(aObject: TMyClass): Integer;
begin
Result:= inherited Add(aObject)
end;
Post by Tygrys
Nie jest złotą regułą wybór tego drugiego rozwiązania, zależy to
bardzo od celu, jaki dana klasa ma spełnić.
Nie jest. Ale ja nie piszę, że jest.
Post by Tygrys
Np. zobacz: TObjectList dziedziczy z TList a TStringList zawiera
wewnętrznie TList.
Co chyba potwierdza tezę, o dziedziczeniu w przypadku rozbudowy
funkcjonalności i użyciu jako pola gdy potrzebujemy tylko
funkcjonalności TObjectList? W TObjectList trzeba było ponadpisywać
wszystkie metody z Pointer. TObjectList, nadal tak jak TList, jest
taką generyczną listą ogólnego zastosowania?
Post by Tygrys
Można też upublicznić tylko potrzebne właściwości i metody i
trochę je dostosować do rodzaju składowanych obiektów.
TMyClass = class(TObject)
private
fObjects: TObjectList;
public
property Items[Index: Integer]: TKonkretnaKlasa; default;
function Add(AObject: TKonkretnaKlasa): Integer;
// chyba lepiej mieć TKonkretnaKlasa zamiast TObject?
// względnie TKonkretnaKlasaBazowa zamiast TObject
To samo można uzystać przez dziedziczenie (zobacz TObjectList)
Niby to samo, tyle że masz dodatkowo enkapsulację jako premię.
Post by Tygrys
// przy dziedziczeniu jest tu
// property List: PPointerList;
// to chyba niezbyt dobrze?
Daje bardzo szybki dostęp go obiektów z listy, to czy to dobrze
czy źle zależy od przeznaczenia klasy.
Jeszcze nigdy nie musiałem aż tak rozpaczliwie szukać szybkości
działania programu, ale nie zaprzeczam, że komuś mogło sie zdarzyć.
Tylko czy ja wiem, czy wtedy TObjectList byłby dobrym rozwiązaniem?
Post by Tygrys
// property OwnsObjects: Boolean;
// też chyba często też jest tu raczej niepożądane?
Jw, zależy do czego jest klasa.
Jw ;P~ Zestaw procentowo przypadki kiedy potrzebujesz, z
przypadkami kiedy nie potrzebujesz.
Post by Tygrys
A kto pisze? OIDP to na BDNie było o tym obszerniej napisane w
jakichś (chyba nawet dwóch) artykułach. Z.G. na About Delphi
Programming też chyba coś o tym pisał, ale ZTCP to właśnie
powołując się na w.w artykuły.
Traktuj to jako wskazówkę, a nie jako przykazanie.
Hmm... Widziałeś mnie kiedyś w kapturze, biegającego z pochodnią po
firmach programistyczych i palącego wszystkich, którzy się
sprzeciwiają?
--
NoBy MD5: 486cf5eee849c8de7bb630e4aaa8b761
Zeman
2006-03-27 17:44:27 UTC
Permalink
jeszcze wazny argument - jak sie dziedziczy po TObjectList mozna korzystac z
polimorfizmu. Jesli zas liste sie zamknie w polu, polimorfirmu nie ma ;) W
niektorych przypadkach ten argument moze byc duzym atutem, w niektorych nie.

Pozwiodronka,
Zeman.
NoBy
2006-03-28 17:58:06 UTC
Permalink
Post by Zeman
jeszcze wazny argument - jak sie dziedziczy po TObjectList mozna
korzystac z polimorfizmu. Jesli zas liste sie zamknie w polu,
polimorfirmu nie ma ;) W niektorych przypadkach ten argument
moze byc duzym atutem, w niektorych nie.
No a tu dla odmiany polemizować nie zamierzam ;)
--
NoBy MD5: 486cf5eee849c8de7bb630e4aaa8b761
Tygrys
2006-03-27 21:46:11 UTC
Permalink
Post by NoBy
Funkcjonalności TObjectList nie zawężam. A jeżeli chodzi ci o
- Zawężanie funkcjonalności jednocześnie zmniejsza ilość właściwości
i metod, które muszę sam dopisać;
To zależy, co chcesz otrzymać. Ja np. dodając do objectlist funkcję zapisu
na dysk dodaję jedną funkcję.
Gdybym chciał to zrobić przez enkapsulację, to musiałbym oprogramować Add,
Items i całą restę.
Post by NoBy
- Właściwości i metod które muszę dopisać, jest w większości wypadków
mniej, niż gdybym poprawiał właściwości i metody przy dziedziczeniu -
w obu przypadkach dopisuję function Add(AObject: TMyClass): Integer;
To znowu zależy, patrz wyżej.
Post by NoBy
Post by Tygrys
I do każdego odwołania do obiektu
wewnętrznego dokładasz dodatkowy czas na przejście Twoich metod.
Hmm...
function Add(aObject: TMyClass): Integer;
begin
Result:= fMyList.Add(aObject)
end;
function Add(aObject: TMyClass): Integer;
begin
Result:= inherited Add(aObject)
end;
Pod warunkiem, że zmienam Add. Patrz przykład wyżej.
Post by NoBy
Post by Tygrys
Nie jest złotą regułą wybór tego drugiego rozwiązania, zależy to
bardzo od celu, jaki dana klasa ma spełnić.
Nie jest. Ale ja nie piszę, że jest.
Piszesz, że zaleca się. Nie piszesz, że w niektórych przpadkach zaleca się.
Post by NoBy
Post by Tygrys
Np. zobacz: TObjectList dziedziczy z TList a TStringList zawiera
wewnętrznie TList.
Co chyba potwierdza tezę, o dziedziczeniu w przypadku rozbudowy
funkcjonalności i użyciu jako pola gdy potrzebujemy tylko
funkcjonalności TObjectList? W TObjectList trzeba było ponadpisywać
wszystkie metody z Pointer. TObjectList, nadal tak jak TList, jest
taką generyczną listą ogólnego zastosowania?
Jest.
Post by NoBy
Post by Tygrys
To samo można uzystać przez dziedziczenie (zobacz TObjectList)
Niby to samo, tyle że masz dodatkowo enkapsulację jako premię.
Albo balast.
Post by NoBy
Post by Tygrys
Post by NoBy
// przy dziedziczeniu jest tu
// property List: PPointerList;
// to chyba niezbyt dobrze?
Daje bardzo szybki dostęp go obiektów z listy, to czy to dobrze
czy źle zależy od przeznaczenia klasy.
Jeszcze nigdy nie musiałem aż tak rozpaczliwie szukać szybkości
działania programu, ale nie zaprzeczam, że komuś mogło sie zdarzyć.
Tylko czy ja wiem, czy wtedy TObjectList byłby dobrym rozwiązaniem?
To taka dynamiczna tablica obiektów. Z funkcjonalnością listy. Bardzo
przydatna klasa. No i stosunkowo 'lekka'.
Post by NoBy
Post by Tygrys
Traktuj to jako wskazówkę, a nie jako przykazanie.
Hmm... Widziałeś mnie kiedyś w kapturze, biegającego z pochodnią po
firmach programistyczych i palącego wszystkich, którzy się
sprzeciwiają?
No to w takim razie ok.

Tygrys
NoBy
2006-03-28 17:56:21 UTC
Permalink
Post by Tygrys
Post by NoBy
Funkcjonalności TObjectList nie zawężam. A jeżeli chodzi ci o
- Zawężanie funkcjonalności jednocześnie zmniejsza ilość
właściwości i metod, które muszę sam dopisać;
To zależy, co chcesz otrzymać. Ja np. dodając do objectlist
funkcję zapisu na dysk dodaję jedną funkcję.
Gdybym chciał to zrobić przez enkapsulację, to musiałbym
oprogramować Add, Items i całą restę.
Ekhm... Jeszcze raz. W twoim kontrprzykładzie _dodajesz_ funkcję
zapisu, czyli _nie zawężasz_, czyli _dodajesz funkcjonalność_ do
TObjectList?
Post by Tygrys
Post by NoBy
- Właściwości i metod które muszę dopisać, jest w większości
wypadków mniej, niż gdybym poprawiał właściwości i metody przy
dziedziczeniu - w obu przypadkach dopisuję function
Add(AObject: TMyClass): Integer;
To znowu zależy, patrz wyżej.
Patrz jak wyżej ;P~
Post by Tygrys
Post by NoBy
function Add(aObject: TMyClass): Integer;
begin
Result:= fMyList.Add(aObject)
end;
function Add(aObject: TMyClass): Integer;
begin
Result:= inherited Add(aObject)
end;
Pod warunkiem, że zmienam Add. Patrz przykład wyżej.
Nie tylko Add - pod warunkiem, że zmieniasz którąkolwiek metode, czy
właściwość której argument jest typu TObject w TObjectList, czy
Pointer w TList. A tych jest całkiem sporo. Enkapsulując możesz
dopisać tylko te które potrzebujesz, dziedzicząc powinieneś nadpisać
wszystkie.
Post by Tygrys
Post by NoBy
Nie jest. Ale ja nie piszę, że jest.
Piszesz, że zaleca się. Nie piszesz, że w niektórych przpadkach zaleca się.
Przepraszam - że co?!?

<news:***@127.0.0.1>
"IMO słusznie (przynajmniej w typowych zastosowaniach)" - uściślając
typowe zastosowanie TObject list polega chyba na jej użyciu, nie
rozbudowie?

<news:***@127.0.0.1>
"Jeżeli nie dodaje się do TObjectList żadnych dodatkowych
funkcjonalności, tylko składuje się obiekty jakiegoś pojedyńczego
typu (chyba zdecydowana większość zastosowań), to dostęp w klasie
potomnej do sekcji public TObjectList jest raczej niepożądany."

I sam cytujesz tuż poniżej z
Post by Tygrys
Post by NoBy
Co chyba potwierdza tezę, o dziedziczeniu w przypadku rozbudowy
funkcjonalności i użyciu jako pola gdy potrzebujemy tylko
funkcjonalności TObjectList?
Chyba EOT?
--
NoBy MD5: 486cf5eee849c8de7bb630e4aaa8b761
jh
2006-03-26 14:26:45 UTC
Permalink
Post by Tadeusz Bodalski
for i:=0 to count-1 do (Items[i] as TJakasKlasa).Free;
inherited;
end;
Tu jest błąd.

for i:=count-1 downto 0 do (Items[i] as TJakasKlasa).Free;


jh
Zeman
2006-03-26 14:50:18 UTC
Permalink
Post by jh
Post by Tadeusz Bodalski
for i:=0 to count-1 do (Items[i] as TJakasKlasa).Free;
inherited;
end;
Tu jest błąd.
for i:=count-1 downto 0 do (Items[i] as TJakasKlasa).Free;
jak - a jaka roznica ?
jh
2006-03-26 15:25:02 UTC
Permalink
Post by Zeman
Post by jh
Post by Tadeusz Bodalski
for i:=0 to count-1 do (Items[i] as TJakasKlasa).Free;
inherited;
end;
Tu jest błąd.
for i:=count-1 downto 0 do (Items[i] as TJakasKlasa).Free;
jak - a jaka roznica ?
Może się mylę...

-------------------------------------------------------------
procedure TForm1.btnCreateClick(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 9 do
ListBox1.Items.Add(IntToStr(i));
end;

procedure TForm1.btnZeroToCountClick(Sender: TObject);
var
i: Integer;
begin
Memo1.Clear;
for i := 0 to ListBox1.Items.Count - 1 do
begin
Memo1.Lines.Add(Format('i=%d Items.Count=%d', [i,
ListBox1.Items.Count]));
ListBox1.Items.Delete(i);
end;
end;

procedure TForm1.btnCountDowntoZeroClick(Sender: TObject);
var
i: Integer;
begin
Memo1.Clear;
for i := ListBox1.Items.Count - 1 downto 0 do
begin
Memo1.Lines.Add(Format('i=%d Items.Count=%d', [i,
ListBox1.Items.Count]));
ListBox1.Items.Delete(i);
end;
end;
-------------------------------------------------------------
No i Memo1 pokazuje tak dla btnZeroToCountClick:

i=0 Items.Count=10
i=1 Items.Count=9
i=2 Items.Count=8
i=3 Items.Count=7
i=4 Items.Count=6
i=5 Items.Count=5
i=6 Items.Count=5
i=7 Items.Count=5
i=8 Items.Count=5
i=9 Items.Count=5

Co w efekcie z elementów 0..9 pozostawia niepoarzyste, czyli 1, 3, 5, 7, 9.

a tak dla btnCountDowntoZeroClick

i=9 Items.Count=10
i=8 Items.Count=9
i=7 Items.Count=8
i=6 Items.Count=7
i=5 Items.Count=6
i=4 Items.Count=5
i=3 Items.Count=4
i=2 Items.Count=3
i=1 Items.Count=2
i=0 Items.Count=1

I lista jest pusta.

jh
jh
2006-03-26 15:42:24 UTC
Permalink
Sorry, zagalopowałem się - założyłem, że tam jest Delete, no i ObjectOwns =
True, jak jest w domyślnym konstruktorze. Czyli
var
ObjList: TObjectList;
i
ObjList := TObjectList.Create;
to
for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(i);

Oczywiście błędu nie wywali w przeciwieństwie do pętli:
for i := 0 to ObjList.Count - 1 do

:)

jh
Zeman
2006-03-26 16:15:02 UTC
Permalink
Post by jh
Sorry, zagalopowałem się - założyłem, że tam jest Delete, no i ObjectOwns
= True, jak jest w domyślnym konstruktorze. Czyli
var
ObjList: TObjectList;
i
ObjList := TObjectList.Create;
to
for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(i);
for i := 0 to ObjList.Count - 1 do
:)
;)

Pozwiodronka,
Zeman.
[Cichy]
2006-03-29 09:35:07 UTC
Permalink
Post by jh
for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(i);
szybsze bedzie

for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(0);

bo nie bedzie musial leciec w kazdym kroku do oststniego elemetu listy,
tylko bedzie sciagal pierwszy za kazdym razem.
Tocbac
2006-03-29 10:36:22 UTC
Permalink
Post by [Cichy]
Post by jh
for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(i);
szybsze bedzie
for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(0);
Albo ja mam jakieś zaćmienie albo Ty ;-)
Post by [Cichy]
bo nie bedzie musial leciec w kazdym kroku do oststniego elemetu listy,
Co to znaczy "leciec w kazdym kroku do oststniego elemetu listy"???

Usuwanie elementu z listy wygląda tak:
1. Określenie elementu do usuwania: = Items[Index]
Czy to Items[0] czy Items[i] to przecież to samo.
Czy to znaczy, że odczyt Items[i] przebiega "i" razy wolniej?
2. Skracanie długości tablicy o 1 (jeden)
3. Jeśli element do usuwania nie jest ostatni to nastąpi przesuwania
tablicy wskaźników do przodu o 1 (jeden).
(przesuwana jest tylko część od następnego elementu do ostatniego)
Post by [Cichy]
tylko bedzie sciagal pierwszy za kazdym razem.
Przy usuwaniu ostatniego elementu odpada p. 3, czyli
co jest szybsze???

ps. Tak samo z np.
a: array of Integer
Jeśli chcesz zachować porządek elementów w tablicy
(np. kolejne punkty tworzące Polygon)
to przy usuwaniu ostatniego musisz tylko skrócić długość
tablicy. Przy usuwaniu "środkowego" musisz przesuwać część
tablicy do przodu

Tocbac.
Zeman
2006-03-29 10:55:26 UTC
Permalink
Post by [Cichy]
Post by jh
for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(i);
szybsze bedzie
for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(0);
bo nie bedzie musial leciec w kazdym kroku do oststniego elemetu listy,
tylko bedzie sciagal pierwszy za kazdym razem.
Nie nie.
Musi Pan sobie zdawac sprawe, ze TList choc z nazwy sugeruje klasyczna
liste - czyli ze element ma wskaznik na nastepny, to tak nie jest. TList to
tablica - czyli charakteryzuje sie tym, ze dostep do kazdego elementu jest
rowno szybki. Poza tym usuwanie srodkowego elementu jest rownowazne z
przesunieciem wszystkich nastepnych - jak to w tablicy ;)

Pozwiodronka,
Zeman.
[Cichy]
2006-04-04 10:47:00 UTC
Permalink
Witam,

Ma Pan racje, teraz to doczytalem :)
Zasugerowalem sie nazwa klasy :)

Przepraszam za zamet :)

Pozdrawiam,
Cichy

Johnny
2006-03-29 10:58:42 UTC
Permalink
Post by [Cichy]
Post by jh
for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(i);
szybsze bedzie
for i := ObjList.Count - 1 downto 0 do
ObjList.Delete(0);
bo nie bedzie musial leciec w kazdym kroku do oststniego elemetu listy,
tylko bedzie sciagal pierwszy za kazdym razem.
a czytelniejsze

While ObjList.Count>0 Do ObjList.Delete(0);

:-)

pzdr
Johnny
Loading...