Article View: pl.comp.objects
Article #15754Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
From: SasQ
Date: Mon, 19 Mar 2007 01:18
Date: Mon, 19 Mar 2007 01:18
222 lines
9875 bytes
9875 bytes
Dnia Sun, 18 Mar 2007 23:11:57 +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
Aaa no to już chyba zaczynam qmać, co masz na myśli :)
Jeśli mamy sobie takie coś:
int x = 2;
int y = 2;
i teraz porównujemy je tak:
if (x == y) ...
to obchodzi nas wyłącznie fakt, że wartości obiektów są takie same.
Nie obchodzi nas, że są to dwa różne obiekty przechowujące tą samą
wartość. Równość wartości traktujemy jako równość obiektów, a
wartość utożsamiamy z samym obiektem. O to chodzi? :>
Kolor jest typem wartościowym, bo jeśli mamy:
Kolor pierwszy = czerwony;
Kolor drugi = czerwony;
i porównamy je:
if (pierwszy == drugi) ...
to dla nas będzie to "ten sam kolor" [mimo że leży w różnych
miejscach].
Przy takim postawieniu sprawy rzeczywiście portfel nie jest
typem wartościowym, bo gdy zrobimy tak:
Portfel moj = 500; //w moim portfelu śpi 500 zł
Portfel twoj = 500; //w twoim portfelu śpi 500 zł
to kiedy je porównujemy, domyślne rozumienie tego porównania
jest inne:
if (moj == twoj) ...
bo tym razem wygląda to jak sprawdzenie, czy to są dwa różne
portfele, czy może ten sam, i nie obchodzi nas co jest w środku i
że oboje mamy tyle samo pieniędzy w swoich portfelach.
Tutaj zawartość portfela nie jest utożsamiana z nim samym.
Jeśli byśmy chcieli porównywać zawartość portfeli, to musimy
to jasno powiedzieć:
if (moj.zawartosc == twoj.zawartosc) ...
> (pomijając już bezsens porównywania dwóch stanów z dwóch
> różnych obiektów, ale to tak na marginesie).
A tego to nie skumałem :|
> if ( portfel1 == portfel2 ) // czy to ten sam portfel
No spox, teraz wchodzi do garka ;)
> 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.
Hmm... czyli sugerujesz, że w przypadku portfela robienie
z niego typu wartościowego jest jakimś kaskaderstwem i
lepiej użyć semantyki, w której jego zawartość jest osobnym
obiektem składowym?
> Powtarzam: typ jest wartościowy wtedy (i tylko wtedy), gdy
> tożsamość poznajemy po jego wartości.
No czyli chyba każdy typ podstawowy taki jest.
Hmm... a jak to jest z referencjami i wskaźnikami?
Albo tablice znakowe - ostatnio na pl.comp.lang.c był taki
przypadek, że koleś porównywał wskaźniki do takiego samego
[ale nie tego samego] ciągu znaków. Coś w stylu:
char* str1 = "test";
...
if (str1 == "test") ...
i się dziwił, czemu ten warunek mu się nie spełnia, skoro
"stringi są te same" ;J Może to jest pole dla twojej
teorii? :> Bo tutaj ewidentnie ktoś miał na myśli porównanie
wartości, a wyszło mu porównanie tożsamości i to go
wpuściło w maliny.
> 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.
Czyli to jest wybór arbitralny, czy jednak podyktowany
jakimiś właściwościami?
>> 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?
To się zdecyduj. Niedawno jak pytałem czy stałe dosłowne są
obiektami stałymi, czy jedynie wartościami "nie opakowanymi" w
żadnym obiekcie, to mi odpowiedziałeś:
"Są obiektami stałymi. Świadczy o tym fakt, że można nimi
inicjalizować stałe referencje."
A teraz mi tu siejesz trwogę, że są "gołymi" wartościami
nie trzymanymi nigdzie? :P
Jakby tego było mało, to mi jeszcze później napisałeś, że
"Wszelkie inne stałe dosłowne nie leżą nigdzie w pamięci"
No to nie rozumiem: obiekty których nigdzie nie ma? :P
>> Jeśli chodzi ci o tożsamość, 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 rozumiem pytania :|
> 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
No tak, w sumie masz rację. Ale jest jedno ale: zarządzanie
takimi obiektami wartościowymi w pamięci. Użytkownik takich
obiektów może je sobie traktować jak wartościowe, przekazywać
go mając na myśli jego wartość, porównywać go mając na myśli
porównanie wartości, ale wciąż będą pewne części programu,
w których chciałby wiedzieć, w jakim miejscu pamięci leży
ten obiekt, albo czy dwa obiekty leżą w różnych miejscach
pamięci, czy może jest to to samo miejsce pamięci.
> 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.
Hmm... coś mi to przypomina...
Czy obiekt klasy TrybGraficzny mógłby być typem wartościowym?
Chodzi mi o taki obiekt przechowujący informacje o parametrach
trybu graficznego. Coś mi się zdaje, że tak, bo tutaj:
TrybGraficzny pierwszy = { 800, 600, 16 };
TrybGraficzny drugi = { 800, 600, 16 };
...
if (pierwszy==drugi) ...
porównanie oznacza porównanie wartości, a nie tożsamości.
W moim kodzie chciałem dodatkowo zagwarantować stałość
takich obiektów, tzn. żeby były właśnie niemodyfikowalne.
Raz utworzone z pewnymi wartościami mają je już do końca
życia [bo parametry tego samego trybu graficznego nigdy
się nie zmieniają]. Są one produkowane raz, przez obiekt
wyciągający je z karty graficznej, i później już się
nie zmieniają. Mogą być jedynie kopiowane, ale wykonanie
kopii sprawia, że mamy wciąż "ten sam" tryb graficzny,
tylko przechowywany w dwóch miejscach ;J
[to miało zagwarantować, że nikt niepowołany nie stworzy
sobie własnego obiektu klasy TrybGraficzny z dowolnie
ustawionymi, nieprawidłowymi wartościami].
Czy ten mój TrybGraficzny nie jest przypadkiem idealnym
przykładem typu wartościowego? :J [o ile dobrze to zrozumiałem]
> W językach, które naturalnie wspierają typy wartościowe
O jakich językach mowa? Wolałbym to wiedzieć, bo wtedy
mógłbym sobie popatrzeć jak tam to jest zrobione i może
ułatwiłoby mi to zrozumienie sprawy na przykładach ;)
> Oczywiście teorię typów wartościowych i niewartościowych [...]
> 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.
Mógłbyś uściślić na czym polega związek typów wartościowych
z płytkim/głębokim kopiowaniem?
> 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
A czy w Javie przypadkiem nie jest tak samo?
No chyba że tam się wtedy robi kopia przy modyfikacji przez b.
Już nie pamiętam...
--
SasQ
Technical Details
Message-ID:
<pan.2007.03.19.01.18.29.79961@go2.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!newsfeed.atman.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.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> <etkgvt$2b$1@kujawiak.man.lodz.pl>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!newsfeed.atman.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mail From: SasQ <sasq1@go2.pl> Newsgroups: pl.comp.objects Subject: Re: pl.comp.objects FAQ (Frequently Asked Questions and more) Date: Mon, 19 Mar 2007 02:18:29 +0100 Organization: Ganz Automyjnia (i przeróbki ;) Lines: 222 Message-ID: <pan.2007.03.19.01.18.29.79961@go2.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> <etkgvt$2b$1@kujawiak.man.lodz.pl> Reply-To: sasq1@go2.pl NNTP-Posting-Host: cai89.neoplus.adsl.tpnet.pl Mime-Version: 1.0 X-Trace: nemesis.news.tpi.pl 1174267300 21442 83.30.80.89 (19 Mar 2007 01:21:40 GMT) X-Complaints-To: usenet@tpi.pl NNTP-Posting-Date: Mon, 19 Mar 2007 01:21:40 +0000 (UTC) User-Agent: Pan/0.14.2 (This is not a psychotic episode. It's a cleansing moment of clarity.) Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit