Skocz do zawartości

[Delphi]Błąd z selfem


Force

Polecane posty

Błąd jaki tutaj opiszę zdarzał mi się w różnych zdarzeniach, ale zawsze jakoś udało mi się znajdywać inny sposób, ale teraz się nie da.

Otóż:

Mam klasę, które funkcja zwraca rekord, w którym jeden z elementów jest wskaźnikiem na klasę która go wywołała - używam @self. Gdy wykonuje się kod i w debuggerze podglądnę jak zachowują się zmienne ze wskaźnika z rekordu to mają dobre dane, ale gdy wywołam funkcją z rekordu, która ma operować na danych z tego wskaźnika, to wskaźnik pokazuje złe dane, ma ten sam adres, ale jest tam co innego, i się sypie program bo chodzę po nie mojej pamięci.

Miał ktoś taki problem lub wie jak go rozwiązać?

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

W delphi nie tworzysz obiektu tak jak w cepie, w delphi tworzy sie referencje na obiekt. Tak wiec wszystkie @self jest bledne. Nie rob wskaznika na klase bo to jest niepotrzebne tylko skozystaj z faktu ze to jest referencja.

 

mi już się to wszystko chrzani jak się teraz ucze C++ :) - to w Delphi referencja to będzie poprostu Func(cos: TKlasa);

 

func(Self); ?

Moje projekty: http://wojciechkulik.pl

Link do komentarza
Udostępnij na innych stronach

Ale szybcy jesteście :D

Robie prawie tak jak KKKas, z resztą tu jest link http://www.unit1.pl/pb-472

Robie to w Turbo Delphi, więc procedura, która operuje na rekordzie jest w nim.

Jeśli dobrze Blina rozumiem (a nie za bardzo mi z tym idzie:P) to mam zrobić zmienną TForceIArray w TForceIArrayS i do niej przypisać self-a?

 

W funkcji referencja jest przez var, przynajmniej tak mi sie jeszcze wydaje, ale jak słucham innych to mogę zmienić zdanie :D

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

Ale szybcy jesteście :D

Robie prawie tak jak KKKas, z resztą tu jest link http://www.unit1.pl/pb-472

Robie to w Turbo Delphi, więc procedura, która operuje na rekordzie jest w nim.

Jeśli dobrze Blina rozumiem (a nie za bardzo mi z tym idzie:P) to mam zrobić zmienną TForceIArray w TForceIArrayS i do niej przypisać self-a?

 

W funkcji referencja jest przez var, przynajmniej tak mi sie jeszcze wydaje, ale jak słucham innych to mogę zmienić zdanie :D

 

kurcze... faktycznie :D zapomniałem o tym, to przez tą naukę C++ :D

Moje projekty: http://wojciechkulik.pl

Link do komentarza
Udostępnij na innych stronach

Nie ma sensu dawać w parametrze funkcji var obiekt : TJakasKlasa bo obiekty są tworzone na stercie, więc my tak naprawde operujemy na wskaźnikach - Delphi samo za nas dodaje operator wyłuskania: ^

Skoro więc dajesz var obiekt : TJakasKlasa to w rezultacie przesyłasz wskaźnik do referencji, a wystarczy obiekt : TJakasKlasa

 

// Edit: Tfu, w ostatnim zdaniu, nie cały obiekt jest przesyłany tylko wskaźnik : p

Link do komentarza
Udostępnij na innych stronach

Kto by pomyślał. Nie wiedziałem, że w Delphi są takie rozwiązania a'la C# czy Java, to jak ktoś będzie mi gadał, że nie ma typu referencyjnego to go zbije :D

To już wiem, czemu piszecie TKlasa(List.Items) i działa, co dla mnie zawsze wyglądało na błąd na który Delphi mruży oczy:D dzięki

 

Max1414 przegrał :P

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

Iskar niezupelnie nie ma sensu, bo jak dasz var to bedzie szybciej a jak dasz const to bedzie jeszcze szybciej ;)

 

Ech, o czym Ty mówisz. Przesyłany jest i tak i tak tylko wskaźnik a nie cały obiekt, więc po co dawać jeszcze var i jak to ma niby przyspieszyć? A const niby w jaki sposób to jeszcze bardziej przyspiesza?

