Article View: pl.comp.objects
Article #15753Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
From: Sektor van Skijlen
Date: Sun, 18 Mar 2007 23:11
Date: Sun, 18 Mar 2007 23:11
161 lines
7940 bytes
7940 bytes
Dnia Fri, 16 Mar 2007 22:49:45 +0100, SasQ skrobie:
> Dnia Fri, 16 Mar 2007 16:39:31 +0000, Sektor van Skijlen napisał(a):
> > Typ wartościowy jest typem, którego obiekt jest identyfikowany
> > zawsze przez wartość. Więc jeśli portfel z tą samą ilością
> > pieniędzy nie jest tym samym portfelem, to portfel nie jest
> > typem wartościowym.
> Hmm... ale chyba jest dobrym przykładem, że czasami chcemy go
> potraktować jako typ wartościowy, a czasami jako niewartościowy:
> if (portfel1==portfel2) //Czy mają tyle samo pieniędzy?
> if (portfel1 IS portfel2) //Czy to ten sam portfel, czy inny?
Nie.
if ( portfel1->ilosc_pieniedzy()
== portfel2->ilosc_pieniedzy() ) // czy mają tyle samo pieniędzy
Nie porównujesz "dwóch portfeli", tylko porównujesz stan dwóch portfeli
(pomijając już bezsens porównywania dwóch stanów z dwóch różnych obiektów, ale
to tak na marginesie).
if ( portfel1 == portfel2 ) // czy to ten sam portfel
Ja wiem, że jak komuś odbija kolba i musi sobie nawymyślać wypasione definicje
operatorów (w tym ==), to nic się na to nie poradzi, ale to bynajmniej nie
powoduje, że portfel nagle staje się typem wartościowym.
Powtarzam: typ jest wartościowy wtedy (i tylko wtedy), gdy tożsamość poznajemy
po jego wartości. Jeśli więc ilość pieniędzy w portfelu nie stanowi o tym, że
to ten sam portfel, to nie jest to typ wartościowy.
> > Nic nie zależy od żadnego kontekstu.
> >
> > Saldo jest stanem (cząstkowym) konta. Saldo jest wartością.
> > Konto jest obiektem.
> No cóż, ale C++ już taki dziwny jest, że nie ma "gołych" wartości
> [a przynajmniej nic mi o tym nie wiadomo], tylko wszystko jest
> trzymane w jakichś obiektach ;)
A takie coś jak np. 119 to jest gdzie trzymane twoim zdaniem?
> W przypadku tego konta to akurat
> da się sprawy rozdzielić:
> if (konto1.saldo==konto2.saldo) //porównanie wartości
> if (konto1==konto2) //porównanie tożsamości
Zgadza się - z drobną poprawką: pierwsze to porównanie wartości salda obu kont
(a nie porównanie wartości obu kont).
> chyba że ktoś dla wygody przeładuje sobie operator== żeby
> działał jako porównanie składników saldo ;)
Za takie PRZEŁADOWANIE to chętnie bym komuś PRZYŁADOWAŁ.
Ale nawet to nie spowodowałoby, że nagle konto staje się typem wartościowym.
Typ wartościowy zyskuje tożsamość przez wartość. Przypisanie zatem powoduje,
że obiekt po lewej staje się tym samym, co obiekt o poprawej, co można też
sprawdzić operatorem ==. Przekazanie obiektu jest również przekazaniem
warości.
> Ale już np. dla typu int z twojego przykładu:
> > int x = 2;
> > int y = 2;
> >
> > Powiedz mi teraz, czy "x jest y".
> sprawa nie jest taka prosta ;) bo tutaj porównując x i y
> w taki sposób:
> if (x==y) ...
> porównujesz wartości.
Zgadza się!
> Jeśli chodzi ci o tożsamość,
Tożsamość w typach wartościowych określamy jako tożsamość wartości.
> to już trzeba by zapisać to np. tak:
> if (&x == &y) ...
> i wtedy już wiadomo, czy "x jest y" ;)
I w których operacjach wynik tego porównania ma znaczenie, a w których nie ma?
> Nie wiem tylko, czy dobrze rozumiem to, co próbujesz
> wytłumaczyć, bo już się pogubiłem w tej całej dyskusji... :/
Najprościej to jest mniej więcej wytłumaczyć tak:
Typ wartościowy jest identyfikowany przez wartość. To oznacza, że w przypadku
typów wartościowych porównywanie tożsamości obiektów typów wartościowych (o
ile w ogóle jest dostępne w języku - w Javie np. nie jest dostępne) nie daje
żadnej istotnej informacji, tzn. takiej, na której można w czymś polegać w
programie (jeśli już, to jest to kwestia ściśle techniczna określonego
języka).
W językach, w których wszystko jest obiektem, typy wartościowe są symulowane
poprzez niemodyfikowalne obiekty. To znaczy, każdy obiekt typu wartościowego
musi zostać za każdym razem wyprodukowany na nowo.
Cała istota sprawy polega na tym, co się dzieje, jeśli obiekt jest
modyfikowany. Jeśli np. mamy dwa identyfikatory a i b:
a = get(1);
b = a;
Fakt, że a == b po czymś takim jest spełniony zarówno dla typów wartościowych,
jak i obiektowych (z tym, że w przypadku typów obiektowych a i b są
referencjami, a więc również typami wartościowymi).
Ale jeśli nastąpi modyfikacja obiektu poprzez 'b', to wtedy:
- w przypadku obiektów wartościowych, 'a' pozostaje przy starej wartości
- w przypadku obiektów niewartościowych, obiekt określany przez 'a' zmieni
się również, jest bowiem tym samym obiektem, co 'b'
W językach, które naturalnie wspierają typy wartościowe, obiekty typów
wartościowych mogą mieć taki interfejs, który albo zawsze tworzy oddzielną
kopię w przypadku przypisania, albo jeśli współdzieli jakiś obiekt z innym
obiektem tego typu, to modyfikacja powoduje zakończenie współdzielenia i
wykonanie własnej, oddzielnej kopii. Tylko w takich językach mogą istnieć
modyfikowalne typy wartościowe; w innych językach mogą istnieć tylko
niezmienialne obiekty wartościowe, więc modyfikacja może polegać tylko na
stworzeniu nowej wartości.
Oczywiście teorię typów wartościowych i niewartościowych (co ciekawe, te
terminy pojawiają się w coraz większej ilości różnych niezwiązanych ze sobą
dokumentacji, ostatnio widziałem bodajże w dokumentacji do Qt) można olać,
jeśli ktoś uważa, że mu nie pasuje. Tylko że alternatywą jest stwierdzenie, że
mamy kilka różnych definicji porównania, kopiowanie płytkie i głębokie itd. -
jeśli komuś to bardziej odpowiada, to proszę bardzo.
Nawiasem mówiąc, w Rubym spierdzielili sprawę ze stringami totalnie. String w
ogólności jest typem wartościowym - niestety w Rubym jest on ehm... takim
dziwnie-hybrydowym. To znaczy, modyfikacje przenoszą się na inne obiekty
oznaczane identyfikatorami:
a = "dupa"
b = a
b[0] = "p"
print a
Ciekaw jestem, czy istnieje w Rubym jakaś możliwość wymuszenia skopiowania.
Ale porównanie z kolei porównuje zawartość stringa.
--
// _ ___ Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `| /^\ ,() <ethouris(O)gmail.com>
// \_ |\ \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx
"Java is answer for a question that has never been stated"
Technical Details
Message-ID:
<etkgvt$2b$1@kujawiak.man.lodz.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!newsfeed.pionier.net.pl!news.man.lodz.pl!not-for-mailReferences:
<pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.pl> <esfchn$t5r$1@kujawiak.man.lodz.pl> <esgboi$8i2$2@bandai.magma-net.pl> <esi2kk$skh$2@kujawiak.man.lodz.pl> <esi6uk$4mt$1@bandai.magma-net.pl> <esmu4p$ii1$2@kujawiak.man.lodz.pl> <esn1nl$7q7$1@bandai.magma-net.pl> <esv08v$o5d$1@kujawiak.man.lodz.pl> <et6pse$eab$1@bandai.magma-net.pl> <et7emm$cf1$1@kujawiak.man.lodz.pl> <etak85$krq$1@bandai.magma-net.pl> <eteh83$he8$1@kujawiak.man.lodz.pl> <pan.2007.03.16.21.49.44.873488@go2.pl>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!newsfeed.pionier.net.pl!news.man.lodz.pl!not-for-mail
From: Sektor van Skijlen <ethouris@guess.if.gmail.com.is.valid.or.invalid>
Newsgroups: pl.comp.objects
Subject: Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Date: Sun, 18 Mar 2007 23:11:57 +0000 (UTC)
Organization: LODMAN - Metropolitan Area Network in LODZ, Poland
Lines: 161
Sender: Michal Malecki <sektor@zly.kis.p.lodz.pl>
Message-ID: <etkgvt$2b$1@kujawiak.man.lodz.pl>
References: <pl-comp-objects-faq-1-1166202604@ict.pwr.wroc.pl> <esfchn$t5r$1@kujawiak.man.lodz.pl> <esgboi$8i2$2@bandai.magma-net.pl> <esi2kk$skh$2@kujawiak.man.lodz.pl> <esi6uk$4mt$1@bandai.magma-net.pl> <esmu4p$ii1$2@kujawiak.man.lodz.pl> <esn1nl$7q7$1@bandai.magma-net.pl> <esv08v$o5d$1@kujawiak.man.lodz.pl> <et6pse$eab$1@bandai.magma-net.pl> <et7emm$cf1$1@kujawiak.man.lodz.pl> <etak85$krq$1@bandai.magma-net.pl> <eteh83$he8$1@kujawiak.man.lodz.pl> <pan.2007.03.16.21.49.44.873488@go2.pl>
NNTP-Posting-Host: zly.kis.p.lodz.pl
Mime-Version: 1.0
X-Trace: kujawiak.man.lodz.pl 1174259517 75 212.191.89.2 (18 Mar 2007 23:11:57 GMT)
X-Complaints-To: abuse@man.lodz.pl
NNTP-Posting-Date: Sun, 18 Mar 2007 23:11:57 +0000 (UTC)
User-Agent: tin/1.6.2-20030910 ("Pabbay") (UNIX) (SunOS/5.9 (sun4u))
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit