Article View: pl.comp.objects
Article #15275Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
From: Mariusz Lotko
Date: Tue, 06 Mar 2007 00:15
Date: Tue, 06 Mar 2007 00:15
247 lines
9421 bytes
9421 bytes
Sektor van Skijlen wrote: > Dnia Mon, 05 Mar 2007 07:07:47 +0100, Mariusz Lotko skrobie: >> Sektor van Skijlen wrote: > >> > Dnia Sun, 04 Mar 2007 19:37:50 +0100, Mariusz Lotko skrobie: >> >> Adam Karpierz wrote: >> > >> >> > "Sektor van Skijlen" >> >> > <ethouris@guess.if.gmail.com.is.valid.or.invalid> wrote: >> >> >>> if obj is anotherObj : # sprawdza czy to te same obiekty >> >> >>> if obj == anotherObj : # sprawdza czy zawarto¶æ obiektów jest >> >> >>> równa. >> >> >> >> >> >>> Czy o to Ci chodzi? >> >> >> >> >> >> W³a¶nie NIE o to mi chodzi. >> >> >> Chodzi o to, ¿e ma byæ dostêpny TYLKO operator ==, >> >> >> natomiast od definicji typu zale¿y czy porównuje on to¿samo¶æ, >> >> >> czy warto¶æ. >> > >> >> Tu siê nie zgodzê. W przypadku C++ porównuje siê zawsze warto¶æ >> >> obiektu. W przypadku wska¼nika warto¶ci± jest adres obiektu na >> >> jaki wska¼nik wskazuje. >> > >> > No tak, ale je¶li porównujesz warto¶ci wska¼nikowe, to de facto >> > porównujesz to¿samo¶ci dwóch obiektów. >> > >> > Np. porównuj±c "a == b" nie porównujesz "a" z "b", tylko porównujesz >> > "to¿samo¶æ obiektu widocznego pod a" i "to¿samo¶æ obiektu widocznego >> > pod b". > >> A je¶li obiektami s± smart pointery, to co porównujê? > > To samo. Przecie¿ ich warto¶ci równie¿ s± wska¼nikami. Ale napisa³e¶ (parê linijek wy¿ej), ¿e porównywanie wska¼ników, to porównywanie to¿samo¶ci. Czy to¿samo¶æ przeradza siê w warto¶æ je¶li obiekt jest inteligentny (smart)? ;-) > >> > Zreszt± to siê odnosi, jak s³usznie zauwa¿y³e¶, ogólnie do warto¶ci. >> > Je¶li porównujesz dowolne dwa a i b tego samego typu, to porównanie >> > okre¶la ci, czy pod tymi dwiema zmiennymi siedz± te same warto¶ci. W >> > przypadku wska¼ników bêdzie to oznacza³o tylko to, czy te dwie zmienne >> > wska¼nikowe wskazuj± na ten sam obiekt (czy na dwa ró¿ne). Jest to wiêc >> > w efekcie porównanie to¿samo¶ci. >> > >> >> Operator == dla dwóch obiektów powinien _zawsze_ porównywaæ równo¶æ >> >> semantyczn± ich _zawarto¶ci_, a nie kombinowaæ z ich to¿samo¶ci±. >> > >> > Moment. >> > >> > Po pierwsze, równo¶æ dwóch obiektów powinna wynikaæ z równo¶ci ich >> > warto¶ci. Je¶li obiekt nie ma warto¶ci, to nie powinien mieæ okre¶lonej >> > porównywalno¶ci, bo po prostu nie ma czego porównaæ. Porównujemy wiêc >> > WARTO¦Æ (a nie za-WARTO¦Æ). > >> OK, w takim razie jaki¶ przyk³ad obiektu bez warto¶ci? > > struct X > { > int a; > int* b; > }; Czyli tak: jak mam wska¼nik osobno, to mogê go porównaæ, jak mam int osobno to równie¿ mogê porównaæ, a jak je wezmê razem do kupy to ju¿ nie? >> >> Ka¿d± dowoln± parê obiektów mo¿na w prosty sposób zweryfikowaæ >> >> pod k±tem "czy to te same obiekty" maj±c do nich referencjê, np. >> > >> >> bool teSame(const Klasa& a, const Klasa& b) >> >> { >> >> return &a == &b; >> >> } >> > >> >> lub czy to równe obiekty >> >> a == b >> > >> >> Co odpowiada konstrukcjom z Pythona jakie podalem w poprzednim po¶cie. >> > >> > Mo¿na - tyle ¿e tej pierwszej konstrukcji nikt nie stosuje. > >> ¯e jak? Piersza linijka wiêkszo¶ci porz±dnych operatorów == ! Po co >> porównywaæ zawarto¶æ tego samego obiektu? > > A niby po co chcesz to sprawdzaæ? Jeste¶ pewny, ¿e w ka¿dym przypadku > bêdzie to tañsze? Mogê domniemywaæ, szczególnie je¶li obiekt sk³ada siê nie tylko z typów prostych, a wiêc "rekursywnie" bêd± wywo³ane inne operatory porównania je¶li tego nie zrobiê. > > Je¶li w danym obiekcie w operatorze == nast±pi porównanie tylko jednej > warto¶ci, to oszczêdzasz tylko w przypadku, gdy masz ten sam obiekt. Je¶li > nie, to masz dodatkowe, niepotrzebne porównanie. Czyli koszt jest mniejszy > w przypadku równo¶ci, ale wiêkszy w przypadku nierówno¶ci. > >> > W Javie np. masz: >> > >> > Klasa a, b; >> > int c, d; >> > >> > i masz >> > a == b >> > c == d >> > >> > i bez ró¿nicy. Szkoda tylko, ¿e dla "String t, s" jest to samo ;) >> > >> > Nie mo¿esz jednak w ¿aden sposob (inny ni¿ przez odpowiednie metody) >> > porównaæ warto¶ci a i b, ani porównaæ referencji c i d. > >> W C++ te¿ musisz wiedzieæ co porównujesz. Bo je¶li a i b s± wska¿nikami, >> to masz analogiczny problem. Z tym, ¿e zamiast equals() u¿ywasz * do >> wy³uskania warto¶ci. > > Nieprawda. Je¶li c i d s± typami warto¶ciowymi, to ich wska¼niki w ogóle > nie powinny ciê interesowaæ. Ale mog± i jêzyk C++ tego nie zabrania. Jaki wiêc sens ma Twoja teoria w odniesieniu do tego jêzyka? >> > Pierwsze nie ma sensu dlatego, ¿e je¶li w typach warto¶ciowych liczy >> > siê dla nas warto¶æ, to nie liczy siê to¿samo¶æ. Porównuj±c warto¶æ do >> > wspomnianego koloru, interesuje nas kolor, a nie np. czy kartki >> > papieru, na których zapisano kod koloru, s± te same, czy inne. > >> W szczególno¶ci mo¿e siê zdarzyæ, ¿e bêdziemy chcieli porównaæ kolor tego >> samego egzemplarza kartki. Wówczas porównanie bêdzie prostsze i wykonalne >> nawet dla daltonisty. St±d chyba nie warto od to¿samo¶ci siê odcinaæ. > > Ale PO CO? > > Zwróæ uwagê na to, co napisa³em poni¿ej: nigdy nie porównuje siê dwóch > warto¶ci stanów z dwóch ró¿nych obiektów, je¶li nie mamy z innego ¼ród³a > informacji o tym, jaka ta warto¶æ jest. Twoja teoria stoi na glinianych nó¿kach. Wprawdzie nie mam pamiêci absolutnej, ale gdzie¶ mi ko³acze po g³owie, ¿e kilka Twoich "nigdy" ju¿ mi siê w ¿yciu zdarzy³o. A ¿e nie pamiêtam, to chyba nie skoñczy³o siê to ¿adn± katastrof± programistyczn±, któr± trzebaby w po¶piechu naprawiaæ. >> > Dlatego w³a¶nie obiekty nie maj± zwykle takiej ogólnej "warto¶ci", maj± >> > ich zwykle wiele i ró¿ne warto¶ci mog± nas interesowaæ przy >> > porównaniach. > >> Piszesz trochê w kontek¶cie bazodanowym, gdzie jest np. poszukiwanie >> obiektów spe³niaj±cych okre¶lone kryteria. Jest jednak ca³a gama klas, >> dla których bez wiêkszych trudno¶ci mo¿na zdefiniowaæ operatory >> porównania. > > To s± to wtedy typy warto¶ciowe. > > Java próbuje symulowaæ to poprzez wprowadzanie obiektów niezmienialnych, > jak w³a¶nie String (w C# wysz³o to o tyle lepiej, ¿e tam jest dla tego > typu poprawnie zdefiniowany operator porównania). Niestety z przyczyn > wydajno¶ciowych wymaga to dodatkowych wygibasów jak StringBuilder. > >> Mimo to nie odwa¿y³bym siê na takie wyra¼ne i jednoznaczne nazwanie >> pierwszych obiektów warto¶ciowymi a drugich niewarto¶ciowymi. > > Dlaczego? Bo ¶wiat to nie tylko bazy danych. > >> > Ja wiem, ¿e zaraz kto¶ rzuci szczególnym przypadkiem, ¿e co z >> > obiektami, które maj± jedno pole, a zatem tylko jeden stan cz±stkowy? >> > >> > Otó¿ tutaj w³a¶nie odgrywa rolê kwestia to¿samo¶ci obiektów. Je¶li >> > bowiem interesuje nas to¿samo¶æ obiektu, to nie interesuje nas jego >> > warto¶æ (je¶li nie podlega ona bie¿±cemu przetwarzaniu, tzn. np. >> > w³a¶nie chcieliby¶my t± warto¶æ porównaæ z odpowiadaj±cym temu czemu¶ >> > stanem w innym obiekcie). > >> We¼my obiekty w rodzaju mutable string. Da siê jednoznacznie zdefiniowaæ >> operator porównania, w pewnej chwili dwa obiekty bêd± równe, a za chwilê >> nie, wiêc trudno tu mówiæ o to¿samo¶ci. > > Tak, ale mutable string - je¶li mówimy o czym¶ takim, jak StringBuilder - > nie jest ju¿ typem warto¶ciowym, gdy¿ zmienno¶æ obiektu wchodzi w > interakcjê z jego to¿samo¶ci±. > > Porównanie tego typu z innym mog³oby siê odbywaæ tylko poprzez - > najczê¶ciej niejawne - pozyskanie String'a - czyli typu ju¿ warto¶ciowego > - i porównanie go z innym stringiem. Rozumiem, ¿e String jest niezmienialny a SB zmienialny, ale dlaczego jeden jest warto¶ciowy, a drugi ju¿ nie - wstyd siê przyznaæ, ale nie mogê. >> > Natomiast porównanie stanów dwóch obiektów nie ma po prostu sensu. Co >> > na przyk³ad da ci informacja, ¿e pewne dwa samochody s± "tego samego >> > koloru", dopóki nie wiesz, jaki to kolor? > >> Uwierz mi, w wielu sytuacjach ma to sens. > > Nie wierzê :) Znowu zrobiê niecodzienn± w ¶wiecie informatyki wycieczkê: za³ó¿my jeste¶ na dyskotece i jeste¶ stanu wolnego. Je¶li nie zainteresujesz siê stanem obiektu "kobieta" (czy te¿ jest "wolny") przed zagajeniem, to ryzykujesz stratê zêbów od jej ch³opaka-dresiarza. > >> Dziwiê siê Twoj± opini±, bo sprawiasz wra¿enie cz³owieka, który ma >> do¶wiadczenie zawodowe i trochê linii kodu wyprodukowa³. > > I mówiê to w³a¶nie na podstawie tego :) > > Je¶li chcemy stwierdziæ, czy dwa obiekty s± w "tym samym stanie", to > musimy mieæ chocia¿ przybli¿one pojêcie o tym, jaki ten stan jest. A je¶li chcemy je tylko pogrupowaæ wed³ug stanu? > >> >> > Podobnie chodzi o to aby byl dostepny inny operator do >> >> > 'clone' obiektu a inny do zmiany referencji >> > >> >> To te¿ jest w C++ rozgraniczone: >> >> C o1 = inny; // kopiowanie obiektu >> >> C* o2 = &inny; // przypisywanie "referencji". >> >> C& o3 = inny; // przypisywanie referencji. >> > >> >> Schody zaczynaj± siê, gdyby¶my napisali >> >> o3 = jeszcze_inny; // ... bo to ju¿ znowu jest kopiowanie, a nie >> >> zmiana >> >> // referencji >> > >> >> No ale taki ju¿ jest ten C++... >> > >> > Ale w C++ zwykle - poza szczególnymi przypadkami - nie stosuje siê dla >> > tego samego typu operowania statycznego i dynamicznego. Czyli, je¶li >> > u¿ywamy wska¼ników i new, to obiektów tego samego typu ju¿ nie tworzymy >> > na stosie. > >> A "my" stosujemy, je¶li jest taka potrzeba... :-) > > I to prowadzi potem do ciekawych kwiatków ;) Jeden z moich kolegów komentuj±c efekt nieprzemy¶lanego wymagania powiedzia³: "trzeba wiedzieæ o co siê prosi...". -- Mariusz Lotko
Message-ID:
<esi7ve$5ia$1@bandai.magma-net.pl>
Path:
polish.pugleaf.net!archive.newsdeef.eu!mbox2nntp-pl.comp.objects.mbox.gz!number1.nntp.dca.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!t-online.de!news.nask.pl!news.nask.org.pl!news.internetia.pl!newsfeed.gazeta.pl!news.magma-net.pl!not-for-mail
References:
<pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.pl> <pan.2007.02.26.21.12.45.8078@go2.pl> <es6b6u$2ls$1@kujawiak.man.lodz.pl> <esbllu$51n$1@bandai.magma-net.pl> <esbv7t$7o$1@kujawiak.man.lodz.pl> <1172940339.25227.28.camel@qrnik> <escc9e$2h2$1@kujawiak.man.lodz.pl> <esd1k1$9bp$1@bandai.magma-net.pl> <esemb6$2r3$1@kujawiak.man.lodz.pl> <eses6u$8fm$1@inews.gazeta.pl> <esf3am$r52$1@bandai.magma-net.pl> <esfg25$b2m$1@kujawiak.man.lodz.pl> <esgboa$8i2$1@bandai.magma-net.pl> <esi21l$skh$1@kujawiak.man.lodz.pl>