🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.objects
Article #15275

Re: pl.comp.objects FAQ (Frequently Asked Questions and more)

#15275
From: Mariusz Lotko
Date: Tue, 06 Mar 2007 00:15
247 lines
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>