Link do komentarza
Udostępnij na innych stronach

Z 'var' jest (bardzo) minimalnie najwolniejsze.

 

Dla takiego kodu:

[delphi]procedure a(Obj: TObject);

begin

Obj.ClassName;

end;

 

procYHX

NY[Ó[YN[GW&R267B&ŁD&ŚV7BŚ&Vv&6Ć74ćSŚVćC&QŃĄMQ=)(=Q=

begin

Obj := TObject.Create;

a(Obj);

b(Obj);

c(Obj)[[/asm]

 

Przy b (z 'var') mamy dodatkowo: mov eax,[eax], które jest właśnie niepotrzebne.

a i c są identyczne.

 

EDIT: Aha, i przy wywołaniu procedur dla 'a' i 'c' mamy przekazanie argumentu przez mov:

mov eax,[ebp...]

a dla 'b' mamy właśnie referencję:

lea eax,[ebp...]

 

Ogólnie wywołanie 'b' jest o jakieś 5-8% wolniejsze niż 'a' i 'c'.

҉

Link do komentarza
Udostępnij na innych stronach

tak nawiasem to var w przypadku wskazania na obiekt ma swoje znaczenie i nie chodzi tu o predkosc:

 

[delphi][/delphi]

 

w tym przypadku zarowno

a) procedure generateNewData(obj:TMyObject)

jak i

B) procedure generateNewData(const obj:TMyObject);

 

odpada. A dla wnikliwych w tym przypadku powinno byc tak:

procedure generateNewData(out obj:TMyObject)

 

dawanie const jest zalecane bo kompilator moze zrobic jakies optymalizacjie i nie tyczy sie to tylko tablic ale roznego typu danych np rekordow. W przypadku typow natywnych (integer, pointer, itd) to nie ma o ile sie nie myle znaczenia.

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

Toster możesz troche więcej napisać i wytłumaczyć tą sytuacje? :) Myśle, że nie tylko ja będe wdzięczny ;) Tzn. chodzi mi o ten przykład który dałeś.

No przecież to jest typowa referencja ;-) Też zapomniałem, że w ten sposób można wykorzystać referencję ;-) Dajesz procedurze/funkcji zmienną obiektową, a po jej wykonaniu ta zmienna jest już 'do użycia'. Zamiast tego jaśniejsze (i używane w VCL) jest zwracanie obiektu niż tworzenie go przez referencję:

funkcja Add: TObject;
begin
 Result := TObject.Create;
 Re[[XY[HY

NŚVćC

҉

Link do komentarza
Udostępnij na innych stronach

tak jak mowi KKas + troche odemnie:

 

Wiekszosc ludzi myli const z c++ z delphi, ktore dzialaja calkowicie inaczej...

w delphi mamy takie rzeczy jak: const, var, out, (nic)

 

jak to dziala:

const - przekazany parametr nie moze byc modyfikowany, ale wszelakie operacje na nim (jesli to jest obiekt) sa dozwolone. czyli jesli prze konst przekazujemy zmienna typu: integer, record, pointer itd to nie mozemy jej zmienic. Jesli przekazujemy wskazanie na obiekt to pola tego obiektu i jego metody moga byc uzywane bez ograniczen.

 

var - to zwykla referencja nie ma sie co rozpisywac

out - to jest dokladnie4 to samo co var, ale jest to czytelniejsze, widzac out w definicji fuynkcji wiadomo ze ta funkcja bedzie zwracac ten parametr

 

jak nie poda sie zadnego prefixa to jest przekazanie zmiennej przez kopie na stosie czyli zamienia sie ja w zmienna lokalna

 

ot i tyle

 

Warto pamietac o tym co mowil Blind, w delphi wszystkie obiekty sa tworzone dynamicznie i sa to de facto referencje. wiec zawsze odqwoluje sie do nich po nzawi np

 

var

t: TObject

 

odwolanie zawsze

 

t.cosTam()

 

bez cudow typu

t^.cosTam

@t

i innych wygibasow.

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...