Thread View: pl.comp.objects
79 messages
79 total messages
Page 1 of 2
Started by kkoniec@mks.com.
Fri, 15 Dec 2006 17:10
Page 1 of 2 • 79 total messages
pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: kkoniec@mks.com.
Date: Fri, 15 Dec 2006 17:10
Date: Fri, 15 Dec 2006 17:10
692 lines
25779 bytes
25779 bytes
Posted-By: auto-faq 3.1.1.2 Archive-name: pl-comp-objects-faq --------------------------------------------------------------------------- Zawartosc: pl.comp.objects FAQ (Frequently Asked Questions and Summary) Data: 1998.08.18 Wersja: 3.2 Autorzy: Kuba Chabik Kamil Konieczny kkoniec@mks.com.pl --------------------------------------------------------------------------- Wykorzystane materialy: poprzednia (druga) edycja FAQ, opracowana przez Maciej "MACiAS" Pilichowski, macias@vm.cc.uni.torun.pl Data opracowania: 2.05.95 - 16.05.95 Zasoby: 6.12.94 - 12.04.95 ------- Uwagi: [ts 2005.12.27] To FAQ jest juz tak stare, ze chyba az przestarzale. Ale dopoki ktos nie wymysli nowego, to z braku innego bedzie wysylane nadal. Moze ktos sie zlituje i napisze/poprawi? [Kamil 1998.06.24]: Ze wzgledu na brak czasu edycja trzecia to glownie reorganizacja i poprawienie poprzedniej edycji, autorstwa [MACiAS]. W miare wolnego czasu bede dodawal nowe tematy, zaczynajac od biezacych listow az do zamierzchlej przeszlosci, czyli od roku 1998 do 1995. Nie beda dodawane tematy, nie majace nic (albo niewiele) wspolnego z tematyka grupy. Postaram sie rowniez o usuwanie z archiwow listy spamow, jak rowniez nieaktualnych ogloszen zwiazanych z obiektami. [MACiAS 1995.05.16]: W znakomitej wiekszosci wszystkie informacje zostaly wziete z listow uczestnikow grupy. Jesli zauwazycie ponizej bledy, niescislosci, luki, etc. to bardzo prosze o listy (jesli sprawa nie jest oczywista, to najlepiej na adres grupy). ------- Krotki spis tematow: T.1 Informacje ogolne (literatura, slowniczek, pojecia). T.2 Jezyk C++. T.3 Jezyk Smaltalk. T.4 Inne ------- Spis tematow: T.1.1 Literatura. T.1.1.1 Literatura w jezyku angielskim. T.1.1.2 Literatura w jezyku polskim. T.1.2 Proponowany maly slownik terminow. T.1.3 Co to jest klasa? T.1.4 Co to jest metoda? T.1.5 Co to jest atrybut? T.1.6 Co reprezentuje dziedziczenie? T.1.7 Co to jest polimorfizm? T.1.8 Co zyskujemy przez polimorfizm? T.1.9 Do czego potrzebna jest hermetyzacja? T.1.10 Co to jest klasa abstrakcyjna? T.1.11 Co to jest metaklasa? T.1.12 Co to jest komponent? T.1.13 Co to sa obiektowe bazy danych? T.1.14 Czy obiektowe bazy danych sa gorsze od relacyjnych? T.1.15 Co to jest CORBA? T.1.16 Czy programy obiektowe sa wolniejsze od proceduralnych? T.2.1 Jak w prosty sposob zrozumiec opis bledu w BC++? T.2.2 Co zrobic jesli klasa deklarowana w pliku naglowkowym uzywa typow T.2.3 Co to sa dziwne pliki w katalogu "/usr/g++-include/gen" z T.2.4 Jak w C++ obsluguje sie funkcje ze zmienna liczba parametrow? T.2.5 Czy mozna zaimplementowac funkcje wirtualne w C? T.2.6 Czy stosowanie zaprzyjazniania klas nalezy do dobrej praktyki T.2.7 Gdzie mozna dostac gramatyke C++ (obojetnie dla jakiego narzedzia, T.2.8 Czy przejscie do OOP wymaga odrzucenia "balastu proceduralnego"? T.2.9 Co to jest konstruktor kopiujacy? T.2.10 Czy istnieje domyslny konstruktor kopiujacy? T.2.11 Jak uniknac dolaczania metod wirtualnych, z ktorych nie korzystam, a T.2.12 Ciekawostki z historii C++. T.2.13 Stosowac wskaznik czy referencje? T.2.14 Co to sa sprytne wskazniki (smart pointers)? T.2.15 Czy wszystkie metody w mojej klasie powinny byc wirtualne? T.2.16 Czy konstruktory moga byc wirtualne? T.2.17 Jak tworzyc klasy abstrakcyjne? T.3.1 Czy jest dostepna darmowa implementacja Smalltalka? T.3.2 Czy SmallTalk jest dobry w praktyce, czy tylko w teorii? T.3.3 Gdzie mozna dowiedziec sie o jezyku Smalltalk i jego zastosowaniach? T.4.1 Jak powinienem zabrac sie za programowanie obiektowe? T.4.2 Czy OOP oznacza brak optymalizacji? T.4.3 Jak rozpoznawac, czy dany program lub projekt jest dobry ? T.4.4 Poszukuje informacji na temat rozszerzen do jezykow obiektowych --------------------------------------------------------------------------- ------- T.1.1 Literatura. T.1.1.1 Literatura w jezyku angielskim. Badouin-Lafon M., "Object-Oriented Languages" wyd ?, ISBN ? Brown W.H., Malveau R.C., McCormick H.W. III, Mowbray T.J., "AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis." John Wiley & Sons, ISBN 0-471-19713-0 Buchmann et al., "A System of Patterns" John Wiley & Sons, ISBN 0-471-95869-7 Budd, T., "An Introduction to Object Oriented Programming", Addison Wesley Publishing, ISBN 0-201-54709-0 Coleman D., et al, "The Fusion Method" wyd ?, ISBN ? Fowler M., Scott K., "UML Distilled" Addison-Wesley, ISBN 0-201-32563-2 Gamma E., Helm R., Johnson R., Vlissides J. "Design Patterns" Addison-Wesley, ISBN 0-201-63361-2 Graham I., "Object-Oriented Methods" 2nd ed. Addison-Wesley, ISBN 0-201-59371-8 http://www2.awl.com/cseng/ Jacobson I., Christerson M., Johnsson P., Overgaard G., "Object-Oriented Software Engineering" Addison-Wesley, ISBN 0-201-54435-0 Lakos J., "Large-Scale C++ Software Design" Addison-Wesley, ISBN 0-201-63362-0 Lalonde W.R., Pugh J.R., "Inside Smalltalk", Volume 1 and 2, Prentice Hall, ISBN ? Rumbaugh J., Blaha M., Premerlani W.,Eddy F.,Lorensen W., "Object-Oriented Modelling and Design" Prentince Hall, ISBN ? Stroustrup B., "The C++ Programming Language" 3rd. ed., 6th printing Addison-Wesley, ISBN 0-201-88954-4 http://www.research.att.com/~bs/homepage.html T.1.1.2 Literatura w jezyku polskim. Barteczko K., "Praktyczne wprowadzenie do programowania w jezyku C++", LUPUS, ISBN ISBN 83-85545-13-1 Coad P., Yourdon E., "Analiza obiektowa" (OOA), README, ISBN 83-85769-17-X Coad P., Yourdon E., "Projektowanie obiektowe" (OOD), README, ISBN 83-85769-18-8 Coad P., Nicola J., "Programowanie obiektowe" (OOP), README, ISBN 83-85769-16-1 Grebosz J., grebosz@bron.ifj.edu.pl, "Symfonia C++" Oficyna Kallimach, ISBN 83-901689-0-1 wydanie 3, Oficyna Kallimach, ISBN 83-901689-1-X Grebosz J., "Pasja C++" Oficyna Kallimach, ISBN 83-901689-2-8 Hansen T., "Zadania z jezyka C++", WNT, ISBN 83-204-1759-7 Kliszewski M., "Inzynieria oprogramowania obiektowego - analiza obiektowa", RESPEKT, ISBN 83-901994-0-8 Kain E., "Od C do C++" wyd ?, ISBN ? Lippman S.B., "Podstawy jezyka C++", Tlumaczenie z wydania 2, WNT, ISBN 83-204-1681-7 Martin J., Odell J.J., "Podstawy metod obiektowych" WNT, ISBN 83-204-2116-0 Stroustrup B., "Jezyk C++", Tlumaczenie wydania 2, WNT, ISBN 83-204-1697-3 Stroustrup B., "Projektowanie i rozwoj jezyka C++", WNT, ISBN 83-204-2042-3 ------- T.1.2 Proponowany maly slownik terminow. garbage collector - odsmiecacz operator overloading - przeciazanie operatora object persistency - trwanie obiektu persistent pointer - trwaly wskaznik container - pojemnik template - szablon reference - odnosnik dereferencing - wyluskiwanie ----- T.1.3 Co to jest klasa? Klasa jest abstrakcja obiektow z modelowanej dziedziny. Stanowi wzorzec, opis, z ktorego te obiekty beda tworzone. Klasa nic nie "robi", klasa czyms "jest". Klasy odwzorowuja przedmioty, osoby, a takze organizacje i procesy zachodzace w swiecie rzeczywistym. Klasa posiada jakas odpowiedzialnosc. Cos, dla czego nie potrafisz wskazac odpowiedzialnosci, klasa nie jest (najprawdodobniej jest jedyniem atrybutem innej klasy). ----- T.1.4 Co to jest metoda? Metoda, zwana takze operacja, reprezentuje czynnosc, jaka moze byc wykonana przez dany obiekt w swiecie rzeczywistym. Metody moga uzywane do uzyskania informacji lub do zmiany stanu danego obiektu. ----- T.1.5 Co to jest atrybut? Atrybut to cecha obiektu, na przyklad kolor pojazdu, dlugosc tekstu, wzrost osoby. Atrybuty sa innymi obiektami zagniezdzonymi w danym obiekcie. ----- T.1.6 Co reprezentuje dziedziczenie? Dziedziczenie reprezentuje specjalizacje. Mowimy, ze klasa dziedziczaca (subclass) "jest rodzaju" klasy bazowej (superclass). Innymi slowy, klasa bazowa reprezentuje pojecie bardziej ogolne, niz klasa dziedziczaca. ----- T.1.7 Co to jest polimorfizm? Metody polimorficzne to takie, ktore moga zachowywac sie roznie, w zaleznosci od tego, na rzecz jakiego konkretnego obiektu zostaly wywolane. Metode polimorficzna mozemy przedefiniowac w klasie implementujacej interfejs (czyli, najczesciej, dziedziczacej). Jezeli teraz inne obiekty beda wywolywac te metode dla obiektow nowej klasy, to bedzie wykonywala sie nowo, a nie stara metoda, choc same obiekty wolajace nie zauwaza zmiany. ----- T.1.8 Co zyskujemy przez polimorfizm? Dzieki polimorfizmowi uzyskujemy elastycznosc systemow, bowiem mozemy modyfikowac jedynie to, co rzeczywiscie nalezy zmienic, nie zas cale "otoczenie" konkretnej metody ----- T.1.9 Do czego potrzebna jest hermetyzacja? Hermetyzacja, czyli ukrywanie metod i atrybutow klas, daje nam bezpieczenstwo i przejrzystosc. Przypuscmy, ze mamy atrybut "godzinaRozpoczecia" klasy "Wyklad". Gdyby wszyscy mieli dostep do takiego atrybutu, mogloby sie zdarzyc, ze ktos ustawilby ja na liczbe wieksza od 23, co oczywiscie nie ma sensu. Jednakze dzieki hermetyzacji mozemy taka kontrole poprawnosci zawrzec w metodzie "zmienGodzineRozpoczecia" i odmowic ustawienia nieprawidlowej godziny. ----- T.1.10 Co to jest klasa abstrakcyjna? To taka klasa, ktora mozna tylko wykorzystywac przez dziedziczenie od niej, a nie mozna tworzyc jej obiektow. Klasy abstrakcyjne reprezentuja pojecia, ktore sa generalizacja innych pojec, ale same w sobie nie reprezentuja zadnych obiektow w dziedzinie. ----- T.1.11 Co to jest metaklasa? Metaklasa to jakby klasa dla klasy, innymi slowy, egzemplarze (instance) metaklas sa klasami. Metaklasy wystepuja nie we wszystkich jezykach programowania, a nawet w tych, w ktorych wystepuja, trudno wskazac ich konkretne, programistyczne zastosowanie. Jednakze czesto stosuje sie jej nawet o tym nie wiedzac. ----- T.1.12 Co to jest komponent? Komponent to grupa klas, ktore sluza jednemu, konkretnemu celowi. Klasy w komponencie charakteryzuja sie tym, ze maja silne powiazania z innymi klasami wewnatrz tego samego komponentu i slabe poza nim. Dzieki temu komponent moga byc rozwijane niezaleznie i podmieniane w razie potrzeby, bez modyfikacji innych komponentow. Przykladem komponentu moglaby byc grupa klas odpowiedzialna za obsluge wydruku. ----- T.1.13 Co to sa obiektowe bazy danych? Pojecie "bazy danych" nie jest szczegolnie szczesliwe. Lepiej mowic o "obiektach trwalych". Systemy takie pozwalaja na przechowanie stanu obiektu pomiedzy wywolaniami aplikacji, czyli tak, jak tradycyjna baza danych przechowuje dane. Jednakze roznica miedzy nimi a takimi bazami polega na fakcie, ze nie trzeba programowo odtwarzac stanu aplikacji z bazy (np. zapytaniami SQL). Po prostu obiekty aplikacji i obiekty bazy danych to to samo. ----- T.1.14 Czy obiektowe bazy danych sa gorsze od relacyjnych? To zalezy do czego. W przypadku odwzorowywania skomplikowanych zaleznosci sa o niebo lepsze. W przypadku plaskich, kartotekowych danych sa gorsze. Technologia ODBMS jest niewatpliwie mniej dojrzala od RDBMS, jednakze swoj okres "dzieciecy" ma juz na pewno za soba. ----- T.1.15 Co to jest CORBA? CORBA to skrot od Common Object Request Broker Architecture. Jest to architektura, ktore umozliwia komunikacje obiektom zlokalizowanym na roznych maszynach, roznych systemach operacyjnych, roznych architekturach sprzetowych komunikacje miedzy soba. W ramach standardu CORBA istnieja takze uslugi (CORBA services), np. kolekcje, zdarzenia (events), transakcje i inne. CORBA jest bardzo potezna architektura, ale nie ma zbyt dobrych implementacji, szczegolnie uslug. Ponadto organizacja OMG, ktora zdefiniowala CORBA'e, jest cialem biurokratycznym i nieruchawym. Spowalnia to rozwoj tego standardu. ----- T.1.16 Czy programy obiektowe sa wolniejsze od proceduralnych? Nie, to kompletna bzdura. Programowanie obiektowe pozwala na zastosowanie takich technik, ktore czynia program bezpieczniejszym, stabilniejszym, szybszym i bardziej elastycznym. Ponadto, technologia obiektowa pozwala tworzyc system w sposob bardziej rygorystyczny, a wiec pewniejszy i bardziej skoordynowany, niz technologia proceduralna. Skutkiem jest generalnie wyzsza jakosc systemow, szczegolnie tych powazniejszych, a wiec i wieksza szybkosc ich dzialania. Opinie taka programy obiektowe zawdzieczaja niedouczonym programistom, ktorzy, liznawszy odrobiny C++, poczuli sie ekspertami od obiektow i wyglaszali na prawo i lewo podobne bzdury. --------------------------------------------------------------------------- ----- T.2.1 Jak w prosty sposob zrozumiec opis bledu w BC++? Przeczytac opis bledu, zajrzec do "Programmer's Manual", "Programmer's Reference", podrecznika C++. Jesli nie pomoze, skontaktowac sie z innymi osobami piszacymi w C++. ----- T.2.2 Co zrobic jesli klasa deklarowana w pliku naglowkowym uzywa typow deklarowanych w innych plikach naglowkowych? W _kazdym_ pliku naglowkowym nalezy wpisac: #ifndef nazwapliku_h #define nazwapliku_h .. #endif I mozesz bezkarnie wlaczac potrzebne ci headery. ----- T.2.3 Co to sa dziwne pliki w katalogu "/usr/g++-include/gen" z roszerzeniami ".ccP" oraz ".hP"? Jest to po prostu biblioteka "libg++". Dowiedziec sie czegos wiecej mozesz z dokumentacji. A pliki z rozszerzeniem ".ccP" i ".hP" sa wejsciowymy plikami do programu "genclass". To sa pliki ze starej wersji kompilatora, ktory nie mial wlaczonych templates, wiec uzywalo sie tego i "genclass" specyfikujac jaki mial byc bazowy typ, "genclass" tworzyl z tego pliki np. "<type>Vec.cc" i "<type>Vec.h" zastepujac <T> podanym typem. ----- T.2.4 Jak w C++ obsluguje sie funkcje ze zmienna liczba parametrow? W starym C stosowalo sie <varargs.h>, w nowym (ANSI C oraz C++) stosuje sie <stdarg.h>. Ponizej przyklad programu wykorzystujacy <stdarg.h>. va_list - typ zmiennej pomocniczej va_start - inicjalizacja listy va_argptr - przesuniecie wskaznika listy na nastepny element #include <stdio.h> #include <stdarg.h> void pisz(char *tekst,...) { va_list argptr; va_start(argptr,tekst); printf("\nTo sa dane : %s",tekst); while(*(tekst=va_arg(argptr,char *))!=NULL) printf(" %s",tekst); va_end(argptr); }; void main() { pisz("ala","ola","kot","domek na prerii","i nic",NULL); }; Typowo to jest tak, ze pierwszy parametr zawiera informacje o liczbie dalszych parametrow. Moze to byc liczba, ale moze byc tak jak w "printf": printf("zmienna %s = %d",...) Tu jest podane, ze tylko dwoch parametrow trzeba sie doszukac. ----- T.2.5 Czy mozna zaimplementowac funkcje wirtualne w C? Tak - mozna to zrobic poprzez umieszczenie wskaznikow do funkcji razem z danymi, np: struct ojciec { int daneojca; int *funkcjaWirtualna(char *arg); }; struct syn { struct ojciec o; int danesyna; int *mojaFunkcjaWirtualna(); }; struct syn *konstuktor_syna() { struct syn *s = malloc(...); s->mojaFunkcjaWirtualna = syn_mojaFunkcja; s->o.funkcjaWirtualna = s->mojaFunkcjaWirtualna; // podmiana wskaznika // funkcji wirtualnej } czyli poprzez podmiane wskaznika do funkcji. Taka realizacja jednak umozliwa jednak uzywanie tylko pseudo-wirtualnych funkcji. Jesli chcemy uzywac naprawde takich funkcji uzyjmy jezyka obiektowego, gdyz w tych jezykach funkcja/metoda wirtualna wyroznia sie tym, ze niezaleznie od sposobu wywolania zawsze wykonana zostanie funkcja odpowiadajaca rzeczywistemu typowi klasy. Tak jak w ponizszym przykladzie: foobar( struct ojciec *o) { o->mojaFunkcjaWirtualna(); // jesli o jest wskaznikiem na syna // to wywolane zostanie syn_mojaFunkcja } ----- T.2.6 Czy stosowanie zaprzyjazniania klas nalezy do dobrej praktyki programisty? Nie, gdyz dopuszcza do latwego dostepu do pol prywatnych i chronionych. Narusza to zasade "jedyna aktywnosc systemu obiektowego to przekazywanie wiadomosci (message passing)". Istnieje roznica miedzy zapisaniem "kolo->radius=5;", a "kolo->setRadius(5);". ----- T.2.7 Gdzie mozna dostac gramatyke C++ (obojetnie dla jakiego narzedzia, preferowane yacc(bison), lex(flex) itp), ale koniecznie AT&T 2.0 (glownie chodzi o nested classes oraz templates)? Powinna byc w zrodlach GNU cc. Jest rowniez w B.Stroustrup "The C++ Programming Language", 3rd ed., Appendix A (niekompletna). ----- T.2.8 Czy przejscie do OOP wymaga odrzucenia "balastu proceduralnego"? Wczytujac sie w Stroustrupa "Jezyk C++" mozna zauwazyc jego slowa: nowe techniki programowania nie neguja starych - uzupelniaja je. To nie rewolucja. Tam gdzie wystarcza procedury lub moduly, nie szukamy obiektow. [czy ktos moze znalezc nr rozdzialu i paragrafu, lub nr strony ? Kamil] ----- T.2.9 Co to jest konstruktor kopiujacy? Konstruktor kopiujacy jest bardzo podobny do operatora przypisania, tyle ze o ile operator przypisania uzywany jest dla obiektow juz istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu raczej malo kto zrozumie :-) ): class A { private: int data; public: A(int new_data=0) : data(new_data) {}; // To jest zwykly // konstruktor A( A& a ) : data(a.data) {}; // A to konstruktor kopiujacy A& operator=(A &a) { data=a.data; return *this; } // a to // operator przypisania }; I teraz... main() { A a(1); // Tu zostanie wywolany zwykly konstruktor, z argumentem 1 A b; // Podbnie, tyle ze argument zostanie domyslnie // przyjety jako 0 A c=b; // Tutaj konstruktor kopiujacy z argumentem b A d; // A tutaj operator przypisania z tym samym argumentem d=b; }; Najwazniejsze w tym wszystkim sa ostatnie trzy linijki, bo tutaj wlasnie widac roznice, kiedy wywolywany jest operator przypisania, a kiedy konstruktor kopiujacy. Konstruktor kopiujacy jest tylko i wylacznie wtedy gdy przypisanie nastepuje rownoczesnie z utworzeniem. Dlaczego to wyroznienie? Pozwala to zaoszczedzic operacji, bo oczywiscie moglo by byc i tak ze kazda instrukcja typu "A b=c;" bylaby rozbijana na dwie: "A b; b=c;". Ale wtedy niepotrzebnie obiekt "b" bylby dwa razy inicjowany (w naszym przypadku najpierw "data=0", a potem "data=c.data"). Taka instrukcja jak "A b=c;" jest rownowazna po prostu "A b(c);" a nie (jak mogloby sie wydawac) parze instrukcji "A b; b=c;". Ponizsze przyklady takze sa ciekawe: class klasaA { public: klasaA metoda() { return (*this); }; ... }; Tutaj zostanie najpierw wykonana kopia obiektu (poprzez wywolanie kostruktora kopiujacego) i kopia zostanie zwrocona jako wynik metody; Trzeba bardzo uwazac na brak znaczku referencji "&"!!! class klasaA { public: klasaA& metoda() { klasaA temp; .... return temp; }; .... }; Poniewaz "temp" jest obiektem o czasie zycia tylko wewnatrz metody, wiec by moc zwrocic referencje do niego trzeba miec kopie o zasiegu wiekszym. Kopilator wiec wola konstruktor kopiujacy z argumentem "temp" i tworzy jego kopie na stercie i zwraca referencje do nowego obiektu. ----- T.2.10 Czy istnieje domyslny konstruktor kopiujacy? Tak - kopiuje poszczegolne pola. Z tego powodu nie nadaje sie do klas zawierajacych wskazniki - w efekcie otrzymujemy dwa obiekty wskazujace na ten sam (trzeci) obiekt. Jezeli teraz jeden z tych obiektow zostanie usuniety, to najprawdopodobniej zostanie tez zniszczony obiekt przez niego wskazywany, i drugi z obiektow bedzie wskazywal cos blednego. Dlatego tez gdy uzywamy operacji przypisania, a dana klasa zawiera wskazniki, to trzeba konstruktor kopiujacy zdefiniowac samemu, umieszczajac w nim operacje potrzebne do utworzenia kopii obiektu wskazywanego przez wskaznik. ----- T.2.11 Jak uniknac dolaczania metod wirtualnych, z ktorych nie korzystam, a sa zadeklaroawne w definicji objektu? Pozne laczenie ("late binding"), ktore UMOZLIWIA tworzenie metod wirtualnych, polega wlasnie na tym, ze program w momencie kompilacji i linkowania _nie wie_, ktore metody beda mu potrzebne. Inna sprawa ze zwyklymi metodami. ------- T.2.12 Ciekawostki z historii C++. Autorem C++ jest Bjarne Stroustrup. W swojej ksiazce "The Design and Evolution of C++" skladajac wyrazy holdu za wplyw na powstanie jezyka C++, Stroustrup wymienia m.in. nastepujace osoby: Briana Kernighana, Andrew Koeniga, Douga McIlroya, Jonathana Shopiro. Kristen Nygaard (Simula 67) i Dennis Ritchie (C) zajmuja na tej liscie miejsca szczegolnie eksponowane. W pazdzierniku 1979 roku istnial 1 uzytkownik C++ (C z klasami), w pazdzierniku 1981 C++ mial 38 uzytkownikow, w dziesiec lat pozniej - 400 000 osob przyznawalo sie do programowania w C++. A obecnie? Obecnie trwaja prace nad normalizacja jezyka C++, prowadzone przez kilka cial standaryzacyjnych. Standard jest juz zatwierdzony, i mozna go zakupic bezposrednio w ANSI. Bjarne Stroustrup od cwiercwiecza interesuje sie filozofia i historia. Jego sympatie do empirystow i awersja do idealistow, "uszczesliwiajacych" ludzkosc "tym, co dla niej dobre" (slowa Stroustrupa), wplynely na niektore decyzje i rozwiazania projektowe w C++. ------- T.2.13 Stosowac wskaznik czy referencje? Istnieja zasadnicze roznice miedzy wskaznikiem, a referencja: 1. Referencje nie moga byc puste 2. Raz ustawionej referencji nie mozna przeniesc na inny obiek 3. Nie mozna zrobic referencji do referencji, tak jak robi sie wskaznik do wskaznika. Generalnie, lepiej jest stosowac referencje. Jednakze jezeli z wyzej wymienionych powodow jest to niemozliwe, to nalezy zastosowac wskaznik. ------- T.2.14 Co to sa sprytne wskazniki (smart pointers)? Jest to szczegolny rodzaj klas, ktore definiuja operator rzutowania na typ pierwotny (ktory opakowuja). Z tego powodu moga byc stosowane w programie tak, jakby byly typu pierwotnego. Najbardziej znane przyklady sprytnych wskaznikow to string (opakowujacy wskaznik do char) i auto_ptr (szablon parametryzowany opakowywanym typem) ze standradowej biblioteki C++. ------- T.2.15 Czy wszystkie metody w mojej klasie powinny byc wirtualne? W zasadzie tak. Deklarujac metode jako niewirtualna uniemozliwiasz zmiane jej implementacji w klasie dziedziczacej, a tym samym zawezasz elastycznosc swojego systemu. Jednakze w przypadku metod prostych, np. jedynie zwracajacych referencje do atrybutu, lepiej zrobic je inline, a metoda inline nie moze byc wirtualna. ------- T.2.16 Czy konstruktory moga byc wirtualne? Nie. Ale mozna stworzyc odpowiednik konstruktora wirtualnego. Opisuje to wzorzec Abstract Factory z ksiazki "Design Patterns", Gamma et al. ------- T.2.17 Jak tworzyc klasy abstrakcyjne? Klasa abstrakcyjna jest kazda klasa, ktora ma choc jedna metode czysto wirtualna (abstrakcyjna), czyli zadeklarowana, a nie zaimplementowana. Mozna klase uczynic abstrakcyjna takze deklarujac wszystkie jej konstruktory jako prywatne lub chronione (protected). --------------------------------------------------------------------------- ----- T.3.1 Czy jest dostepna darmowa implementacja Smalltalka? Tak - w ramach GNU. Znalezc go mozna w wiekszosci katalogow z GNU. ----- T.3.2 Czy SmallTalk jest dobry w praktyce, czy tylko w teorii? W przypadku Smalltalka o teorii mogla byc mowa jakies 10 lat temu. Teraz jest to praktyka. Niejaki Dave Thomas z Kanady odpowiedzial na to pytanie w bardzo ciekawym referacie. Oto, co wdrozono na Smalltalku: 1. Centrale telefoniczna dla kilkudziesieciotysiecznego miasta. 2. "Zastosowania specjalne". 3. IBM zatrudnil ostatnio (pocz.'94) okolo 300 programistow w Smalltalku. Chyba nie do podlewania kwiatkow. 4. System analizy jakosci programow napisanych w C. Tyle pamietam. Inna sprawa, ze Smalltalk nie dorownuje C++ rozpowszechnieniu, wiec i produkty komercyjne nie sa tak czeste. Ja nie potrafie podac zadnych, ale w C++ to chyba tez tylko te, w ktorych pisaniu sam uczestniczylem. Czytalem, ze zrobienie jednej klasy w Smalltalku zajmuje 1 osobodni, w C++ trzy razy tyle. Oczywiscie slyszalem to od entuzjastki Smalltalka, wiec trzeba wziac poprawke. ----- T.3.3 Gdzie mozna dowiedziec sie o jezyku Smalltalk i jego zastosowaniach? Pod nastepujacym adresem: http://www.stic.org Jest to adres Smalltalk Industry Council, instytucji zrzeszajacej firmy produkujace oprogramowanie i narzedzia do Smalltalka. Pod tym adresem znalezc mozna liste dostepnych kompilatorow (komercyjnych i darmowych), firmy produkujace biblioteki i narzedzia, materialy do nauki Smalltalka, informacje o wybranych projektach wykonanych przy pomocy Smalltalka oraz porownanie sprawnosci Smalltalka z jezykami C i C++. --------------------------------------------------------------------------- ----- T.4.1 Jak powinienem zabrac sie za programowanie obiektowe? Wykonac analize i projekt. Wybrac jezyk i zaimplementowac projekt. Na poczatek doradzam kilka niewielkich projektow. Nie zaszkodzi poczytac o analizie, projektowaniu i programowaniu obiektowym. ----- T.4.2 Czy OOP oznacza brak optymalizacji? Ani tak, ani nie - zaden jezyk z gory nie zaklada braku optymalizacji. To zalezy tylko i wylacznie od konkretnego programu. ----- T.4.3 Jak rozpoznawac, czy dany program lub projekt jest dobry ? Mozliwe kryteria: o dziala - dobrze, nie dziala - zle o stopien realizacji obiektow jako "czarnych skrzynek" o zbyt mala lub zbyt duza wiedza klas o czytelnosc o podatnosc na zmiany o powiazania miedzy modulami o mozliwosc powtornego uzycia ----- T.4.4 Poszukuje informacji na temat rozszerzen do jezykow obiektowych (C++, Smalltalk, Eiffel), takich jak np. O++ do C++ O++ jest rozszerzeniem C++ pozwalajacym na tworzenie obiektow trwalych (persistent), manipulowanie nimi, laczenie w clustery etc. Jesli chodzi o Smalltalk, to jego rozszerzeniem jesli silnie stypizowany Strongtalk. --------------------------------------------------------------------------- end of pl.comp.object FAQ and Summary ---------------------------------------------------------------------------
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: SasQ
Date: Thu, 22 Feb 2007 20:14
Date: Thu, 22 Feb 2007 20:14
121 lines
4684 bytes
4684 bytes
Dnia Fri, 15 Dec 2006 17:10:05 +0000, Kamil Konieczny napisa³(a): > T.2.4 Jak w C++ obsluguje sie funkcje ze zmienna liczba parametrow? > > W starym C stosowalo sie <varargs.h>, w nowym (ANSI C oraz C++) > stosuje sie <stdarg.h> Je¶li mowa o C++, to chyba raczej <cstdarg> > void main() Je¶li przyk³ad by³ dla C++, to raczej int main(). Standard ANSI/ISO C++ nie dopuszcza void dla main. > T.2.6 Czy stosowanie zaprzyjazniania klas nalezy do dobrej > praktyki rogramisty? > > Nie, gdyz dopuszcza do latwego dostepu do pol prywatnych i > chronionych. Ale nie ka¿demu ;) Tylko wybranym. Przyja¼ñ wcale nie jest "zamachem na enkapsulacjê", bo klasa deklaruj±ca przyja¼ñ sama decyduje o tym, z kim siê przyja¼ni i robi to z pe³n± ¶wiadomo¶ci± ;) Poza tym je¶li ju¿ jest deklaracja przyja¼ni, to jest ona czê¶ci± interfejsu klasy i daje sygna³, ¿e dwie klasy s± ze sob± ¶ci¶le powi±zane i dzia³aj± wspólnie. > T.2.9 Co to jest konstruktor kopiujacy? > > Konstruktor kopiujacy jest bardzo podobny do operatora przypisania, > tyle ze o ile operator przypisania uzywany jest dla obiektow juz > istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i > jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu > raczej malo kto zrozumie :-) ): Czemu? Po prostu chodzi o zwyczajn± inicjalizacjê nowo tworzonego biektu warto¶ci± innego obiektu tego samego typu ;) > main() A typ warto¶ci zwracanej to zjad³ pies? :P > A d; // A tutaj operator przypisania z tym samym argumentem Raczej linijkê ni¿ej ;) o tu: > d=b; > Konstruktor kopiujacy jest tylko i wylacznie wtedy gdy > przypisanie nastepuje rownoczesnie z utworzeniem. Ale wtedy to nie jest przypisanie, tylko inicjalizacja ;P Przypisuje siê do obiektów ju¿ skonstruowanych. Jak nie ³apiesz ró¿nicy, to spróbuj z obiektami const: mo¿na je tylko inicjalizowaæ, ale nie mo¿na do nich ju¿ pó¼niej przypisywaæ. > Dlaczego to wyroznienie? Pozwala to zaoszczedzic operacji, > bo oczywiscie moglo by byc i tak ze kazda instrukcja typu > "A b=c;" bylaby rozbijana na dwie: "A b; b=c;". Tu akurat nie to jest najwa¿niejsze ;) Ponownie polecam popróbowaæ z const ;) Je¶li obiekt jest const, nie mo¿esz do niego ju¿ nic przypisaæ po utworzeniu. Je¶li chcesz ustawiæ warto¶æ obiektu sta³ego "na wzór" innego obiektu, to jedyny moment, gdzie jest to mo¿liwe, jest przy konstruowaniu. Pó¼niej jest ju¿ "po ptokach" :P I tu siê w³a¶nie przydaje konstruktor kopiuj±cy, zwany te¿ "inicjalizatorem kopiuj±cym" ;J > Ale wtedy niepotrzebnie obiekt "b" bylby dwa razy inicjowany Inicjuje siê czynno¶ci. Obiekty siê inicjalizuje. I nie s³uchaj s³ownika Kopaliñskiego, jego autorzy nie wiedz± co to jest programowanie ;) > Najbardziej znane przyklady sprytnych wskaznikow to string > (opakowujacy wskaznik do char) ?? :P Tak rozumuj±c, to ka¿da klasa, która zawiera³aby w swojej implementacji jakie¶ wska¼niki i je obs³ugiwa³a, musia³aby byæ "sprytnym wska¼nikiem" :P Ja bym raczej zawêzi³ ten termin do obiektów "symuluj±cych" zwyk³e wska¼niki w widoczny sposób. > Opisuje to wzorzec Abstract Factory z ksiazki "Design > Patterns", Gamma et al. "et al." to skrót od ³aciñskiego "et alii" = "i inni" ;J > Klasa abstrakcyjna jest kazda klasa, ktora ma choc jedna metode > czysto wirtualna (abstrakcyjna), czyli zadeklarowana, a nie > zaimplementowana. Mozna klase uczynic abstrakcyjna takze deklarujac > wszystkie jej konstruktory jako prywatne lub chronione (protected). No nie wiem ;J Uczynienie konstruktora prywatnym lub chronionym jeszcze nie czyni klasy abstrakcyjn±, bo obiekty tej klasy wbrew pozorom nadal mog± byæ tworzone, tylko nie ka¿demu wolno to robiæ ;J Je¶li konstruktor jest private, to wolno tworzyæ obiekt tylko z wnêtrza klasy, a je¶li protected, to dodatkowo z wnêtrza klas pochodnych. Klasa "dla samej siebie" albo "dla siebie i rodzinki" nie jest ju¿ wtedy wcale abstrakcyjna. Podobnie je¶li klasa ma prywatny konstruktor, ale przyja¼ni siê z jak±¶ funkcj± która mo¿e ten konstruktor prywatny wtedy wywo³aæ i utworzyæ obiekty tej klasy, to klasa ju¿ nie mo¿e byæ traktowana jako abstrakcyjna :P Dlatego zawêzi³bym t± definicjê tylko dla klas, które maj± choæ jedn± metodê czysto wirtualn±, bo tylko to daje pe³n± gwarancjê, ¿e nie powstanie ¿aden obiekt tej klasy, choæby i na jej w³asny u¿ytek prywatny ;J Klasa Ssak jest dobrym przyk³adem klasy abstrakcyjnej. Je¶li chcia³by¶ j± uzyskaæ ukrywaj±c konstruktor, to nadal klasa mo¿e stworzyæ instancjê Ssaka :P [np. z metody statycznej albo zaprzyja¼nionej] i co wtedy? :D Widzia³e¶ kiedy ssaka luzem? ;) P.S.: chodzi³em z jednym Kamilem Koniecznym do podstawówki :J Mo¿e to ty? :D Jeste¶ mo¿e z ¯ywca? ;J -- SasQ
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: rwt
Date: Thu, 22 Feb 2007 23:29
Date: Thu, 22 Feb 2007 23:29
74 lines
2805 bytes
2805 bytes
Odpowiedź do listu Wielce Szanownej Pani / Szanownego Pana ‹SasQ›. Wysłannik wyższej inteligencji tako rzecze :): >> T.2.9 Co to jest konstruktor kopiujacy? >> Konstruktor kopiujacy jest bardzo podobny do operatora przypisania, >> tyle ze o ile operator przypisania uzywany jest dla obiektow juz >> istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i >> jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu >> raczej malo kto zrozumie :-) ): > Czemu? Po prostu chodzi o zwyczajną inicjalizację nowo tworzonego > biektu wartością innego obiektu tego samego typu ;) >> A d; // A tutaj operator przypisania z tym samym argumentem > Raczej linijkę niżej ;) o tu: >> d=b; >> Konstruktor kopiujacy jest tylko i wylacznie wtedy gdy >> przypisanie nastepuje rownoczesnie z utworzeniem. > Ale wtedy to nie jest przypisanie, tylko inicjalizacja ;P > Przypisuje się do obiektów już skonstruowanych. > Jak nie łapiesz różnicy, to spróbuj z obiektami const: > można je tylko inicjalizować, ale nie można do nich już > później przypisywać. >> Dlaczego to wyroznienie? Pozwala to zaoszczedzic operacji, >> bo oczywiscie moglo by byc i tak ze kazda instrukcja typu >> "A b=c;" bylaby rozbijana na dwie: "A b; b=c;". > Tu akurat nie to jest najważniejsze ;) > Ponownie polecam popróbować z const ;) > Jeśli obiekt jest const, nie możesz do niego już nic przypisać > po utworzeniu. Jeśli chcesz ustawić wartość obiektu stałego > "na wzór" innego obiektu, to jedyny moment, gdzie jest to możliwe, > jest przy konstruowaniu. Później jest już "po ptokach" :P > I tu się właśnie przydaje konstruktor kopiujący, zwany też > "inicjalizatorem kopiującym" ;J >> Ale wtedy niepotrzebnie obiekt "b" bylby dwa razy inicjowany > Inicjuje się czynności. Obiekty się inicjalizuje. > I nie słuchaj słownika Kopalińskiego, jego autorzy nie wiedzą > co to jest programowanie ;) >> Najbardziej znane przyklady sprytnych wskaznikow to string >> (opakowujacy wskaznik do char) > ?? :P > Tak rozumując, to każda klasa, która zawierałaby w swojej > implementacji jakieś wskaźniki i je obsługiwała, musiałaby > być "sprytnym wskaźnikiem" :P Ja bym raczej zawęził ten termin > do obiektów "symulujących" zwykłe wskaźniki w widoczny sposób. Można by zauważyć, że dla zmiennych typu klasa nie zachodzą przypisania. Tak naprawdę dla nich są tylko inicjalizacje. Natomiast przypisania pozostały dla zmiennych prymitywnych oraz referencji, wskaźników. Wasz -- / qo |) :@=N%_g=v=a=g_eD_e=c()=d=8! =%!Gn@8're. w8in/ad \ _x/ , ;h-%-a'hA'H4,X0'Xo~xo~xO,R`-%EXp01ITed: *-7/+eh / | ng `-%__%--'__%--'__%--~__%--^%B`/$qV3r[o; &GooMee L o_O http://tech.groups.yahoo.com/group/opRWTng O_o L"EnOF"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Mon, 26 Feb 2007 09:58
Date: Mon, 26 Feb 2007 09:58
33 lines
1248 bytes
1248 bytes
rwt wrote: > Odpowied¼ do listu Wielce Szanownej Pani / Szanownego Pana ?SasQ?. > Wys³annik wy¿szej inteligencji tako rzecze :): > >>> T.2.9 Co to jest konstruktor kopiujacy? > >>> Konstruktor kopiujacy jest bardzo podobny do operatora przypisania, >>> tyle ze o ile operator przypisania uzywany jest dla obiektow juz >>> istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i >>> jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu >>> raczej malo kto zrozumie :-) ): > >> Czemu? Po prostu chodzi o zwyczajn± inicjalizacjê nowo tworzonego >> biektu warto¶ci± innego obiektu tego samego typu ;) (...) > > Mo¿na by zauwa¿yæ, ¿e dla zmiennych typu klasa nie zachodz± > przypisania. Tak naprawdê dla nich s± tylko inicjalizacje. Natomiast > przypisania pozosta³y dla zmiennych prymitywnych oraz referencji, > wska¼ników. Pomimo, ¼e do¶æ uwa¿nie przeczyta³em komentarz SasQ, nie bardzo rozumiem Twoj± odpowied¼. Czy móg³by¶ to nieco rozwin±æ? No i pytanie podstawowe: dlaczego uwa¿asz, ¿e dla obiektów nie wystêpuj± tutaj przypisania a jedynie "przypisania (...) dla zmiennych prymitywnych"? Przypominam, ¿e mowa jest o C++ a nie jakim¶ zorientowanym na referencje jêzyku jak Java czy Python. -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: rwt
Date: Mon, 26 Feb 2007 20:10
Date: Mon, 26 Feb 2007 20:10
49 lines
2249 bytes
2249 bytes
Odpowiedź do listu Wielce Szanownej Pani / Szanownego Pana ‹Mariusz Lotko›. Wysłannik wyższej inteligencji tako rzecze :): > rwt wrote: >> Odpowiedź do listu Wielce Szanownej Pani / Szanownego Pana ?SasQ?. >> Wysłannik wyższej inteligencji tako rzecze :): >>>> T.2.9 Co to jest konstruktor kopiujacy? >>>> Konstruktor kopiujacy jest bardzo podobny do operatora przypisania, >>>> tyle ze o ile operator przypisania uzywany jest dla obiektow juz >>>> istniejacych, to konstruktor kopiujacy gdy tworzymy nowy obiekt i >>>> jednoczesnie nadajemy mu jakas wartosc. Przyklad (bo bez przykladu >>>> raczej malo kto zrozumie :-) ): >>> Czemu? Po prostu chodzi o zwyczajną inicjalizację nowo tworzonego >>> biektu wartością innego obiektu tego samego typu ;) > (...) >> Można by zauważyć, że dla zmiennych typu klasa nie zachodzą >> przypisania. Tak naprawdę dla nich są tylko inicjalizacje. Natomiast >> przypisania pozostały dla zmiennych prymitywnych oraz referencji, >> wskaźników. > Pomimo, źe dość uważnie przeczytałem komentarz SasQ, nie bardzo > rozumiem Twoją odpowiedź. Czy mógłbyś to nieco rozwinąć? No i > pytanie podstawowe: dlaczego uważasz, że dla obiektów nie występują > tutaj przypisania a jedynie "przypisania (...) dla zmiennych > prymitywnych"? Przypominam, że mowa jest o C++ a nie jakimś > zorientowanym na referencje języku jak Java czy Python. Być może w języku nadal pozostaje operator przypisania (jak we wcześniejszym cytacie), ale… obiekty, które mają program wiążący z mechanizmami języka, inny niż zformalizowany, czyli inny niż otwarty mimo że istniejący (jak w językach funkcyjnych)— po zwykłym skopiowaniu wartości przez sam związek z innymi obiektami tworzony przez ten program stają się klonami a nie kopiami. Oczywiście jeszcze innego rodzaju operacją jest ‚przypisanie’ do zmiennej typu klasy dziedziczącej dany typ. Mimo że do wszystkiego używa się tego samego operatora. Wasz -- / qo |) :@=N%_g=v=a=g_eD_e=c()=d=8! =%!Gn@8're. w8in/ad \ _x/ , ;h-%-a'hA'H4,X0'Xo~xo~xO,R`-%EXp01ITed: *-7/+eh / | ng `-%__%--'__%--'__%--~__%--^%B`/$qV3r[o; &GooMee L o_O http://tech.groups.yahoo.com/group/opRWTng O_o L"EnOF"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: SasQ
Date: Mon, 26 Feb 2007 22:12
Date: Mon, 26 Feb 2007 22:12
75 lines
3097 bytes
3097 bytes
Dnia Mon, 26 Feb 2007 20:10:02 +0100, rwt napisa³(a): > Byæ mo¿e w jêzyku nadal pozostaje operator przypisania (jak we > wcze¶niejszym cytacie), ale... obiekty, które maj± program wi±¿±cy > z mechanizmami jêzyka, inny ni¿ zformalizowany, czyli inny ni¿ > otwarty mimo ¿e istniej±cy (jak w jêzykach funkcyjnych)- po > zwyk³ym skopiowaniu warto¶ci przez sam zwi±zek z innymi obiektami > tworzony przez ten program staj± siê klonami a nie kopiami. Atak klonów ;) Przyznam ¿e ja te¿ nie zrozumia³em poprzednio, a to "wyja¶nienie" jeszcze bardziej mi zamiesza³o i nic z tego nie rozumiem :P Poniewa¿ w programowaniu liczy siê precyzja, pozwolê sobie zadaæ kilka pytañ o s³ownictwo, którego u¿ywasz, by¶my siê dobrze rozumieli i pos³ugiwali siê tymi samymi definicjami: 1) Co to s± "zmienne typu klasa"? Moje definicje u¿ytych tutaj s³ów przedstawiaj± siê tak: zmienna: typ obiektu, który mo¿e zmieniaæ swój stan. sta³a: typ obiektu, który nie mo¿e zmieniaæ swojego stanu. stan: warto¶æ ;) obiekt: wydzielony jednolity i ci±g³y obszar pamiêci, który ma jasno okre¶lony typ. typ: okre¶la jakie warto¶ci/stany mo¿e przyjmowaæ obiekt, jak te stany mog± siê zmieniaæ, oraz jakie operacje mo¿na na tym obiekcie wykonywaæ klasa: definiuje nowy typ obiektu 2) Dlaczego mia³yby nie zachodziæ dla nich przypisania? Moja definicja przypisania: Skopiowanie stanu [warto¶ci] jednego obiektu do drugiego, zastêpuj±c poprzedni± warto¶æ obiektu docelowego. 3) Czemu dla nich mia³yby byæ tylko inicjalizacje? Moja definicja inicjalizacji: Nadanie pocz±tkowej warto¶ci obiektowi w momencie jego utworzenia [mo¿na to zrobiæ tylko wtedy]. 4) Co to s± zmienne prymitywne? Czy chodzi³o ci mo¿e o zmienne [lub w ogólno¶ci obiekty] typów wbudowanych? Typy wbudowane: istniej±ce w jêzyku od pocz±tku, nie definiowane przez u¿ytkownika. 5) Dlaczegó¿ to tylko dla nich pozostaj± przypisania? 6) "Byæ mo¿e w jêzyku nadal pozostaje operator przypisania" Mówisz tutaj o operatorze przypisania dla jakiego typu? Jednego z typów wbudowanych? Bo nie wiem jak inaczej zrozumieæ ¿e on "pozostaje w jêzyku". 7) "obiekty, które maj± program wi±¿±cy z mechanizmami jêzyka, inny ni¿ zformalizowany, czyli inny ni¿ otwarty" Co to jest "program wi±¿±cy z mechanizmami jêzyka"? A co to jest "program sformalizowany" czy "program otwarty"? [o ile dobrze zrozumia³em sens logiczny tego zdania :P] 8) "mimo ¿e istniej±cy (jak w jêzykach funkcyjnych)- po zwyk³ym skopiowaniu warto¶ci przez sam zwi±zek z innymi obiektami tworzony przez ten program" Tego to ju¿ nijak nie potrafiê ugry¼æ :| Nawet nie wiem o co zapytaæ, bo zupe³nie nie jarzê sensu tego zdania :7 9) "staj± siê klonami a nie kopiami" Czym siê ró¿ni kopia od klonu? 10) "Oczywi¶cie jeszcze innego rodzaju operacj± jest 'przypisanie' do zmiennej typu klasy dziedzicz±cej dany typ." Co to jest "zmienna typu klasy dziedzicz±cej dany typ"? :P 11) "Mimo ¿e do wszystkiego u¿ywa siê tego samego operatora." Czyli do czego, i jakiego operatora? Bo z kontekstu tego nie mogê wyczytaæ... -- SasQ
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: rwt
Date: Mon, 26 Feb 2007 22:29
Date: Mon, 26 Feb 2007 22:29
9 lines
281 bytes
281 bytes
Che, che. Pełna analiza. Wasz -- / qo |) :@=N%_g=v=a=g_eD_e=c()=d=8! =%!Gn@8're. w8in/ad \ _x/ , ;h-%-a'hA'H4,X0'Xo~xo~xO,R`-%EXp01ITed: *-7/+eh / | ng `-%__%--'__%--'__%--~__%--^%B`/$qV3r[o; &GooMee L o_O http://tech.groups.yahoo.com/group/opRWTng O_o L"EnOF"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Mon, 26 Feb 2007 23:55
Date: Mon, 26 Feb 2007 23:55
8 lines
112 bytes
112 bytes
rwt wrote: > Che, che. Pe³na analiza. Wygl±da to raczej na atak trolli ni¿ atak klonów :-) -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: SasQ
Date: Tue, 27 Feb 2007 00:02
Date: Tue, 27 Feb 2007 00:02
13 lines
335 bytes
335 bytes
Dnia Mon, 26 Feb 2007 23:55:29 +0100, Mariusz Lotko napisa³(a): > rwt wrote: > >> Che, che. Pe³na analiza. > > Wygl±da to raczej na atak trolli ni¿ atak klonów :-) A mo¿e bot spamerski? :) Ostatnio pojawi³y siê takie, co bior± s³ownik z danej dziedziny i generuj± losowe zestawienia s³ów, przypominaj±ce normalny tekst ;) -- SasQ
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: pdemb@gazeta.pl
Date: Wed, 28 Feb 2007 15:32
Date: Wed, 28 Feb 2007 15:32
14 lines
413 bytes
413 bytes
SasQ <sasq1@go2.pl> writes: > Dnia Mon, 26 Feb 2007 23:55:29 +0100, Mariusz Lotko napisa³(a): > >> rwt wrote: >> >>> Che, che. Pe³na analiza. >> >> Wygl±da to raczej na atak trolli ni¿ atak klonów :-) > > A mo¿e bot spamerski? :) Ostatnio pojawi³y siê takie, co bior± > s³ownik z danej dziedziny i generuj± losowe zestawienia s³ów, > przypominaj±ce normalny tekst ;) Ano s±: http://pdos.csail.mit.edu/scigen/.
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Thu, 01 Mar 2007 10:51
Date: Thu, 01 Mar 2007 10:51
94 lines
4041 bytes
4041 bytes
Dnia Mon, 26 Feb 2007 22:12:45 +0100, SasQ skrobie: > Dnia Mon, 26 Feb 2007 20:10:02 +0100, rwt napisa³(a): > > Byæ mo¿e w jêzyku nadal pozostaje operator przypisania (jak we > > wcze¶niejszym cytacie), ale... obiekty, które maj± program wi±¿±cy > > z mechanizmami jêzyka, inny ni¿ zformalizowany, czyli inny ni¿ > > otwarty mimo ¿e istniej±cy (jak w jêzykach funkcyjnych)- po > > zwyk³ym skopiowaniu warto¶ci przez sam zwi±zek z innymi obiektami > > tworzony przez ten program staj± siê klonami a nie kopiami. > Atak klonów ;) Nie ma siê co ¶miaæ. Kopiowanie nie zachodzi dla obiektów typów niewarto¶ciowych, a jedynie dla obiektów typów warto¶ciowych. Kopiowaniu podlega wtedy owa "warto¶æ", która mo¿e byæ dowolnie przenoszona pomiêdzy poszczególnymi obiektami. Natomiast obiekty niewarto¶ciowe, jak sama nazwa wskazuje, warto¶ci nie maj±, wiêc one podlegaj± klonowaniu - tworzy siê nowy obiekt o nowej to¿samo¶ci. W obiektach warto¶ciowych to¿samo¶ci± jest warto¶æ. > Przyznam ¿e ja te¿ nie zrozumia³em poprzednio, a to "wyja¶nienie" > jeszcze bardziej mi zamiesza³o i nic z tego nie rozumiem :P > Poniewa¿ w programowaniu liczy siê precyzja, pozwolê sobie > zadaæ kilka pytañ o s³ownictwo, którego u¿ywasz, by¶my siê > dobrze rozumieli i pos³ugiwali siê tymi samymi definicjami: > 1) Co to s± "zmienne typu klasa"? > Moje definicje u¿ytych tutaj s³ów przedstawiaj± siê tak: > zmienna: typ obiektu, który mo¿e zmieniaæ swój stan. > sta³a: typ obiektu, który nie mo¿e zmieniaæ swojego stanu. > stan: warto¶æ ;) Dok³adnie to bie¿±ca warto¶æ, w przypadku typów warto¶ciowych. W pozosta³ych bêdzie to zespó³ wszystkich warto¶ci sk³adowych obiektu (je¶li sk³adow± jest obiekt, to jeszcze i jego warto¶ci itd.) > obiekt: wydzielony jednolity i ci±g³y obszar pamiêci, który > ma jasno okre¶lony typ. > typ: okre¶la jakie warto¶ci/stany mo¿e przyjmowaæ obiekt, > jak te stany mog± siê zmieniaæ, oraz jakie operacje > mo¿na na tym obiekcie wykonywaæ > klasa: definiuje nowy typ obiektu > 2) Dlaczego mia³yby nie zachodziæ dla nich przypisania? > Moja definicja przypisania: > Skopiowanie stanu [warto¶ci] jednego obiektu do drugiego, > zastêpuj±c poprzedni± warto¶æ obiektu docelowego. S³usznie, pod warunkiem, ¿e to jest obiekt warto¶ciowy. > 3) Czemu dla nich mia³yby byæ tylko inicjalizacje? > Moja definicja inicjalizacji: > Nadanie pocz±tkowej warto¶ci obiektowi w momencie jego > utworzenia [mo¿na to zrobiæ tylko wtedy]. Znów - w przypadku typów warto¶ciowych. W pozosta³ych jest to po prostu inicjalizacja sk³adowych - a dalej ju¿ jak wy¿ej. > 4) Co to s± zmienne prymitywne? > Czy chodzi³o ci mo¿e o zmienne [lub w ogólno¶ci obiekty] > typów wbudowanych? > Typy wbudowane: istniej±ce w jêzyku od pocz±tku, nie > definiowane przez u¿ytkownika. Kwestia czy to s± typy wbudowane, czy nie, zale¿y od jêzyka. W Javie np. nie ma innych typów warto¶ciowych ni¿ wbudowane - plus referencje, przy czym warto¶ci± zmiennej referencyjnej jest referencja do okre¶lonego obiektu (lub null). W C++ mo¿emy sobie dowolnie tworzyæ typy warto¶ciowe. > 5) Dlaczegó¿ to tylko dla nich pozostaj± przypisania? Dla typów warto¶ciowych. > 6) "Byæ mo¿e w jêzyku nadal pozostaje operator przypisania" > Mówisz tutaj o operatorze przypisania dla jakiego typu? > Jednego z typów wbudowanych? Bo nie wiem jak inaczej > zrozumieæ ¿e on "pozostaje w jêzyku". Te¿ nie rozumiem ;) > 9) "staj± siê klonami a nie kopiami" > Czym siê ró¿ni kopia od klonu? Tym w³a¶nie, ¿e sklonowany obiekt staje siê osobnym obiektem z w³asnym zestawem stanów. Obiekty warto¶ciowe maj± okre¶lon± to¿samo¶æ przez warto¶æ, wiêc po wykonaniu a = b, 'a' staje siê "tym samym" co b - dopóki kto¶ nie przypisze mu innej warto¶ci. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: rwt
Date: Fri, 02 Mar 2007 09:26
Date: Fri, 02 Mar 2007 09:26
19 lines
623 bytes
623 bytes
Odpowiedź do listu Wielce Szanownej Pani / Szanownego Pana ‹Mariusz Lotko›. Wysłannik wyższej inteligencji tako rzecze :): > rwt wrote: >> Che, che. Pełna analiza. > Wygląda to raczej na atak trolli niż atak klonów :-) Zrozumiałeś, o czym pisałem, czy wypowiadasz się, by zaistnieć? Nie ukrywam, że odpowiedź lub jej brak zadecyje o ignorowaniu. Wasz -- / qo |) :@=N%_g=v=a=g_eD_e=c()=d=8! =%!Gn@8're. w8in/ad \ _x/ , ;h-%-a'hA'H4,X0'Xo~xo~xO,R`-%EXp01ITed: *-7/+eh / | ng `-%__%--'__%--'__%--~__%--^%B`/$qV3r[o; &GooMee L o_O http://tech.groups.yahoo.com/group/opRWTng O_o L"EnOF"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Sat, 03 Mar 2007 12:19
Date: Sat, 03 Mar 2007 12:19
18 lines
440 bytes
440 bytes
rwt wrote: >>> Che, che. Pe³na analiza. > >> Wygl±da to raczej na atak trolli ni¿ atak klonów :-) > > Zrozumia³e¶, o czym pisa³em, czy wypowiadasz siê, by zaistnieæ? > Nie ukrywam, ¿e odpowied¼ lub jej brak zadecyje o ignorowaniu. Ignoruj. Czy Twoja "wypowied¼" (patrz piersza linijka) zas³uguje na co¶ wiêcej? A co do "zaistnienia" - to nie ja wymy¶lam niestworzone teorie na temat rzeczy prostych i zrozumia³ych. -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Sat, 03 Mar 2007 12:26
Date: Sat, 03 Mar 2007 12:26
30 lines
1208 bytes
1208 bytes
Sektor van Skijlen wrote: > Dnia Mon, 26 Feb 2007 22:12:45 +0100, SasQ skrobie: >> Dnia Mon, 26 Feb 2007 20:10:02 +0100, rwt napisa³(a): > >> > Byæ mo¿e w jêzyku nadal pozostaje operator przypisania (jak we >> > wcze¶niejszym cytacie), ale... obiekty, które maj± program wi±¿±cy >> > z mechanizmami jêzyka, inny ni¿ zformalizowany, czyli inny ni¿ >> > otwarty mimo ¿e istniej±cy (jak w jêzykach funkcyjnych)- po >> > zwyk³ym skopiowaniu warto¶ci przez sam zwi±zek z innymi obiektami >> > tworzony przez ten program staj± siê klonami a nie kopiami. > >> Atak klonów ;) > > Nie ma siê co ¶miaæ. > > Kopiowanie nie zachodzi dla obiektów typów niewarto¶ciowych, a jedynie dla > obiektów typów warto¶ciowych. Kopiowaniu podlega wtedy owa "warto¶æ", > która mo¿e byæ dowolnie przenoszona pomiêdzy poszczególnymi obiektami. > > Natomiast obiekty niewarto¶ciowe, jak sama nazwa wskazuje, warto¶ci nie > maj±, wiêc one podlegaj± klonowaniu - tworzy siê nowy obiekt o nowej > to¿samo¶ci. W obiektach warto¶ciowych to¿samo¶ci± jest warto¶æ. Czy mo¿esz podaæ jakie¶ ¼ród³a mówi±ce o typach warto¶ciowych i niewarto¶ciowych? Google na takie pytanie odpowiada wy³±cznie Twoimi postami z usenetu. -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Sat, 03 Mar 2007 14:03
Date: Sat, 03 Mar 2007 14:03
77 lines
4258 bytes
4258 bytes
Dnia Sat, 03 Mar 2007 12:26:28 +0100, Mariusz Lotko skrobie: > Czy mo¿esz podaæ jakie¶ ¼ród³a mówi±ce o typach warto¶ciowych i > niewarto¶ciowych? Google na takie pytanie odpowiada wy³±cznie Twoimi > postami z usenetu. Problem w tym, ¿e wiedza na ten temat jest aktualnie na etapie "odkrywamy, ¿e w jêzyku nagle jest co¶, czego twórca nie wymy¶li³". Natomiast tak dok³adniej sprawa polega na tym, ¿e o istnieniu warto¶ci od d³u¿szego czasu wszyscy wiedzieli, tylko ¿e nie bardzo wiedzieli, jak siê maj± do tego zabraæ. Przyk³adowo, od zawsze wiedziano, ¿e takie 'int' i 'Car' ró¿ni co¶ wiêcej, ni¿ tylko zestaw dozwolonych operacji. Ale w wiêkszo¶ci jêzyków niestety sprowadzono to do specjalnego traktowania liczb ca³kowitych (tak jest w Smalltalku i w Javie), a co za tym idzie, uniemo¿liwiono tworzenie w³asnych typów warto¶ciowych. W Javie po prostu stwierdzono, ¿e wszystkie typy warto¶ciowe to bêd± typy wbudowane (czyli, najpro¶ciej mówi±c, s± to wszystkie rzeczy, których nie tworzy siê przez new) i u¿ytkownik nie mo¿e definiowaæ w³asnych. Tematem siê raczej nikt nie zaj±³ i raczej nikt go nie opracowa³ - wiedzia³bym o tym, bo po takim wa³kowaniu tematu, jakie zorganizowa³em na pl.comp.lang.c, my¶lê ¿e kto¶ dobrze obyty z ogólnie dostêpn± wiedz± nt. informatyki ju¿ by to zg³osi³. Mo¿e nikt nie uwa¿a go za wart uwagi. Co jeszcze ciekawsze, wiêkszo¶æ jêzyków (nie tylko Smalltalk i Java, ale równie¿ wiele funkcjonalnych) ma dziwnie "uniwersalne" podej¶cie do tych obiektów i usi³uje zaciemniæ ten podzia³. W Smalltalku przyk³adowo (a tak¿e np. w OCamlu) masz ka¿dy obiekt zapisany na czterech bajtach. W tych czterech bajtach s± jednak wyznaczone odpowiednie bity, które odró¿niaj± liczbê ca³kowit± od wska¼nika na obiekt. W ten sposób liczba ca³kowita jest takim samym obiektem, jak ka¿dy inny, a fakt, ¿e nie nastêpuje przydzia³ pamiêci przy tworzeniu, jest szczegó³em implementacyjnym. Jednak podzia³ na "warto¶ci" i "obiekty" bierze siê nie z samej konstrukcji jêzyków, tylko z pojêæ u¿ywanych równie¿ w codziennym ¿yciu. Wszystko zale¿y od tego, co oznacza dla nas stwierdzenie "ten sam". Przyk³adowo, je¶li mówimy "ten sam samochód", to chodzi nam o ten sam egzemplarz samochodu, a nie o inny samochód tylko identyczny. Je¶li mówimy "ten sam kolor" albo "ten sam producent" (!) - chodzi o to, ¿e samochód zosta³ pomalowany farb± o tym samym kodzie koloru, a w drugim przypadku, ¿e identyfikator producenta jest identyczny. Identyfikator i kolor nie mog± mieæ egzemplarzy, wiêc to s± warto¶ci. Identyfikator akurat dodatkowo obrazuje nam co¶, co jest odpowiednikiem "referencji", która te¿ jest typem warto¶ciowym. Z podzia³em na typy warto¶ciowe i niewarto¶ciowe wi±¿e siê równie¿ kwestia porównywania, nie tylko kopiowania.Przyk³adowo, porównywanie powinno siê odbywaæ tylko dla typów warto¶ciowych, a to powinno konkretnie stwierdziæ, czy oba obiekty posiadaj± t± sam± warto¶æ. Porównanie obiektów typów niewarto¶ciowych nie ma sensu - albo uznajemy go za obiekt warto¶ciowy (tzn. taki, gdzie kopiowanie z innego czyni go identycznym z tym innym), albo niewarto¶ciowy, wiêc nie ma tu czego porównaæ. Niestety jêzyki próbuj±ce i¶æ w poprzek tego podzia³u dostaj± nadmiernej komplikacji. Nie pamiêtam nawet dok³adnie, jakie jêzyki to maj±, ale jest ich wiele. Chodzi o osobne wrêcz operatory do porównania osobno warto¶ci i to¿samo¶ci - i tu mamy wiele ró¿nych kombinacji, jak <> i != (dla nierównych), czasem jest = i == itd. Musz± byæ wprowadzone, bo sam jêzyk nie rozró¿nia typów obiektowych i warto¶ciowych. Programista zwykle rozró¿nia, nawet bezwiednie, ale i tak teoretycznie da siê zrobiæ tak± g³upotê, jak obiekt warto¶ciowy z w³asn± to¿samo¶ci±. Ale tu ciekawostka - Java np. nie posiada takiego rozró¿nienia i to jest w niej pozytywne. Problem z Jav± jednak le¿y gdzie indziej - jej typ String jest typem obiektowym, a nie warto¶ciowym (podczas gdy String moim zdaniem nale¿y w³a¶nie do typów warto¶ciowych i takim jest np. w C++). -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Marcin 'Qrczak'
Date: Sat, 03 Mar 2007 17:45
Date: Sat, 03 Mar 2007 17:45
25 lines
938 bytes
938 bytes
Dnia 03-03-2007, sob o godzinie 14:03 +0000, Sektor van Skijlen napisał(a): > Ale w większości języków niestety > sprowadzono to do specjalnego traktowania liczb całkowitych (tak jest w > Smalltalku i w Javie), a co za tym idzie, uniemożliwiono tworzenie własnych > typów wartościowych. Nie ma potrzeby ściślejszego wyróżniania typów wartościowych niż danie im odpowiedniej definicja równości. W języku, który nie kopiuje niejawnie obiektów (czyli w większości poza C/C++), jedyne potrzebne wsparcie dla typów wartościowych to definicja standardowej równości dla tych typów uwzględniająca zawartość, a nie tożsamość obiektu. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Sat, 03 Mar 2007 17:46
Date: Sat, 03 Mar 2007 17:46
43 lines
1944 bytes
1944 bytes
Dnia Sat, 03 Mar 2007 17:45:39 +0100, Marcin 'Qrczak' Kowalczyk skrobie: > Dnia 03-03-2007, sob o godzinie 14:03 +0000, Sektor van Skijlen > napisa³(a): > > Ale w wiêkszo¶ci jêzyków niestety > > sprowadzono to do specjalnego traktowania liczb ca³kowitych (tak jest w > > Smalltalku i w Javie), a co za tym idzie, uniemo¿liwiono tworzenie w³asnych > > typów warto¶ciowych. > Nie ma potrzeby ¶ci¶lejszego wyró¿niania typów warto¶ciowych ni¿ > danie im odpowiedniej definicja równo¶ci. W jêzyku, który nie kopiuje > niejawnie obiektów (czyli w wiêkszo¶ci poza C/C++), jedyne potrzebne > wsparcie dla typów warto¶ciowych to definicja standardowej równo¶ci > dla tych typów uwzglêdniaj±ca zawarto¶æ, a nie to¿samo¶æ obiektu. Mo¿liwe, ale by³bym za tym, ¿eby po prostu okre¶laæ, czy porównanie ma porównywaæ WARTO¦Æ, czy TO¯SAMO¦Æ. Tyle, my¶lê, by wystarczy³o. Chodzi jednak o to, ¿eby w jêzyku by³a mo¿liwa do opisania konstrukcja typu: String s; ... s += "\n"; Ja wiem, ¿e Javowy string to wszystko ma (przyda³oby mu siê tylko, ¿eby operator porównania te¿ porównywa³ po warto¶ci), ale co mnie to obchodzi - String jest w Javie dok³adnie tak samo typem wbudowanym, jak int. Jako wsparcie dla typów warto¶ciowych, takie pe³ne, wyobra¿a³bym sobie: - mo¿liwo¶æ okre¶lenia, jak wykonuje siê porównanie warto¶ci (i opisaæ to jako standardowe porównanie dla tego typu) - mo¿liwo¶æ okre¶lenia, co ma siê dziaæ z obiektem, który chcemy zmodyfikowaæ w miejscu za po¶rednictwem takiego uchwytu, jaki akurat jest dostêpny w jêzyku (w Javie tym uchwytem jest referencja, wiêc i tak musi siê wtedy odbyæ wyprodukowanie nowego obiektu i zgubienie starego) -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Sun, 04 Mar 2007 00:56
Date: Sun, 04 Mar 2007 00:56
29 lines
1134 bytes
1134 bytes
Sektor van Skijlen wrote: > Dnia Sat, 03 Mar 2007 17:45:39 +0100, Marcin 'Qrczak' Kowalczyk skrobie: >> Dnia 03-03-2007, sob o godzinie 14:03 +0000, Sektor van Skijlen >> napisa³(a): > >> > Ale w wiêkszo¶ci jêzyków niestety >> > sprowadzono to do specjalnego traktowania liczb ca³kowitych (tak jest w >> > Smalltalku i w Javie), a co za tym idzie, uniemo¿liwiono tworzenie >> > w³asnych typów warto¶ciowych. > >> Nie ma potrzeby ¶ci¶lejszego wyró¿niania typów warto¶ciowych ni¿ >> danie im odpowiedniej definicja równo¶ci. W jêzyku, który nie kopiuje >> niejawnie obiektów (czyli w wiêkszo¶ci poza C/C++), jedyne potrzebne >> wsparcie dla typów warto¶ciowych to definicja standardowej równo¶ci >> dla tych typów uwzglêdniaj±ca zawarto¶æ, a nie to¿samo¶æ obiektu. > > Mo¿liwe, ale by³bym za tym, ¿eby po prostu okre¶laæ, czy porównanie ma > porównywaæ WARTO¦Æ, czy TO¯SAMO¦Æ. Tyle, my¶lê, by wystarczy³o. Python rozró¿nia to¿samo¶æ z warto¶ci± tzn. s± porównania 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? -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Sun, 04 Mar 2007 14:50
Date: Sun, 04 Mar 2007 14:50
36 lines
1659 bytes
1659 bytes
Dnia Sun, 04 Mar 2007 00:56:21 +0100, Mariusz Lotko skrobie: > Sektor van Skijlen wrote: > > Dnia Sat, 03 Mar 2007 17:45:39 +0100, Marcin 'Qrczak' Kowalczyk skrobie: > >> Dnia 03-03-2007, sob o godzinie 14:03 +0000, Sektor van Skijlen > >> napisa³(a): > > > >> > Ale w wiêkszo¶ci jêzyków niestety > >> > sprowadzono to do specjalnego traktowania liczb ca³kowitych (tak jest w > >> > Smalltalku i w Javie), a co za tym idzie, uniemo¿liwiono tworzenie > >> > w³asnych typów warto¶ciowych. > > > >> Nie ma potrzeby ¶ci¶lejszego wyró¿niania typów warto¶ciowych ni¿ > >> danie im odpowiedniej definicja równo¶ci. W jêzyku, który nie kopiuje > >> niejawnie obiektów (czyli w wiêkszo¶ci poza C/C++), jedyne potrzebne > >> wsparcie dla typów warto¶ciowych to definicja standardowej równo¶ci > >> dla tych typów uwzglêdniaj±ca zawarto¶æ, a nie to¿samo¶æ obiektu. > > > > Mo¿liwe, ale by³bym za tym, ¿eby po prostu okre¶laæ, czy porównanie ma > > porównywaæ WARTO¦Æ, czy TO¯SAMO¦Æ. Tyle, my¶lê, by wystarczy³o. > Python rozró¿nia to¿samo¶æ z warto¶ci± tzn. s± porównania > 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¶æ. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: "Adam Karpierz"
Date: Sun, 04 Mar 2007 17:30
Date: Sun, 04 Mar 2007 17:30
37 lines
1236 bytes
1236 bytes
"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¶æ. Czyli chodzi ci ogolnie o to, aby cos bylo sp...dzielone Jesli do porownania wartosci jak i tozsamosci istnieje w danym jezyku ten sam operator to taki jezyk mozna sobie usnac za syf, a nie jezyk Podobnie z operatorem przypisania Jelsi do skopowiania obiektu uzywa sie tego samego operatora co do przypisania referencji to jest to rowniez syf. Wiec jest doklandie odwrotnie niz piszesz: Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania wartosci a inny do porownania tozsamosci obiektow Podobnie chodzi o to aby byl dostepny inny operator do 'clone' obiektu a inny do zmiany referencji Porzadne jezyki tak maja (mialy nawet w latach 60-tych), a jesli np ten syf zwany C++ tego nie ma to nazwij to zwyczajnie syfem. i przejdz nad tym do porzadku dziennego, a nie probuj robic z tego syfu kamieni szlachetnych. AK
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Marcin 'Qrczak'
Date: Sun, 04 Mar 2007 17:46
Date: Sun, 04 Mar 2007 17:46
35 lines
1421 bytes
1421 bytes
Dnia 04-03-2007, nie o godzinie 14:50 +0000, Sektor van Skijlen napisał(a): > > 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ść. To się sprawdza, ale tylko w językach, w których podstawowe wartości są realizowane przez obiekty immutable. Jeśli tak nie jest, czyli kiedy typ, który powinien być typem wartościowym, jest realizowany jako obiekt ze stanem, czyli kiedy ten obiekt ze stanem tak naprawdę modeluje zmienną tego typu, a nie wartość tego typu, to mamy konflikt: równość zmiennych powinna porównywać zmienne jako takie, ale częściej chcemy porównywać bieżące wartości tych zmiennych i to zazwyczaj robi operator ==. Czyli po pierwsze działa niezgodnie z ogólnymi wytycznymi, a po drugie porównanie zmiennych w razie czego też powinno być dostępne. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Sun, 04 Mar 2007 19:37
Date: Sun, 04 Mar 2007 19:37
89 lines
3103 bytes
3103 bytes
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. Operator == dla dwóch obiektów powinien _zawsze_ porównywaæ równo¶æ semantyczn± ich _zawarto¶ci_, a nie kombinowaæ z ich to¿samo¶ci±. Nie widzê szczególnego powodu, ¿eby wska¼niki nazywaæ "obiektami niewarto¶ciowymi", skoro pe³ni± one funkcjê referencji, czy jak kto woli, identyfikatora obiektu. 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. > Czyli chodzi ci ogolnie o to, aby cos bylo sp...dzielone Wszystko mo¿na zepsuæ, je¶li siê tylko za mocno kombinuje nie zwa¿aj±c na intencje twórcy (tu: twórcy C++). > Jesli do porownania wartosci jak i tozsamosci istnieje > w danym jezyku ten sam operator to taki jezyk mozna sobie > usnac za syf, a nie jezyk Operator ten sam, pytanie na czym go u¿yjesz (na obiektach, czy na identyfikatorach obiektów, za które w C++ mo¿na uznaæ wska¼niki). > Podobnie z operatorem przypisania > Jelsi do skopowiania obiektu uzywa sie tego samego > operatora co do przypisania referencji to jest to rowniez syf. j.w. > Wiec jest doklandie odwrotnie niz piszesz: > > Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania > wartosci a inny do porownania tozsamosci obiektow Tak by by³o rzeczywi¶cie najlepiej. Ale uwa¿am, ¿e operator == jest i tak lepszy w C++ ni¿ w Javie. Bo niby dlaczego logiczna równo¶æ mia³aby dotyczyæ wy³±cznie relacji bycia tym samym obiektem? Idealnie jest to w Pythonie: operator == jak w C++ i operator "is" jak w Javie. > 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++... > > Porzadne jezyki tak maja (mialy nawet w latach 60-tych), > a jesli np ten syf zwany C++ tego nie ma to nazwij to zwyczajnie syfem. > i przejdz nad tym do porzadku dziennego, a nie probuj robic > z tego syfu kamieni szlachetnych. Jako fan C++ nie zgadzam siê co do syfu, ale zgadzam siê, ¿e dorabianie teorii tu, gdzie jej nie ma i nie bêdzie, nie czyni niczego lepszym. -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: "Adam Karpierz"
Date: Sun, 04 Mar 2007 20:52
Date: Sun, 04 Mar 2007 20:52
12 lines
289 bytes
289 bytes
"Mariusz Lotko" <imie.nazwisko@wp.pl> wrote: > Adam Karpierz wrote: >>> 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¶æ. Prosze mi nie przypisywac slow Sekatora :) AK
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Sun, 04 Mar 2007 21:09
Date: Sun, 04 Mar 2007 21:09
51 lines
2689 bytes
2689 bytes
Dnia Sun, 04 Mar 2007 17:46:12 +0100, Marcin 'Qrczak' Kowalczyk skrobie: > Dnia 04-03-2007, nie o godzinie 14:50 +0000, Sektor van Skijlen > napisa³(a): > > > 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¶æ. > To siê sprawdza, ale tylko w jêzykach, w których podstawowe warto¶ci s± > realizowane przez obiekty immutable. Je¶li tak nie jest, czyli kiedy > typ, który powinien byæ typem warto¶ciowym, jest realizowany jako obiekt > ze stanem, czyli kiedy ten obiekt ze stanem tak naprawdê modeluje > zmienn± tego typu, a nie warto¶æ tego typu, to mamy konflikt: równo¶æ > zmiennych powinna porównywaæ zmienne jako takie, ale czê¶ciej chcemy > porównywaæ bie¿±ce warto¶ci tych zmiennych i to zazwyczaj robi operator > ==. Czyli po pierwsze dzia³a niezgodnie z ogólnymi wytycznymi, a po > drugie porównanie zmiennych w razie czego te¿ powinno byæ dostêpne. Ha! W razie czego! No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako warto¶ciowy, to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas interesowaæ w ogóle. Je¶li jest to potrzebne do jakich¶ wewnêtrznych operacji, to powinno byæ dostêpne w inny sposób, jakim¶ specjalnym interfejsem, dostêpnym tylko wewn±trz implementacji. U¿ytkownik powinien dostaæ do tego standardowe API, z operatorem porównania porównuj±cym warto¶ci. Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów jak int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie przekazywania (const T&), albo przekazuje siê do zmodyfikowania (T&, T*). Czy widzia³e¶ kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby kto¶ porównywa³ dwa wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik do int jest u¿ywany jako iterator do tablicy int-ów - czyli zastosowanie jest inne, ni¿ warto¶æ referencji)? Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty mog± sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz, dyskutowali¶my o tym - warto¶ci mog± byæ symulowane przez predefiniowane unikalne obiekty i w takim przypadku porównanie to¿samo¶ci takich obiektów jest równowa¿ne porównaniu warto¶ci, choæ to ju¿ jest szczegó³ implementacyjny. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Sun, 04 Mar 2007 21:21
Date: Sun, 04 Mar 2007 21:21
86 lines
3110 bytes
3110 bytes
Dnia Sun, 4 Mar 2007 17:30:21 +0100, Adam Karpierz skrobie: > "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?æ. > Czyli chodzi ci ogolnie o to, aby cos bylo sp...dzielone Nie. Chodzi o to, ¿eby nie by³o zjebane. > Jesli do porownania wartosci jak i tozsamosci istnieje > w danym jezyku ten sam operator to taki jezyk mozna sobie > usnac za syf, a nie jezyk Ok, o gustach mo¿esz sobie podyskutowaæ, je¶li lubisz, ja oczywi¶cie bêdê móg³ o tym równie¿ porozmawiaæ, je¶li masz na ten temat do powiedzenia cokolwiek wiêcej, ni¿ "syf, a nie jêzyk". Aha, plus wszelkie "ile to ja mam lat do¶wiadczenia". Przypomnê na marginesie, ¿e tak maj± to w³a¶nie zrobione wszystkie jêzyki "mainstreamowe". Aha, Perl równie¿, chocia¿ wola³bym siê nim raczej podcieraæ, ni¿ podpieraæ. > Podobnie z operatorem przypisania Nie pisa³em nic o operatorze przypisania. > Jelsi do skopowiania obiektu uzywa sie tego samego > operatora co do przypisania referencji to jest to rowniez syf. Problem polega na tym, ¿e operator przypisania powinien byæ dostêpny i tak tylko dla typów warto¶ciowych. Przy czym typem warto¶ciowym jest równie¿ referencja (wska¼nik w przypadku C++). > Wiec jest doklandie odwrotnie niz piszesz: > Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania > wartosci a inny do porownania tozsamosci obiektow No, dobrze, w ostateczno¶ci siê zgodzê, ¿e tak to ma byæ. Pod jednym wszak¿e warunkiem. ¯e dla ka¿dego typu jest dostêpny wy³±cznie albo jeden albo drugi. W sumie na jedno wychodzi - reszta to kwestia sk³adni. > Podobnie chodzi o to aby byl dostepny inny operator do > 'clone' obiektu a inny do zmiany referencji Mo¿e i tak byæ - w³±cznie z powy¿szym zastrze¿eniem. Fakt, to nie jest dobre, ¿eby stosowaæ operator przypisania do typów niewarto¶ciowych. Powinno siê stosowaæ inne metody, tak dla rozró¿nienia. > Porzadne jezyki tak maja (mialy nawet w latach 60-tych), Te tzw. "porz±dne jêzyki" udostêpnia³y wszystko dla wszystkich, przy czym sam musia³e¶ pamiêtaæ, co jest czym dla ciebie. Dziêkujê bardzo. Gdybym nie potrzebowa³ odpowiedniego wspomagania decyzji i uwagi, to pisa³bym w asemblerze. > a jesli np ten syf zwany C++ tego nie ma C++ akurat ma (Tcl te¿). > to nazwij to zwyczajnie syfem. Tak, i Javê, i C#, i Perla. Z najwiêksz± przyjemno¶ci± ;) > i przejdz nad tym do porzadku dziennego, a nie probuj robic > z tego syfu kamieni szlachetnych. Nie jestem chemikiem i nie znam siê na kamieniach szlachetnych. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Sun, 04 Mar 2007 22:09
Date: Sun, 04 Mar 2007 22:09
204 lines
8508 bytes
8508 bytes
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". 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¦Æ). Po drugie, nie ma akurat kombinowania z to¿samo¶ci± - je¶li mamy np. (no, we¼my teraz Javê dla odmiany) dwie zmienne referencyjne, to ich porównanie nie porównuje tych zmiennych referencyjnych, tylko ich warto¶ci, a w efekcie porównuje siê to¿samo¶ci obiektów. > Nie widzê szczególnego powodu, ¿eby wska¼niki nazywaæ "obiektami > niewarto¶ciowymi", skoro pe³ni± one funkcjê referencji, czy jak > kto woli, identyfikatora obiektu. Ale¿ wska¼niki s± jak najbardziej typami warto¶ciowymi, tylko i wy³±cznie! Tylko obiekty, które s± przez te wska¼niki wskazywane, ju¿ niekoniecznie. W szczególno¶ci, w idealnym projekcie powinno byæ tak, ¿eby wska¼nik nie by³ potrzebny do czegokolwiek poza przyczynami czysto jêzykowymi (czyli, inaczej, ¿eby warto¶æ tego wska¼nika w ogóle nikogo nie musia³a interesowaæ). > 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. 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 Javie zreszt± jest to urz±dzone niemal idealnie pod tym wzglêdem, tylko z drobnymi zastrze¿eniami: - Java nie pozwala na definiowanie w³asnych typów warto¶ciowych - Nie wprowadzono mechanizmu tupli, które mog³yby zast±piæ niemo¿liwo¶æ przekazania do metody zmiennej przez referencjê > > Jesli do porownania wartosci jak i tozsamosci istnieje > > w danym jezyku ten sam operator to taki jezyk mozna sobie > > usnac za syf, a nie jezyk > Operator ten sam, pytanie na czym go u¿yjesz (na obiektach, czy na > identyfikatorach obiektów, za które w C++ mo¿na uznaæ wska¼niki). Problem w tym, ¿e rozró¿nienie typów jest wystarczaj±ce je¶li u¿ywamy osobnej sk³adni do okre¶lenia warto¶ci i osobnej sk³adni do oker¶lenia referencji. Tak ma C++, pomijaj±c przypadek, gdy jawnie u¿ywamy referencji. Tak ma te¿ Tcl - sama nazwa jest zawsze wy³±cznie referencj±, dopiero poprzedzenie jej '$' oznacza warto¶æ. W efekcie np. jak zrobisz: proc compare {a b} { return $a == $b } to potem wszystko zale¿y od tego, czy napiszesz [compare x y] czy [compare $x $y] > > Wiec jest doklandie odwrotnie niz piszesz: > > > > Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania > > wartosci a inny do porownania tozsamosci obiektow > Tak by by³o rzeczywi¶cie najlepiej. Ale uwa¿am, ¿e operator == jest > i tak lepszy w C++ ni¿ w Javie. Bo niby dlaczego logiczna równo¶æ > mia³aby dotyczyæ wy³±cznie relacji bycia tym samym obiektem? > Idealnie jest to w Pythonie: operator == jak w C++ i operator "is" > jak w Javie. Tak, tylko ¿e je¶li "wierzymy w podzia³ na obiekty warto¶ciowe i niewarto¶ciowe" (czytaj: mamy oczy tam gdzie trzeba), to relacja 'is' w obiektach warto¶ciowych jest nam zbêdna, a '==' w obiektach niewarto¶ciowych równie¿ nie ma sensu. 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. Drugie z kolei nie ma sensu dlatego, ¿e porównania obiektów, je¶li ju¿ istniej±, to zazwyczaj maj± zupe³nie inny wymiar. Je¶li ju¿ co¶ porównujemy, to porównujemy stany, najczê¶ciej okre¶lone stany cz±stkowe. Np. mo¿emy porównywaæ samochody pod wzglêdem tego, czy s± tego samego koloru, albo tej samej marki, a tak¿e, czy jeden ma lepszego kopa od drugiego. Ale nie bardzo mo¿emy "porównaæ dwa samochody", no bo jak? Nawet w przypadku porz±dkowania obiektów, mamy do czynienia z okre¶laniem odpowiedniego kryterium porz±dkowania. Kryterium mo¿e byæ okre¶lone nawet wielopoziomowo (np. uszeregowaæ samochody wg marki, a jak s± tej samej marki to wg mocy silnika, a jak s± nadal te same, to wg koloru itd.). 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. 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). A to siê bierze st±d, ¿e to¿samo¶æ obiektu decyduje nam o widoczno¶ci zmian. Je¶li bowiem mamy dwa wska¼niki (a i b) wskazuj±ce na jeden obiekt, to wtedy po a->x = 10 mo¿emy byæ pewni, ¿e b->x == 10. Dlatego te¿ porównania warto¶ci okre¶lonych stanów cz±stkowych obiektów (nawet je¶li obiekt ma tylko jeden taki stan) odbywaj± siê tylko w ten sposób: 1. Porównanie warto¶ci stanu z jak±¶ predefiniowan± sta³± 2. Sprawdzenie, czy warto¶ci stanu z dwóch ró¿nych obiektów maj± tak± sam± warto¶æ - ale równie¿ równ± tak¿e jakiej¶ predefiniowanej sta³êj 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? > > 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. BTW. akurat siê zastanawiam nad tym, czy w Ginle dopu¶ciæ tak± mo¿liwo¶æ. Oczywi¶cie tworzenie na stosie nie wchodzi w rachubê tak czy siak, ale chcia³bym nie zabraniaæ mo¿liwo¶ci tworzenia pod-obiektów jako pól. Czyli ¿eby obiekty tych samych typów mog³y byæ tworzone dynamicznie, a jednocze¶nie ¿eby te¿ mog³y byæ polami. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Mon, 05 Mar 2007 07:07
Date: Mon, 05 Mar 2007 07:07
209 lines
8341 bytes
8341 bytes
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ê? > > 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? > Po drugie, nie ma akurat kombinowania z to¿samo¶ci± - je¶li mamy np. (no, > we¼my teraz Javê dla odmiany) dwie zmienne referencyjne, to ich porównanie > nie porównuje tych zmiennych referencyjnych, tylko ich warto¶ci, a w > efekcie porównuje siê to¿samo¶ci obiektów. Zgoda, z tym, ¿e ja pisa³em o C++. > >> Nie widzê szczególnego powodu, ¿eby wska¼niki nazywaæ "obiektami >> niewarto¶ciowymi", skoro pe³ni± one funkcjê referencji, czy jak >> kto woli, identyfikatora obiektu. > > Ale¿ wska¼niki s± jak najbardziej typami warto¶ciowymi, tylko i wy³±cznie! > > Tylko obiekty, które s± przez te wska¼niki wskazywane, ju¿ niekoniecznie. > W szczególno¶ci, w idealnym projekcie powinno byæ tak, ¿eby wska¼nik nie > by³ potrzebny do czegokolwiek poza przyczynami czysto jêzykowymi (czyli, > inaczej, ¿eby warto¶æ tego wska¼nika w ogóle nikogo nie musia³a > interesowaæ). > >> 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? > 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. > W Javie zreszt± jest to urz±dzone niemal idealnie pod tym wzglêdem, tylko > z drobnymi zastrze¿eniami: > > - Java nie pozwala na definiowanie w³asnych typów warto¶ciowych > - Nie wprowadzono mechanizmu tupli, które mog³yby zast±piæ niemo¿liwo¶æ > przekazania do metody zmiennej przez referencjê Od roku programujê w Javie, jako¶ nieszczególnie mi to przeszkadza. >> > Wiec jest doklandie odwrotnie niz piszesz: >> > >> > Chodzi o to, ¿e maja byæ dostêpny inny oparator do porownania >> > wartosci a inny do porownania tozsamosci obiektow > >> Tak by by³o rzeczywi¶cie najlepiej. Ale uwa¿am, ¿e operator == jest >> i tak lepszy w C++ ni¿ w Javie. Bo niby dlaczego logiczna równo¶æ >> mia³aby dotyczyæ wy³±cznie relacji bycia tym samym obiektem? >> Idealnie jest to w Pythonie: operator == jak w C++ i operator "is" >> jak w Javie. > > Tak, tylko ¿e je¶li "wierzymy w podzia³ na obiekty warto¶ciowe i > niewarto¶ciowe" (czytaj: mamy oczy tam gdzie trzeba), to relacja 'is' w > obiektach warto¶ciowych jest nam zbêdna, a '==' w obiektach > niewarto¶ciowych równie¿ nie ma sensu. > > 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æ. > Drugie z kolei nie ma sensu dlatego, ¿e porównania obiektów, je¶li ju¿ > istniej±, to zazwyczaj maj± zupe³nie inny wymiar. Je¶li ju¿ co¶ > porównujemy, to porównujemy stany, najczê¶ciej okre¶lone stany cz±stkowe. > Np. mo¿emy porównywaæ samochody pod wzglêdem tego, czy s± tego samego > koloru, albo tej samej marki, a tak¿e, czy jeden ma lepszego kopa od > drugiego. Ale nie bardzo mo¿emy "porównaæ dwa samochody", no bo jak? > > Nawet w przypadku porz±dkowania obiektów, mamy do czynienia z okre¶laniem > odpowiedniego kryterium porz±dkowania. Kryterium mo¿e byæ okre¶lone nawet > wielopoziomowo (np. uszeregowaæ samochody wg marki, a jak s± tej samej > marki to wg mocy silnika, a jak s± nadal te same, to wg koloru itd.). > > 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. Mimo to nie odwa¿y³bym siê na takie wyra¼ne i jednoznaczne nazwanie pierwszych obiektów warto¶ciowymi a drugich niewarto¶ciowymi. > > 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. > 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. Dziwiê siê Twoj± opini±, bo sprawiasz wra¿enie cz³owieka, który ma do¶wiadczenie zawodowe i trochê linii kodu wyprodukowa³. > >> > 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... :-) -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Mon, 05 Mar 2007 07:07
Date: Mon, 05 Mar 2007 07:07
73 lines
3428 bytes
3428 bytes
Sektor van Skijlen wrote: > Dnia Sun, 04 Mar 2007 17:46:12 +0100, Marcin 'Qrczak' Kowalczyk skrobie: >> Dnia 04-03-2007, nie o godzinie 14:50 +0000, Sektor van Skijlen >> napisa³(a): > >> > > 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¶æ. > >> To siê sprawdza, ale tylko w jêzykach, w których podstawowe warto¶ci s± >> realizowane przez obiekty immutable. Je¶li tak nie jest, czyli kiedy >> typ, który powinien byæ typem warto¶ciowym, jest realizowany jako obiekt >> ze stanem, czyli kiedy ten obiekt ze stanem tak naprawdê modeluje >> zmienn± tego typu, a nie warto¶æ tego typu, to mamy konflikt: równo¶æ >> zmiennych powinna porównywaæ zmienne jako takie, ale czê¶ciej chcemy >> porównywaæ bie¿±ce warto¶ci tych zmiennych i to zazwyczaj robi operator >> ==. Czyli po pierwsze dzia³a niezgodnie z ogólnymi wytycznymi, a po >> drugie porównanie zmiennych w razie czego te¿ powinno byæ dostêpne. > > Ha! W razie czego! > > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako warto¶ciowy, > to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas interesowaæ w > ogóle. A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu to¿samo¶ci obiektu w pierszej linijce operatora == uwa¿asz za b³êdny? Podobnie w operatorze =, w którym zapobiega to przypisania obiektu samemu sobie? > Je¶li jest to potrzebne do jakich¶ wewnêtrznych operacji, to powinno byæ > dostêpne w inny sposób, jakim¶ specjalnym interfejsem, dostêpnym tylko > wewn±trz implementacji. U¿ytkownik powinien dostaæ do tego standardowe > API, z operatorem porównania porównuj±cym warto¶ci. > > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów jak > int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie > przekazywania (const T&), albo przekazuje siê do zmodyfikowania (T&, T*). > Czy widzia³e¶ kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby kto¶ > porównywa³ dwa wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik do int > jest u¿ywany jako iterator do tablicy int-ów - czyli zastosowanie jest > inne, ni¿ warto¶æ referencji)? Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê robiæ specjalne implementacje dla typów prostych. > Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty mog± > sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz, > dyskutowali¶my o tym - warto¶ci mog± byæ symulowane przez predefiniowane > unikalne obiekty i w takim przypadku porównanie to¿samo¶ci takich obiektów > jest równowa¿ne porównaniu warto¶ci, choæ to ju¿ jest szczegó³ > implementacyjny. Nie zgadzam siê. Ka¿dy obiekt jest uproszczeniem rzeczywisto¶ci, a co za tym idzie z du¿ym prawdopodobieñstwem mog± pojawiæ siê obiekty o tych samych warto¶ciach, które nie s± tymi samymi obiektami. To, ¿e mam kolor oczu jak Brad Pitt nie czyni mnie Bradem Pitem o czym za¶wiadczy ka¿dy stosowny operator porównania - tu: kobieta ;-) A powa¿nie: trzymajmy siê terminologii, która by³a, jest i sprawdza siê: obiekt (zestaw warto¶ci) i identyfikator obiektu (to¿samo¶æ). Nie twórzmy nowych teorii na temat abstrakcji, która ju¿ zosta³a odpowiednio steoretyzowna. -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Mon, 05 Mar 2007 07:09
Date: Mon, 05 Mar 2007 07:09
17 lines
426 bytes
426 bytes
Adam Karpierz wrote: > "Mariusz Lotko" <imie.nazwisko@wp.pl> wrote: >> Adam Karpierz wrote: > >>>> 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¶æ. > > Prosze mi nie przypisywac slow Sekatora :) Przepraszam, my¶la³em, ¿e g³êboko¶æ cytowania jest ju¿ wystarczaj±cym rozró¿nikiem :-) -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Mon, 05 Mar 2007 21:28
Date: Mon, 05 Mar 2007 21:28
228 lines
9099 bytes
9099 bytes
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. > > 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; }; > > Po drugie, nie ma akurat kombinowania z to¿samo¶ci± - je¶li mamy np. (no, > > we¼my teraz Javê dla odmiany) dwie zmienne referencyjne, to ich porównanie > > nie porównuje tych zmiennych referencyjnych, tylko ich warto¶ci, a w > > efekcie porównuje siê to¿samo¶ci obiektów. > Zgoda, z tym, ¿e ja pisa³em o C++. Ale¿ w C++ masz to samo, tylko na wska¼nikach. > >> 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? 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æ. W C++ string jest typem warto¶ciowym i spe³nia wszystkie warunki dotycz±ce typu warto¶ciowego. > > 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. > > Drugie z kolei nie ma sensu dlatego, ¿e porównania obiektów, je¶li ju¿ > > istniej±, to zazwyczaj maj± zupe³nie inny wymiar. Je¶li ju¿ co¶ > > porównujemy, to porównujemy stany, najczê¶ciej okre¶lone stany cz±stkowe. > > Np. mo¿emy porównywaæ samochody pod wzglêdem tego, czy s± tego samego > > koloru, albo tej samej marki, a tak¿e, czy jeden ma lepszego kopa od > > drugiego. Ale nie bardzo mo¿emy "porównaæ dwa samochody", no bo jak? > > > > Nawet w przypadku porz±dkowania obiektów, mamy do czynienia z okre¶laniem > > odpowiedniego kryterium porz±dkowania. Kryterium mo¿e byæ okre¶lone nawet > > wielopoziomowo (np. uszeregowaæ samochody wg marki, a jak s± tej samej > > marki to wg mocy silnika, a jak s± nadal te same, to wg koloru itd.). > > > > 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? > > 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. > > 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ê :) > 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. > >> > 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 ;) -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Mon, 05 Mar 2007 21:38
Date: Mon, 05 Mar 2007 21:38
85 lines
3641 bytes
3641 bytes
Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie: > > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako warto¶ciowy, > > to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas interesowaæ w > > ogóle. > A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu to¿samo¶ci > obiektu w pierszej linijce operatora == uwa¿asz za b³êdny? Tak. > Podobnie w operatorze =, w którym zapobiega to przypisania obiektu > samemu sobie? Tu ju¿ nie, ale to jest zwi±zane z tzw. kwesti± jêzykow±. W przypadku C++ jest to konieczne, je¿eli obiekt podawany jako argument operatora = jest przekazywany przez referencjê. Nie by³oby natomiast tego problemu w przypadku, gdyby ten obiekt by³ tam przekazywany przez warto¶æ. Gdyby hipotetycznie w Javie by³a mo¿liwo¶æ zrobienia czego¶ podobnego, to tam te¿ nie ma konieczno¶ci dodawania takiego sprawdzenia: class K { private String s; public void copyFrom( K x ) { s = x.s; } ... } Wywo³anie K.copyFrom( this ) nie spowoduje b³êdu w tym przypadku. > > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów jak > > int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie > > przekazywania (const T&), albo przekazuje siê do zmodyfikowania (T&, T*). > > Czy widzia³e¶ kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby kto¶ > > porównywa³ dwa wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik do int > > jest u¿ywany jako iterator do tablicy int-ów - czyli zastosowanie jest > > inne, ni¿ warto¶æ referencji)? > Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê > robiæ specjalne implementacje dla typów prostych. Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam typ parametryczny T traktuje siê prawdopodobnie zawsze jak typ obiektowy, wiêc sprawa konkretyzacji na int nie ma i tak znaczenia. Ale je¶li jest traktowany jako typ obiektowy, a nie warto¶ciowy, to równie¿ istnieje przekazywanie przez referencjê, czy nieu¿ywanie operatora == (bo nie wiadomo, czy zdefiniowany) itd. - czyli typu T nie uwa¿a siê za warto¶ciowy. > > Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty mog± > > sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz, > > dyskutowali¶my o tym - warto¶ci mog± byæ symulowane przez predefiniowane > > unikalne obiekty i w takim przypadku porównanie to¿samo¶ci takich obiektów > > jest równowa¿ne porównaniu warto¶ci, choæ to ju¿ jest szczegó³ > > implementacyjny. > Nie zgadzam siê. Ka¿dy obiekt jest uproszczeniem rzeczywisto¶ci, a co za tym > idzie z du¿ym prawdopodobieñstwem mog± pojawiæ siê obiekty o tych samych > warto¶ciach, które nie s± tymi samymi obiektami. Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ. > To, ¿e mam kolor oczu jak Brad Pitt nie czyni mnie Bradem > Pitem o czym za¶wiadczy ka¿dy stosowny operator porównania - tu: kobieta ;-) Ale kolor oczu nie stanowi o warto¶ci cz³owieka, o czym równie¿ mo¿e za¶wiadczyæ wspomniany operator porównania ;) > A powa¿nie: trzymajmy siê terminologii, która by³a, jest i sprawdza siê: > obiekt (zestaw warto¶ci) i identyfikator obiektu (to¿samo¶æ). Nie twórzmy > nowych teorii na temat abstrakcji, która ju¿ zosta³a odpowiednio > steoretyzowna. Ja nie tworzê ¿adnych nowych teorii - ja tylko obserwujê rzeczywisto¶æ. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Mon, 05 Mar 2007 23:58
Date: Mon, 05 Mar 2007 23:58
86 lines
3711 bytes
3711 bytes
Sektor van Skijlen wrote: > Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie: >> > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako >> > warto¶ciowy, to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas >> > interesowaæ w ogóle. > >> A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu to¿samo¶ci >> obiektu w pierszej linijce operatora == uwa¿asz za b³êdny? > > Tak. Wybacz, ale powy¿szym stwierdzeniem sk³aniasz mnie do stwierdzenia u Ciebie paranoi... Przecie¿ stosowanie tego jest oczywiste. Po co mam sprawdzaæ, czy mam tyle samo pieniêdzy w swoim portfelu co... w swoim? > >> Podobnie w operatorze =, w którym zapobiega to przypisania obiektu >> samemu sobie? > > Tu ju¿ nie, ale to jest zwi±zane z tzw. kwesti± jêzykow±. W przypadku C++ > jest to konieczne, je¿eli obiekt podawany jako argument operatora = jest > przekazywany przez referencjê. > > Nie by³oby natomiast tego problemu w przypadku, gdyby ten obiekt by³ tam > przekazywany przez warto¶æ. > > Gdyby hipotetycznie w Javie by³a mo¿liwo¶æ zrobienia czego¶ podobnego, to > tam te¿ nie ma konieczno¶ci dodawania takiego sprawdzenia: Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same" a wiêc na pewno "takie same" obiekty. >> > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów >> > jak int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie >> > przekazywania (const T&), albo przekazuje siê do zmodyfikowania (T&, >> > T*). Czy widzia³e¶ kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby >> > kto¶ porównywa³ dwa wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik >> > do int jest u¿ywany jako iterator do tablicy int-ów - czyli >> > zastosowanie jest inne, ni¿ warto¶æ referencji)? > >> Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê >> robiæ specjalne implementacje dla typów prostych. > > Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam typ > parametryczny T traktuje siê prawdopodobnie zawsze jak typ obiektowy, wiêc > sprawa konkretyzacji na int nie ma i tak znaczenia. "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku szablonów, które wed³ug mojej praktyki z regu³y s± po prostu przeznaczone dla obiektów oferuj±cych okre¶lony interfejs. I innych ograniczeñ w ich u¿yciu w³a¶ciwie nie ma. > Ale je¶li jest traktowany jako typ obiektowy, a nie warto¶ciowy, to > równie¿ istnieje przekazywanie przez referencjê, czy nieu¿ywanie operatora > == (bo nie wiadomo, czy zdefiniowany) itd. - czyli typu T nie uwa¿a siê za > warto¶ciowy. Takich za³o¿eñ raczej te¿ siê nie podejmuje w C++. Je¶li co¶ nie jest zdefiniowane, to poinformuje nas o tym kompilator w czasie konkretyzacji szablonu. >> > Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty >> > mog± sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz, >> > dyskutowali¶my o tym - warto¶ci mog± byæ symulowane przez >> > predefiniowane unikalne obiekty i w takim przypadku porównanie >> > to¿samo¶ci takich obiektów jest równowa¿ne porównaniu warto¶ci, choæ to >> > ju¿ jest szczegó³ implementacyjny. > >> Nie zgadzam siê. Ka¿dy obiekt jest uproszczeniem rzeczywisto¶ci, a co za >> tym idzie z du¿ym prawdopodobieñstwem mog± pojawiæ siê obiekty o tych >> samych warto¶ciach, które nie s± tymi samymi obiektami. > > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ. Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo. Nie chcia³bym mieæ konta w banku, który ma k³opot z odró¿nieniem warto¶ci mojego konta od jego to¿samo¶ci. -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: 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
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Marcin 'Qrczak'
Date: Tue, 06 Mar 2007 00:36
Date: Tue, 06 Mar 2007 00:36
84 lines
3583 bytes
3583 bytes
Dnia 04-03-2007, nie o godzinie 22:09 +0000, Sektor van Skijlen napisał(a): > Tak, tylko że jeśli "wierzymy w podział na obiekty wartościowe i > niewartościowe" (czytaj: mamy oczy tam gdzie trzeba), to relacja 'is' w > obiektach wartościowych jest nam zbędna, a '==' w obiektach niewartościowych > również nie ma sensu. Ten idealistyczny obraz, teoretycznie słuszny, sprawia pewne trudności w językach, w których wiele podstawowych typów jest zmienialnych. (Wyjątkowo nie dotyczy to C++, które pracuje w innym paradygmacie: powszechnie niejawnie kopiuje obiekty, przez co zmienialność obiektów ma węższe konsekwencje. Przy innym stylu programowania analogie między językami przestają działać.) Trudności polegają na tym, że jeśli np. jedyny typ stringów jest zmienialny, to formalnie przestaje być typem wartościowym. Sam napisałeś: „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ą”. Tyle że w takim języku on jest również powszechnie używany w roli typu wartościowego! Prawdopodobnie częściej niż jako „zmienna stringowa”. Większość użyć wykorzystuje zmienialność najwyżej w trakcie konstrukcji, a później taki obiekt już nie jest zmieniany — za to różne moduły swobodnie przechowują wskaźniki do niego, zakładając, że już się nie zmieni. Porównanie jego zawartości staje się powszechne. Stąd część języków wychodzi z założenia, że będzie to bardziej praktycznie, jeśli domyślna równość w takim przypadku porówna zawartość. Czyli dla takich obiektów mamy dwa sensowne warianty równości. Zwłaszcza że tożsamość różnych prostych typów, np. kolekcji, częściej istnieje na poziomie koncepcyjnym (klonujemy obiekt, kiedy mamy ochotę zapamiętać jego bieżący stan, ale jeszcze go zmieniać, i pilnujemy się, w które miejsce przekazujemy którego klona) niż w sensie jawnego porównania tożsamości dwóch obiektów nieznanego pochodzenia. Tak jest na przykład w Pythonie w przypadku list i słowników (ale nie stringów, które są immutable). Lisp i Scheme są zgodne z ogólną teorią, jeśli za podstawową równość (czy też równoważność) przyjąć EQL / eqv?; ona nie zmienia się w czasie i zmienialne obiekty porównuje po tożsamości, a liczby i znaki po wartości (niestety nie można robić własnych typów wartościowych). Ale ponieważ stringi, listy i tablice są dostępne wyłącznie w wersji zmienialnej, mamy też EQUAL / equal?, które schodzi do ich elementów, w dodatku rekurencyjnie z tą samą operacją. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Wed, 07 Mar 2007 17:00
Date: Wed, 07 Mar 2007 17:00
213 lines
8969 bytes
8969 bytes
Dnia Tue, 06 Mar 2007 00:15:37 +0100, Mariusz Lotko skrobie: > >> 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. To¿samo¶ci obiektów wskazywanych przez te wska¼niki. To nie zmienia faktu, ¿e wska¼niki s± warto¶ciami i ich porównanie jest porównaniem warto¶ci. > Czy to¿samo¶æ przeradza siê w warto¶æ je¶li > obiekt jest inteligentny (smart)? ;-) Nic takiego nie napisa³em. Przecie¿ te warto¶ci to równie¿ wska¼niki. Nie pomerda³y ci siê czasem obiekty wskazuj±ce i obiekty wskazywane? > >> > 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? W ¿adnym z tych przypadków. > >> ¯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ê. Teoretycznie mo¿na - ale w za³o¿eniu obiekty warto¶ciowe s± obiektami ma³ymi, bo w obiektach du¿ych nie op³aca siê tak okre¶laæ warto¶ci. Obiekty warto¶ciowe powinny byæ szczególnie przeznaczone do tego, ¿eby identyfikowaæ siê przez warto¶æ, a co za tym idzie, tanio siê porównywaæ i tanio kopiowaæ. Nie ma ¶ci¶le okre¶lone, co to znaczy, ¿e obiekt jest du¿y, ale je¶li porównanie to¿samo¶ci obiektów porównywanych przed porównaniem ich warto¶ci jest op³acalne, to znaczy, ¿e obiekt jest "za du¿y" jak na obiekt warto¶ciowy. > > 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? Moja teoria ma odniesienie do projektowania, a nie do jêzyka. Nie zabrania ona u¿ywania wska¼ników do obiektów warto¶ciowych, ale pod warunkiem, ¿e ich u¿ywanie jest spraw± czysto jêzykow± (typu przekazanie przez wska¼nik/referencjê, czy konieczno¶æ weryfikacji w operatorze przypisania), nie mo¿e natomiast s³u¿yæ do wydawania decyzji na podstawie okre¶lania to¿samo¶ci obiektu. To ostatnie mo¿e byæ brane pod uwagê tylko przez metody danej klasy z uwagi na konieczno¶æ posiadania dostêpu do ró¿nych detali implementacyjnych. Zewnêtrze tego nie powinno potrzebowaæ. > >> > 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æ. To lepiej sobie przypomnij - bo sytuacji, ¿eby ktokolwiek w jakim¶ programie sprawdza³, czy "a.x == b.x, ale ile wynosi a.x nie mam zielonego pojêcia", ja sobie nie przypominam. > >> > 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. A co maj± do tego 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ê. Bo modyfikacja w obiekcie typu StringBuilder jest widziana w ka¿dym miejscu, gdzie jest trzymana referencja do tego obiektu. W przypadku typu String z przyczyn oczywistych ta zale¿no¶æ nie zachodzi. > >> > 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. Czyli w³a¶nie strzeli³e¶ sobie gola ;) Jak najbardziej chcemy sprawdziæ, czy dziewczyna.stan == "wolny". Ale nie ma sensu sprawdzanie, czy dziewczyna.stan == me.stan, je¶li nie wiemy jaki jest stan jednego z tych obiektów. > >> 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? To jest zupe³nie inna sprawa - to nie jest porównywanie, tylko porz±dkowanie (zgodnie z terminologi± STL - operator <). -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Wed, 07 Mar 2007 17:44
Date: Wed, 07 Mar 2007 17:44
98 lines
4975 bytes
4975 bytes
Dnia Tue, 06 Mar 2007 00:36:01 +0100, Marcin 'Qrczak' Kowalczyk skrobie: > Dnia 04-03-2007, nie o godzinie 22:09 +0000, Sektor van Skijlen > napisa³(a): > > Tak, tylko ¿e je¶li "wierzymy w podzia³ na obiekty warto¶ciowe i > > niewarto¶ciowe" (czytaj: mamy oczy tam gdzie trzeba), to relacja 'is' w > > obiektach warto¶ciowych jest nam zbêdna, a '==' w obiektach niewarto¶ciowych > > równie¿ nie ma sensu. > Ten idealistyczny obraz, teoretycznie s³uszny, sprawia pewne trudno¶ci > w jêzykach, w których wiele podstawowych typów jest zmienialnych. > (Wyj±tkowo nie dotyczy to C++, które pracuje w innym paradygmacie: > powszechnie niejawnie kopiuje obiekty, przez co zmienialno¶æ obiektów > ma wê¿sze konsekwencje. Przy innym stylu programowania analogie miêdzy > jêzykami przestaj± dzia³aæ.) Zgadza siê - ale nie tylko dlatego. Obiekty niewarto¶ciowe jak najbardziej wystêpuj± w C++. Chodzi tylko o to, ¿e w C++ - w odró¿nieniu od wiêkszo¶ci jêzyków - mo¿na tworzyæ w³asne typy warto¶ciowe. Fakt, ¿e ka¿dy typ ma domy¶lne traktowanie jako warto¶ciowy, jest przykr± konsekwencj± drobnego uogólnienia (jego brak zwykle oznacza, ¿e nie da siê tworzyæ w³asnych typów warto¶ciowych; w C# zrobili dobr± przymiarkê na udostêpnienie tego inn± metod±, tylko niestety sprawê spartolili). > Trudno¶ci polegaj± na tym, ¿e je¶li np. jedyny typ stringów jest > zmienialny, to formalnie przestaje byæ typem warto¶ciowym. Sam > napisa³e¶: ?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±?. Tyle ¿e w takim jêzyku on jest > równie¿ powszechnie u¿ywany w roli typu warto¶ciowego! Ha! Wynika to z faktu, ¿e string z natury jest typem warto¶ciowym. Je¶li jêzyk nie umo¿liwia zrobienia takiego typu warto¶ciowego, to trzeba robiæ obej¶cia w postaci obiektu niemodyfikowalnego. > Prawdopodobnie > czê¶ciej ni¿ jako ?zmienna stringowa?. Wiêkszo¶æ u¿yæ wykorzystuje > zmienialno¶æ najwy¿ej w trakcie konstrukcji, a pó¼niej taki obiekt ju¿ > nie jest zmieniany ? za to ró¿ne modu³y swobodnie przechowuj± wska¼niki > do niego, zak³adaj±c, ¿e ju¿ siê nie zmieni. Porównanie jego zawarto¶ci > staje siê powszechne. Zgadza siê - ale skoro jest to obiekt niemodyfikowalny, to mo¿e byæ traktowany jako typ warto¶ciowy, gdy¿ zmienno¶æ w tym przypadku nie powoduje konsekwencji wchodzenia zmienno¶ci w interakcjê z to¿samo¶ci±. De facto zatem, to¿samo¶æ takich obiektów nie ma dla nas znaczenia, co wystarcza do stwierdzenia, ¿e jest to typ warto¶ciowy. Ale skoro tak, to i porównywanie tego obiektu powinno porównywaæ warto¶æ, a nie to¿samo¶æ. I tak w³a¶nie jest w C#. > St±d czê¶æ jêzyków wychodzi z za³o¿enia, ¿e bêdzie to bardziej > praktycznie, je¶li domy¶lna równo¶æ w takim przypadku porówna zawarto¶æ. > Czyli dla takich obiektów mamy dwa sensowne warianty równo¶ci. Ale tylko jeden z tych wariantów ma sens. To¿samo¶æ dwóch obiektów typu string, je¶li to s± obiekty niezmienialne, jest nieistotna - program nie powinien w ¿adnym przypadku polegaæ na tej to¿samo¶ci. To¿samo¶æ jest wa¿na, je¶li obiekt jest zmienialny. > Zw³aszcza ¿e to¿samo¶æ ró¿nych prostych typów, np. kolekcji, czê¶ciej > istnieje na poziomie koncepcyjnym (klonujemy obiekt, kiedy mamy ochotê > zapamiêtaæ jego bie¿±cy stan, ale jeszcze go zmieniaæ, i pilnujemy siê, > w które miejsce przekazujemy którego klona) ni¿ w sensie jawnego > porównania to¿samo¶ci dwóch obiektów nieznanego pochodzenia. > Tak jest na przyk³ad w Pythonie w przypadku list i s³owników (ale nie > stringów, które s± immutable). Nie rozumiem. > Lisp i Scheme s± zgodne z ogóln± teori±, je¶li za podstawow± równo¶æ > (czy te¿ równowa¿no¶æ) przyj±æ EQL / eqv?; ona nie zmienia siê w czasie > i zmienialne obiekty porównuje po to¿samo¶ci, a liczby i znaki po > warto¶ci (niestety nie mo¿na robiæ w³asnych typów warto¶ciowych). > Ale poniewa¿ stringi, listy i tablice s± dostêpne wy³±cznie w wersji > zmienialnej, mamy te¿ EQUAL / equal?, które schodzi do ich elementów, > w dodatku rekurencyjnie z t± sam± operacj±. O ile sobie przypominasz, w której¶ z naszych wcze¶niejszych dyskusji nawet zgodzili¶my siê co do tego. Ró¿nica polega jedynie na tym, czy mo¿na tworzyæ w³asne typy warto¶ciowe i czy mo¿na obiekty warto¶ciowe modyfikowaæ w miejscu. Ale te sprawy s± ju¿ ¶ci¶le zwi±zane z okre¶lonymi ficzerami jêzykowymi. Je¶li jêzyk umo¿liwia³by tylko chocia¿by mo¿liwo¶æ definiowania w³asnych typów warto¶ciowych, to rozró¿nianie porównania to¿samo¶ci i porównania warto¶ci nie by³oby potrzebne. ¦miem wrêcz twierdziæ, ¿e wystarczy³aby do tego konstrukcja jêzykowa, która tak stanowi i jednocze¶nie uniemo¿liwia modyfikacjê takiego obiektu. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Wed, 07 Mar 2007 17:52
Date: Wed, 07 Mar 2007 17:52
118 lines
5228 bytes
5228 bytes
Dnia Mon, 05 Mar 2007 23:58:08 +0100, Mariusz Lotko skrobie: > Sektor van Skijlen wrote: > > Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie: > >> > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako > >> > warto¶ciowy, to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas > >> > interesowaæ w ogóle. > > > >> A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu to¿samo¶ci > >> obiektu w pierszej linijce operatora == uwa¿asz za b³êdny? > > > > Tak. > Wybacz, ale powy¿szym stwierdzeniem sk³aniasz mnie do stwierdzenia u Ciebie > paranoi... Przecie¿ stosowanie tego jest oczywiste. Po co mam sprawdzaæ, > czy mam tyle samo pieniêdzy w swoim portfelu co... w swoim? Portfel nie jest typem warto¶ciowym. Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu, podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i materia³, z którego go wykonano. Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany tam kod koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z ka¿dej kartki najpierw sprawdziæ, czy te obie kartki to czasem nie jest jedna i ta sama kartka. Jaki to ma sens? > >> Podobnie w operatorze =, w którym zapobiega to przypisania obiektu > >> samemu sobie? > > > > Tu ju¿ nie, ale to jest zwi±zane z tzw. kwesti± jêzykow±. W przypadku C++ > > jest to konieczne, je¿eli obiekt podawany jako argument operatora = jest > > przekazywany przez referencjê. > > > > Nie by³oby natomiast tego problemu w przypadku, gdyby ten obiekt by³ tam > > przekazywany przez warto¶æ. > > > > Gdyby hipotetycznie w Javie by³a mo¿liwo¶æ zrobienia czego¶ podobnego, to > > tam te¿ nie ma konieczno¶ci dodawania takiego sprawdzenia: > Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a > o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same" > a wiêc na pewno "takie same" obiekty. To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej bêdzie wylot. Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie. > >> > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich typów > >> > jak int, czy std::string. Je¶li ju¿, to stosuje siê albo uogólnienie > >> > przekazywania (const T&), albo przekazuje siê do zmodyfikowania (T&, > >> > T*). Czy widzia³e¶ kiedykolwiek w jakim¶ rzeczywistym programie, ¿eby > >> > kto¶ porównywa³ dwa wska¼niki do int (pomijaj±c przypadek, gdy wska¼nik > >> > do int jest u¿ywany jako iterator do tablicy int-ów - czyli > >> > zastosowanie jest inne, ni¿ warto¶æ referencji)? > > > >> Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê > >> robiæ specjalne implementacje dla typów prostych. > > > > Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam typ > > parametryczny T traktuje siê prawdopodobnie zawsze jak typ obiektowy, wiêc > > sprawa konkretyzacji na int nie ma i tak znaczenia. > "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku > szablonów, które wed³ug mojej praktyki z regu³y s± po prostu przeznaczone > dla obiektów oferuj±cych okre¶lony interfejs. I innych ograniczeñ w ich > u¿yciu w³a¶ciwie nie ma. Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿ typy obiektowe. > > Ale je¶li jest traktowany jako typ obiektowy, a nie warto¶ciowy, to > > równie¿ istnieje przekazywanie przez referencjê, czy nieu¿ywanie operatora > > == (bo nie wiadomo, czy zdefiniowany) itd. - czyli typu T nie uwa¿a siê za > > warto¶ciowy. > Takich za³o¿eñ raczej te¿ siê nie podejmuje w C++. Je¶li co¶ nie jest > zdefiniowane, to poinformuje nas o tym kompilator w czasie konkretyzacji > szablonu. Powoduj±c, ¿e dla danego typu nie da siê tego szablonu zastosowaæ, wiêc nie ma tematu. > >> > Dlatego to¿samo¶ci± dla obiektów warto¶ciowych jest warto¶æ. Obiekty > >> > mog± sobie t± warto¶æ przekazywaæ jak chc±, a nawet - jak pamiêtasz, > >> > dyskutowali¶my o tym - warto¶ci mog± byæ symulowane przez > >> > predefiniowane unikalne obiekty i w takim przypadku porównanie > >> > to¿samo¶ci takich obiektów jest równowa¿ne porównaniu warto¶ci, choæ to > >> > ju¿ jest szczegó³ implementacyjny. > > > >> Nie zgadzam siê. Ka¿dy obiekt jest uproszczeniem rzeczywisto¶ci, a co za > >> tym idzie z du¿ym prawdopodobieñstwem mog± pojawiæ siê obiekty o tych > >> samych warto¶ciach, które nie s± tymi samymi obiektami. > > > > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z > > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ. > Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo. Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ) Oraz obiekt: historia transakcji Oraz... Czy ty w ogóle wiesz, co to jest "warto¶æ"? > Nie chcia³bym mieæ konta w banku, który ma k³opot z odró¿nieniem > warto¶ci mojego konta od jego to¿samo¶ci. Na razie to masz problem z odró¿nieniem warto¶ci od stanu. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Wed, 07 Mar 2007 19:59
Date: Wed, 07 Mar 2007 19:59
132 lines
5590 bytes
5590 bytes
Sektor van Skijlen wrote: > Dnia Mon, 05 Mar 2007 23:58:08 +0100, Mariusz Lotko skrobie: >> Sektor van Skijlen wrote: > >> > Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie: >> >> > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako >> >> > warto¶ciowy, to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas >> >> > interesowaæ w ogóle. >> > >> >> A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu >> >> to¿samo¶ci obiektu w pierszej linijce operatora == uwa¿asz za b³êdny? >> > >> > Tak. > >> Wybacz, ale powy¿szym stwierdzeniem sk³aniasz mnie do stwierdzenia u >> Ciebie paranoi... Przecie¿ stosowanie tego jest oczywiste. Po co mam >> sprawdzaæ, czy mam tyle samo pieniêdzy w swoim portfelu co... w swoim? > > Portfel nie jest typem warto¶ciowym. > > Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu, > podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i materia³, z > którego go wykonano. I w _ka¿dym_ systemie tak to modelujesz? Z pe³n± otoczk±? Piêkny przyk³ad wzorca "swiss army knife". > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor > mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany tam > kod koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z ka¿dej > kartki najpierw sprawdziæ, czy te obie kartki to czasem nie jest jedna i > ta sama kartka. Jaki to ma sens? Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: data naniesienia, technika wykonania i stopieñ nas³onecznienia, które pozwalaj± obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê porównaæ dwóch "czerwonych". Odsy³am do ekspertów - lakierników samochodowych. >> >> Podobnie w operatorze =, w którym zapobiega to przypisania obiektu >> >> samemu sobie? >> > >> > Tu ju¿ nie, ale to jest zwi±zane z tzw. kwesti± jêzykow±. W przypadku >> > C++ jest to konieczne, je¿eli obiekt podawany jako argument operatora >> > jest przekazywany przez referencjê. >> > >> > Nie by³oby natomiast tego problemu w przypadku, gdyby ten obiekt by³ >> > tam przekazywany przez warto¶æ. >> > >> > Gdyby hipotetycznie w Javie by³a mo¿liwo¶æ zrobienia czego¶ podobnego, >> > to tam te¿ nie ma konieczno¶ci dodawania takiego sprawdzenia: > >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same" >> a wiêc na pewno "takie same" obiekty. > > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej bêdzie > wylot. W operatorze porównania? Nie s±dzê... > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie. W pewnych przypadkach mo¿e tak byæ. Implementuj±c operator warto oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów. Generalnie jednak - nie zgadzam siê. >> >> > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich >> >> > typów jak int, czy std::string. Je¶li ju¿, to stosuje siê albo >> >> > uogólnienie przekazywania (const T&), albo przekazuje siê do >> >> > zmodyfikowania (T&, T*). Czy widzia³e¶ kiedykolwiek w jakim¶ >> >> > rzeczywistym programie, ¿eby kto¶ porównywa³ dwa wska¼niki do int >> >> > (pomijaj±c przypadek, gdy wska¼nik do int jest u¿ywany jako iterator >> >> > do tablicy int-ów - czyli zastosowanie jest inne, ni¿ warto¶æ >> >> > referencji)? >> > >> >> Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê >> >> robiæ specjalne implementacje dla typów prostych. >> > >> > Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam >> > typ parametryczny T traktuje siê prawdopodobnie zawsze jak typ >> > obiektowy, wiêc sprawa konkretyzacji na int nie ma i tak znaczenia. > >> "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku >> szablonów, które wed³ug mojej praktyki z regu³y s± po prostu przeznaczone >> dla obiektów oferuj±cych okre¶lony interfejs. I innych ograniczeñ w ich >> u¿yciu w³a¶ciwie nie ma. > > Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿ typy > obiektowe. Znowu ogólnik: "zwykle"... "Sprzedajesz" nam teoriê, która ma dzia³aæ w praktyce, u³atwiaæ j±. Chcia³by¶, ¿eby Twój samochód "zwykle" dzia³a³? > >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ. > >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo. > > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ) > Oraz obiekt: historia transakcji > Oraz... Jak wy¿ej: zale¿y od kontekstu. Mo¿emy nie wi±zaæ obiektów transakcji do konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do konta. I podobnie z w³a¶cicielem. Krótko mówi±c "konto jest anonimowe" i przechowuje jedynie swoje saldo (warto¶æ) oraz numer (to¿samo¶æ). Nie wiem, czy to ma sens, ale nie mo¿esz chyba wykluczyæ, ¿e w jakim¶ tam systemie mo¿e mieæ. > Czy ty w ogóle wiesz, co to jest "warto¶æ"? Element ze zbioru (tu: typ, klasa). >> Nie chcia³bym mieæ konta w banku, który ma k³opot z odró¿nieniem >> warto¶ci mojego konta od jego to¿samo¶ci. > > Na razie to masz problem z odró¿nieniem warto¶ci od stanu. Hmm, mam na ten temat "swoj± teoriê". Na razie przyjmijmy, ¿e jestem betonem zamkniêtym na Twoj± ¶wiat³± my¶l. Na pocieszenie powiem Ci, ¿e je¶li Twoja teoria siê przyjmie i w kilku ksi±¿kach pojawi± siê sformu³owania w rodzaju "s³ynny obiektolog prof. van Skijlen opisuje to w swojej pracy...", to zg³oszê siê do Ciebie po autograf :-) A tymczasem pozwolê sobie zakoñczyæ, bo ju¿ chyba nikt nas nie czyta, a i argumenty jakby zaczê³y siê powtarzaæ. -- Mariusz Lotko
Wartości i obiekty
Author: Marcin 'Qrczak'
Date: Thu, 08 Mar 2007 00:32
Date: Thu, 08 Mar 2007 00:32
176 lines
7528 bytes
7528 bytes
Dnia 07-03-2007, śro o godzinie 17:44 +0000, Sektor van Skijlen napisał(a): > > Trudności polegają na tym, że jeśli np. jedyny typ stringów jest > > zmienialny, to formalnie przestaje być typem wartościowym. Sam > > napisałeś: ?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ą?. Tyle że w takim języku on jest > > również powszechnie używany w roli typu wartościowego! > > Ha! Wynika to z faktu, że string z natury jest typem wartościowym. Jeśli > język nie umożliwia zrobienia takiego typu wartościowego, to trzeba robić > obejścia w postaci obiektu niemodyfikowalnego. To nie jest obejście. W językach, w których obiekt jest podstawowym pojęciem pierwotnym, kwintesencją typu wartościowego jest obiekt niemodyfikowalny. (Można też wyjść od wartości jako pojęcia pierwotnego, a obiekty budować z pogrupowanych w rekordy i inne struktury zmiennych zawierających wartości. Takie podejście wydaje się właściwym sposobem opisu SML-a i Erlanga, gdzie współdzielenie fragmentów wartości jest nieobserwowalne z poziomu języka źródłowego, mimo że implementacyjnie może ono wystąpić bądź nie. Ale w większości języków wygodniej jest zacząć od obiektów.) Jeśli odstawić na bok nietypowy punkt widzenia C++, to wartości dzielą się na te, które są reprezentowane przez niezmienialne obiekty o nieistotnej tożsamości, i na te, które są wskaźnikami na zmienialne obiekty. Jest jeszcze trzecia kategoria leżąca pomiędzy tymi dwiema: wskaźniki na singletony, czyli na jedyne obiekty danego rodzaju, np. true / false / nil. Te obiekty są niezmienialne, ale tożsamość tych obiektów jest dobrze zdefiniowana; rozróżnianie ich po tożsamości jest równoważne rozróżnianiu po cechach wewnętrznych. Wartości można umieszczać w zmiennych. Dana zmienna może zawierać różne wartości w różnym czasie. Jeśli spróbować dopasować do tego modelu C++, to się okaże, że zmienną C++ zawierającą obiekt można rozumieć na dwa sposoby: a) Jako zmienialny obiekt, przywiązany na stałe do swojej nazwy. To tłumaczenie jest odpowiednie w przypadku obiektów z tożsamością, zwłaszcza złożonych, bo pozwala wymodelować możliwość zmiany indywidualnych pól obiektu z zachowaniem tożsamości całego obiektu. Takie obiekty są zwykle przekazywane przez referencje C++ albo wskaźniki C++, co odpowiada przekazaniu wskaźnika na obiekt w modelu, a więc odpowiada naturalnemu sposobowi przekazania wartości w modelu. b) Jako zmienną zawierającą wartość, która sama jest niezmienialna. To tłumaczenie jest lepsze dla atomowych typów wartościowych, bo pozwala wymodelować wartość wyabstrahowaną od miejsca przechowywania. Takie obiekty są w C++ zwykle kopiowane, co odpowiada przekazaniu odczytanej bieżącej wartości zmiennej w modelu, czyli znowu jest naturalnym sposobem przekazania wartości, mimo że w C++ jest inne niż tamto. Użycie do atomowych typów wartościowych mapowania a) zamiast b) wymagałoby klonowania obiektów, co jest nienaturalne i niewygodne, normalnie nie jest wspierane składniowo. Z drugiej strony, użycie do złożonych obiektów mapowania b) zamiast a) wymagałoby wymodelowania przekazania wskaźnika za pomocą wskaźnika na zmienną, co w wielu językach nie jest nawet wspierane. Dlatego zdecydowanie się na jeden sposób mapowania prowadziłoby do nienaturalnego kodu w modelu w części przypadków. Istnienie dwóch możliwych mapowań z nieoczywistym wyborem między nimi powoduje, że realizacje zadań nie przekładają się między C++ a innymi językami dosłownie ani konsekwentnie. W C++ jest grupa typów, które mają złożoną strukturę wewnętrzną, ale których kopiowanie ma sens, np. string albo vector. Takie obiekty czasem są kopiowane, czyli przekazywane przez wartość, a czasem są przekazywane referencje do nich. Tutaj wybór mapowania jest szczególnie nieoczywisty, bo można traktować te obiekty albo jako wartości (i zrealizować je jako obiekty niezmienialne, swobodnie przekazywane między zmiennymi, ale tworzone na nowo przy obliczeniach), albo jako obiekty z tożsamością (i zrealizować je jako obiekty zmienialne, jawnie klonowane w razie potrzeby). To wszystko dotyczyło obiektów zawartych w zmiennych. W C++ jeszcze są obiekty alokowane na stercie i przekazywane przez wskaźniki. One mają jednoznaczne przełożenie na ten model, które jest podobne do wersji a). Przy tłumaczeniu w drugą stronę, na C++, ten wybór teoretycznie byłby uniwersalny, tyle że C++ unika takich obiektów z powodu braku odśmiecania, więc jest tendencja do umieszczenia obiektu od razu w zmiennej. > > Prawdopodobnie > > częściej niż jako ?zmienna stringowa?. Większość użyć wykorzystuje > > zmienialność najwyżej w trakcie konstrukcji, a później taki obiekt już > > nie jest zmieniany ? za to różne moduły swobodnie przechowują wskaźniki > > do niego, zakładając, że już się nie zmieni. Porównanie jego zawartości > > staje się powszechne. > > Zgadza się - ale skoro jest to obiekt niemodyfikowalny, to może być traktowany > jako typ wartościowy, gdyż zmienność w tym przypadku nie powoduje konsekwencji > wchodzenia zmienności w interakcję z tożsamością.. Pisałem tutaj o zmienialnym stringu, zakładając, że to jest jedyny string w danym języku. Czyli kiedy złożony typ pełniący rolę typu wartościowego jest jednak zmienialny. Taka sytuacja jest kłopotliwa. Mój model w wersji czystej wymaga zdecydowania się, który styl użycia jest tutaj dominujący. Pomieszanie styli grozi błędami aliasowania albo niepotrzebnymi kopiami. Jeśli w różnych miejscach programu ten sam typ jest używany w różnym stylu, to trudno zrobić jeden operator porównania, który pasuje do obu. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
Re: =?ISO-8859-2?Q?Warto¶ci?= i obiekty
Author: Sektor van Skijl
Date: Sat, 10 Mar 2007 18:47
Date: Sat, 10 Mar 2007 18:47
191 lines
8595 bytes
8595 bytes
Dnia Thu, 08 Mar 2007 00:32:04 +0100, Marcin 'Qrczak' Kowalczyk skrobie: > To nie jest obej¶cie. W jêzykach, w których obiekt jest podstawowym > pojêciem pierwotnym, kwintesencj± typu warto¶ciowego jest obiekt > niemodyfikowalny. No wtedy tak. Nie twierdzê, ¿e tak jest dobrze, czy ¼le - to jest szczegó³. Po prostu konsekwencj± nieistnienia naturalnych typów warto¶ciowych jest to, ¿e typy warto¶ciowe nale¿y definiowaæ jako sta³e obiekty. > Je¶li odstawiæ na bok nietypowy punkt widzenia C++, to warto¶ci dziel± > siê na te, które s± reprezentowane przez niezmienialne obiekty > o nieistotnej to¿samo¶ci, i na te, które s± wska¼nikami na zmienialne > obiekty. O istniej±cej to¿samo¶ci. :) > Jest jeszcze trzecia kategoria le¿±ca pomiêdzy tymi dwiema: > wska¼niki na singletony, czyli na jedyne obiekty danego rodzaju, > np. true / false / nil. Te obiekty s± niezmienialne, ale to¿samo¶æ > tych obiektów jest dobrze zdefiniowana; rozró¿nianie ich po to¿samo¶ci > jest równowa¿ne rozró¿nianiu po cechach wewnêtrznych. Nie tworzy³bym specjalnej kategorii dla tych obiektów. Po pierwsze, s± one sta³e, wiêc bez problemów mo¿na je zaliczyæ do typów warto¶ciowych. Po drugie, kwestia sposobu ich porównania mo¿e byæ kwesti± czysto implementacyjn±. O ile sobie przypominasz, wskazywa³em ci ju¿ kiedy¶, ¿e jest mo¿liwe takie zorganizowanie warto¶ci ca³kowitych, ¿e ka¿dej liczbie odpowiada obiekt. Ka¿da nowo powsta³a liczba bêdzie albo nowo utworzonym obiektem, a je¶li jest ju¿ obiekt, który symbolizuje dan± liczbê, to siê go znajduje i zwraca. W takim przypadku mo¿emy ¶mia³o stwierdziæ, ¿e ka¿dy obiekt symbolizuj±cy liczbê ca³kowit± jest unikalny - nie ma dwóch obiektów o takiej samej zawarto¶ci. Jest to oczywi¶cie nieoptymalne i nikt tego jak najbardziej nie robi, ale jest to przyk³ad na to, ¿e liczby mog± byæ takimi w³a¶nie "singletonami". Wiêc je¶li mamy pewno¶æ, ¿e istnieje tylko jeden obiekt okre¶lonej klasy w ca³ym systemie, który posiada okre¶lon± zawarto¶æ, to jest oczywiste, ¿e porównanie to¿samo¶ci tych obiektów da ten sam wynik, co porównanie ich zawarto¶ci. Ale sposób porównywania tych obiektów, które s± typami warto¶ciowymi, powinien zale¿eæ ju¿ od implementacji. Efekt jest taki, ¿e nawet je¶li zrobimy ten podzia³ wedle tego, co mówisz, to potrzebujemy nastêpuj±cych typów i odpowiadaj±cych im domy¶lnych metod porównania: 1. Obiektów modyfikowalnych, które s± porównywane po to¿samo¶ci 2. Obiektów sta³ych, które s± porównywane po zawarto¶ci 3. Obiektów sta³ych unikalnych, które s± porównywane po to¿samo¶ci I do ¿adnego z rodzajów typów tych obiektów nie potrzebujemy nigdy dwóch osobnych operatorów porównania. > Warto¶ci mo¿na umieszczaæ w zmiennych. Dana zmienna mo¿e zawieraæ ró¿ne > warto¶ci w ró¿nym czasie. Tak. > Je¶li spróbowaæ dopasowaæ do tego modelu C++, to siê oka¿e, ¿e zmienn± > C++ zawieraj±c± obiekt mo¿na rozumieæ na dwa sposoby: > a) Jako zmienialny obiekt, przywi±zany na sta³e do swojej nazwy. > To t³umaczenie jest odpowiednie w przypadku obiektów z to¿samo¶ci±, > zw³aszcza z³o¿onych, bo pozwala wymodelowaæ mo¿liwo¶æ zmiany > indywidualnych pól obiektu z zachowaniem to¿samo¶ci ca³ego obiektu. > Takie obiekty s± zwykle przekazywane przez referencje C++ albo > wska¼niki C++, co odpowiada przekazaniu wska¼nika na obiekt > w modelu, a wiêc odpowiada naturalnemu sposobowi przekazania > warto¶ci w modelu. > b) Jako zmienn± zawieraj±c± warto¶æ, która sama jest niezmienialna. > To t³umaczenie jest lepsze dla atomowych typów warto¶ciowych, > bo pozwala wymodelowaæ warto¶æ wyabstrahowan± od miejsca > przechowywania. Takie obiekty s± w C++ zwykle kopiowane, > co odpowiada przekazaniu odczytanej bie¿±cej warto¶ci zmiennej > w modelu, czyli znowu jest naturalnym sposobem przekazania warto¶ci, > mimo ¿e w C++ jest inne ni¿ tamto. Szczerze mówi±c to nic z tego nie rozumiem. > U¿ycie do atomowych typów warto¶ciowych mapowania a) zamiast b) > wymaga³oby klonowania obiektów, co jest nienaturalne i niewygodne, > normalnie nie jest wspierane sk³adniowo. Z drugiej strony, u¿ycie do > z³o¿onych obiektów mapowania b) zamiast a) wymaga³oby wymodelowania > przekazania wska¼nika za pomoc± wska¼nika na zmienn±, co w wielu > jêzykach nie jest nawet wspierane. Dlatego zdecydowanie siê na jeden > sposób mapowania prowadzi³oby do nienaturalnego kodu w modelu > w czê¶ci przypadków. Jeszcze raz - tylko pro¶ciej ;) > Istnienie dwóch mo¿liwych mapowañ z nieoczywistym wyborem miêdzy nimi > powoduje, ¿e realizacje zadañ nie przek³adaj± siê miêdzy C++ a innymi > jêzykami dos³ownie ani konsekwentnie. Ale to nie ma wiêkszego znaczenia. > W C++ jest grupa typów, które maj± z³o¿on± strukturê wewnêtrzn±, ale > których kopiowanie ma sens, np. string albo vector. Vector moim zdaniem niespecjalnie. > Takie obiekty czasem > s± kopiowane, czyli przekazywane przez warto¶æ, a czasem s± przekazywane > referencje do nich. Ale przekazywanie stringa przez referncjê robi siê wy³±cznie ze wzglêdów optymalizacyjnych. Nie ma ¿adnych przes³anek czysto jêzykowych, które by nakazywa³y inne przekazywanie, ni¿ przez warto¶æ. > Tutaj wybór mapowania jest szczególnie nieoczywisty, > bo mo¿na traktowaæ te obiekty albo jako warto¶ci (i zrealizowaæ je jako > obiekty niezmienialne, swobodnie przekazywane miêdzy zmiennymi, ale > tworzone na nowo przy obliczeniach), albo jako obiekty z to¿samo¶ci± > (i zrealizowaæ je jako obiekty zmienialne, jawnie klonowane w razie > potrzeby). Tu siê nie zgadzam. String zawsze powinien byæ traktowany jak warto¶æ, natomiast wektor zawsze jak obiekt. > To wszystko dotyczy³o obiektów zawartych w zmiennych. W C++ jeszcze s± > obiekty alokowane na stercie i przekazywane przez wska¼niki. One maj± > jednoznaczne prze³o¿enie na ten model, które jest podobne do wersji a). > Przy t³umaczeniu w drug± stronê, na C++, ten wybór teoretycznie by³by > uniwersalny, tyle ¿e C++ unika takich obiektów z powodu braku > od¶miecania, wiêc jest tendencja do umieszczenia obiektu od razu > w zmiennej. Przyczyny wydajno¶ciowe równie¿ jednak istniej± :). Z tego przecie¿ powodu podobno IBM-owska Java ma taki trik optymalizacyjny (którym mia³a podobno pognêbiæ C#), ¿e je¶li obiekt jest tworzony w funkcji i nigdzie nie przekazywany na zewn±trz tej funkcji (tzn. metody), to jest tworzony w ca³o¶ci na stosie. > > > Prawdopodobnie > > > czê¶ciej ni¿ jako ?zmienna stringowa?. Wiêkszo¶æ u¿yæ wykorzystuje > > > zmienialno¶æ najwy¿ej w trakcie konstrukcji, a pó¼niej taki obiekt ju¿ > > > nie jest zmieniany ? za to ró¿ne modu³y swobodnie przechowuj± wska¼niki > > > do niego, zak³adaj±c, ¿e ju¿ siê nie zmieni. Porównanie jego zawarto¶ci > > > staje siê powszechne. > > > > Zgadza siê - ale skoro jest to obiekt niemodyfikowalny, to mo¿e byæ traktowany > > jako typ warto¶ciowy, gdy¿ zmienno¶æ w tym przypadku nie powoduje konsekwencji > > wchodzenia zmienno¶ci w interakcjê z to¿samo¶ci±. > Pisa³em tutaj o zmienialnym stringu, zak³adaj±c, ¿e to jest jedyny > string w danym jêzyku. Czyli kiedy z³o¿ony typ pe³ni±cy rolê typu > warto¶ciowego jest jednak zmienialny. Taka sytuacja jest k³opotliwa. Oj... nie bardzo to widzê. Takie co¶ jest mo¿liwe w C++, który w naturalny sposób obs³uguje typy warto¶ciowe i pozwala typom definiowaæ operatory. W ten sposób mo¿na zrobiæ typ warto¶ciowy, którego obiekt jest modyfikowalny w miejscu. Je¶li jêzyk nie udostêpnia takiego mechanizmu, to jest skazany na zrobienie takiego tricku, jak obiekt, którego nie mo¿na modyfikowaæ po utworzeniu (bo nie ma operacji, które na to pozwalaj±). Jêzyk zatem powinien umo¿liwiaæ albo: - jak C++, zrobienie wszystkiego i przedefiniowanie wszystkich operatorów - pozwoliæ tylko na wybrane definicje - ale niech one umo¿liwi± programi¶cie zrobienie równie¿ typów warto¶ciowyych > Mój model w wersji czystej wymaga zdecydowania siê, który styl u¿ycia > jest tutaj dominuj±cy. Pomieszanie styli grozi b³êdami aliasowania albo > niepotrzebnymi kopiami. No w³a¶nie - ale nie mo¿esz zrobiæ tak, ¿e w ca³ym jêzyku jeden model obowi±zuje wszystkie obiekty. > Je¶li w ró¿nych miejscach programu ten sam typ > jest u¿ywany w ró¿nym stylu, to trudno zrobiæ jeden operator porównania, > który pasuje do obu. To wtedy trzeba zrobiæ osobne typy. Tak jak w Javie jest String i StringBuilder. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Sat, 10 Mar 2007 19:17
Date: Sat, 10 Mar 2007 19:17
205 lines
8652 bytes
8652 bytes
Dnia Wed, 07 Mar 2007 19:59:52 +0100, Mariusz Lotko skrobie: > Sektor van Skijlen wrote: > > Dnia Mon, 05 Mar 2007 23:58:08 +0100, Mariusz Lotko skrobie: > >> Sektor van Skijlen wrote: > > > >> > Dnia Mon, 05 Mar 2007 07:07:55 +0100, Mariusz Lotko skrobie: > >> >> > No w³a¶nie o to chodzi, ¿e nie. Je¶li okre¶lamy dany typ jako > >> >> > warto¶ciowy, to to¿samo¶æ przechowuj±cego j± obiektu nie powinna nas > >> >> > interesowaæ w ogóle. > >> > > >> >> A zatem powszechnie stosowany "trik" polegaj±cy na sprawdzeniu > >> >> to¿samo¶ci obiektu w pierszej linijce operatora == uwa¿asz za b³êdny? > >> > > >> > Tak. > > > >> Wybacz, ale powy¿szym stwierdzeniem sk³aniasz mnie do stwierdzenia u > >> Ciebie paranoi... Przecie¿ stosowanie tego jest oczywiste. Po co mam > >> sprawdzaæ, czy mam tyle samo pieniêdzy w swoim portfelu co... w swoim? > > > > Portfel nie jest typem warto¶ciowym. > > > > Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu, > > podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i materia³, z > > którego go wykonano. > I w _ka¿dym_ systemie tak to modelujesz? Z pe³n± otoczk±? Piêkny przyk³ad > wzorca "swiss army knife". Nie u¿ywaj pojêæ, których znaczenia nie rozumiesz. Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ pieni±dze, laptopy, meble, samochody, kontenery i elektrownie. Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel nie mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ jeszcze wiele innych stanów i atrytbutów. > > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor > > mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany tam > > kod koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z ka¿dej > > kartki najpierw sprawdziæ, czy te obie kartki to czasem nie jest jedna i > > ta sama kartka. Jaki to ma sens? > Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: data > naniesienia, technika wykonania i stopieñ nas³onecznienia, które pozwalaj± > obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê porównaæ dwóch > "czerwonych". Odsy³am do ekspertów - lakierników samochodowych. Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o kolorze. Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz przypadkiem te¿ nie stanem) lakieru. No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz siê i zg³osisz za tydzieñ? > >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a > >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same" > >> a wiêc na pewno "takie same" obiekty. > > > > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej bêdzie > > wylot. > W operatorze porównania? Nie s±dzê... W operatorze przypisania. > > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie. > W pewnych przypadkach mo¿e tak byæ. Statystycznie jest to 99% przypadków. > Implementuj±c operator warto > oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów. Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla których trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ. Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez wszystkie iteratory w zakresie od jednego do drugiego. Ile masz w tym momencie porównañ, które wyjd± równe, a ile, które wyjd± nierówne? Tu policzyæ bardzo ³atwo: Dla zakresu o d³ugo¶ci N, bêdziesz mia³ N-1 porównañ, które siê oka¿± nierówno¶ci±, i jedno, które oka¿e sie równo¶ci±. Ró¿nica ro¶nie wraz z d³ugo¶ci± zakresu i tylko w przypadku gdy zakres ma 1 element porównanie jest szybsze. Dla dwóch elemmentów jest ju¿ mniej wiêcej tak samo kosztowne, wraz z powiêkszaniem siê d³ugo¶ci zakresu porównanie, które najpierw sprawdza to¿samo¶æ, jest kosztowniejsze. Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e ten przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê, ¿e da³oby siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to nie ma wiêkszego znaczenia. W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania analizy, która dowiedzie, czy to siê nam op³aca, czy nie. Ty przyjmujesz "w ciemno", ¿e sprawdzanie najpierw to¿samo¶ci bêdzie zawsze bardziej op³acalne. W ostateczno¶ci zgadzasz siê nawet, ¿e "najczê¶ciej". No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i oszacuj ilo¶æ porównañ trafionych i nietrafionych w typowych algorytmach, które go u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym rozmawiamy. > Generalnie jednak - nie zgadzam siê. Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie potrafiê to uzasadniæ. > >> >> > Zauwa¿, po co w C++ stosuje siê wska¼niki i referencje do takich > >> >> > typów jak int, czy std::string. Je¶li ju¿, to stosuje siê albo > >> >> > uogólnienie przekazywania (const T&), albo przekazuje siê do > >> >> > zmodyfikowania (T&, T*). Czy widzia³e¶ kiedykolwiek w jakim¶ > >> >> > rzeczywistym programie, ¿eby kto¶ porównywa³ dwa wska¼niki do int > >> >> > (pomijaj±c przypadek, gdy wska¼nik do int jest u¿ywany jako iterator > >> >> > do tablicy int-ów - czyli zastosowanie jest inne, ni¿ warto¶æ > >> >> > referencji)? > >> > > >> >> Tak, w dowolnej konkretyzacji szablonu int'em. Nie ka¿demu chce siê > >> >> robiæ specjalne implementacje dla typów prostych. > >> > > >> > Przy uogólnianiu oczywi¶cie jest to prawda, z t± tylko ró¿nic±, ¿e tam > >> > typ parametryczny T traktuje siê prawdopodobnie zawsze jak typ > >> > obiektowy, wiêc sprawa konkretyzacji na int nie ma i tak znaczenia. > > > >> "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku > >> szablonów, które wed³ug mojej praktyki z regu³y s± po prostu przeznaczone > >> dla obiektów oferuj±cych okre¶lony interfejs. I innych ograniczeñ w ich > >> u¿yciu w³a¶ciwie nie ma. > > > > Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿ typy > > obiektowe. > Znowu ogólnik: "zwykle"... "Sprzedajesz" nam teoriê, która ma dzia³aæ w > praktyce, u³atwiaæ j±. Chcia³by¶, ¿eby Twój samochód "zwykle" dzia³a³? Oczywi¶cie teoretycznie mo¿e istnieæ taki wzorzec, który typom nie stawia ¿adnych wymagañ, ale w praktyce nie spotka³em siê z takim. Wymagania co do typów zawsze okre¶laj± poszczególne operacje, które na typie mo¿na wykonaæ. I te operacje ¶wiadcz± te¿ o tym, czy typ jest warto¶ciowy, czy nie. Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym. Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym nastêpuj±ce wymagania wzglêdem typu: - przypisywalny - kopiowalny - domy¶lnie-konstruowalny Poza tym wiele algorytmów STL, które mog³yby pracowaæ równie¿ na zakresie wziêtym z listy, wymagaj± dodatkowo, ¿eby by³ porównywalny. Dostarczaj±c do swojego typu wszystkie mo¿liwe rzeczy, ¿eby spe³niæ wymagania, de facto czynisz z niego typ warto¶ciowy - co mo¿e siê niekoniecznie zgadzaæ z logik± twojego programu. > >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z > >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ. > > > >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo. > > > > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ) > > Oraz obiekt: historia transakcji > > Oraz... > Jak wy¿ej: zale¿y od kontekstu. Nic nie zale¿y od ¿adnego kontekstu. Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest obiektem. > Mo¿emy nie wi±zaæ obiektów transakcji do > konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do konta. Ale co to ma do rzeczy? Transakcja te¿ jest obiektem, tzw. "warto¶æ transakcji" jest atrybutem obiektu transakcji, a ilo¶æ pieniêdzy, na któr± opiewa transakcja, jest warto¶ci±. > I podobnie z w³a¶cicielem. Krótko mówi±c "konto jest anonimowe" i > przechowuje jedynie swoje saldo (warto¶æ) oraz numer (to¿samo¶æ). Numer jest atrybutem obiektu (unikalnym, wiêc jest ¶ci¶le zwi±zany z to¿samo¶ci±), w³a¶ciciel te¿ jest obiektem (w bazie banku jest osobnym obiektem, który mo¿e byæ podmapowany do kilku kont). Saldo jest stanem konta, a warto¶æ salda to ilo¶æ pieniêdzy znajduj±cych siê na koncie. > Nie wiem, czy to ma sens, ale nie mo¿esz chyba wykluczyæ, ¿e w jakim¶ > tam systemie mo¿e mieæ. Niestety nie. Przykro mi. > > Czy ty w ogóle wiesz, co to jest "warto¶æ"? > Element ze zbioru (tu: typ, klasa). To znaczy? -- // _ ___ 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"
Re: Wartości i obiekty
Author: Marcin 'Qrczak'
Date: Sun, 11 Mar 2007 00:11
Date: Sun, 11 Mar 2007 00:11
171 lines
6695 bytes
6695 bytes
Dnia 10-03-2007, sob o godzinie 18:47 +0000, Sektor van Skijlen napisał(a): > > Jest jeszcze trzecia kategoria leżąca pomiędzy tymi dwiema: > > wskaźniki na singletony, czyli na jedyne obiekty danego rodzaju, > > np. true / false / nil. Te obiekty są niezmienialne, ale tożsamość > > tych obiektów jest dobrze zdefiniowana; rozróżnianie ich po tożsamości > > jest równoważne rozróżnianiu po cechach wewnętrznych. > > Nie tworzyłbym specjalnej kategorii dla tych obiektów. Zwykle można je traktować razem z wartościowymi. Różnica objawia się tylko wtedy, kiedy w języku mamy do dyspozycji operację jawnie porównującą dwa obiekty po tożsamości. Tę operację można uznać za niskopoziomową i rzadko się jej wprost używa, ale w wielu językach jest dostępna, bo może być tańsza od domyślnego porównania, a dla pewnego zbioru obiektów jest mu równoważna (Lisp: EQ, Scheme: eq?, Python: is, Kogut: Is, OCaml: ==). Na przykład w Pythonie porównanie "x is None" jest praktyczne, a "x is 5" nie jest. > > Jeśli spróbować dopasować do tego modelu C++, to się okaże, że zmienną > > C++ zawierającą obiekt można rozumieć na dwa sposoby: > > > a) Jako zmienialny obiekt, przywiązany na stałe do swojej nazwy. > > To tłumaczenie jest odpowiednie w przypadku obiektów z tożsamością, > > zwłaszcza złożonych, bo pozwala wymodelować możliwość zmiany > > indywidualnych pól obiektu z zachowaniem tożsamości całego obiektu. > > Takie obiekty są zwykle przekazywane przez referencje C++ albo > > wskaźniki C++, co odpowiada przekazaniu wskaźnika na obiekt > > w modelu, a więc odpowiada naturalnemu sposobowi przekazania > > wartości w modelu. > > > b) Jako zmienną zawierającą wartość, która sama jest niezmienialna. > > To tłumaczenie jest lepsze dla atomowych typów wartościowych, > > bo pozwala wymodelować wartość wyabstrahowaną od miejsca > > przechowywania. Takie obiekty są w C++ zwykle kopiowane, > > co odpowiada przekazaniu odczytanej bieżącej wartości zmiennej > > w modelu, czyli znowu jest naturalnym sposobem przekazania wartości, > > mimo że w C++ jest inne niż tamto. > > Szczerze mówiąc to nic z tego nie rozumiem. Bo opisałem odpowiedniki zmiennej w C++ językiem (ludzkim) przystosowanym do opisywania innych języków (programowania). Jesteś przyzwyczajony do języka (ludzkiego) przystosowanego do opisywania C++. Jeśli w C++ mamy zmienną zawierającą obiekt udostępniający jakieś metody (w tym metody zmieniające jego stan), to w innym języku odpowiednik tej konstrukcji wygląda z reguły na jeden z dwóch sposobów, zależnie od stylu, w jakim przeważnie wygodnie jest używać obiektów danego typu: a) Typowy przykład: tablica. Zmienna wskazuje na obiekt udostępniający analogiczne operacje jak w C++. Obiekt jest tworzony na stercie. Do tej zmiennej nie jest nigdy przypisywany wskaźnik na inny obiekt. Tam, gdzie w C++ obiekt jest przekazywany przez referencję, w innym języku przekazywana jest wartość tej zmiennej (wskazująca na ten obiekt). Tam, gdzie w C++ obiekt jest przekazywany przez wartość, w innym języku obiekt jest klonowany (czymś w rodzaju metody Clone). b) Typowy przykład: liczba. Zmienna wskazuje na niezmienialny obiekt innego języka reprezentujący bieżący stan obiektu C++. Metodom C++, które zmieniały stan obiektu, odpowiadają operacje zwracające nowy obiekt, który jest przypisywany z powrotem tej zmiennej. Tam, gdzie w C++ obiekt jest przekazywany przez wartość, w innym języku przekazywana jest bieżąca wartość zmiennej. Tam, gdzie w C++ obiekt jest przekazywany przez referencję, w innym języku przekazywana jest referencja na zmienną. > String zawsze powinien być traktowany jak wartość, natomiast wektor zawsze > jak obiekt. Zgodzę się, że zazwyczaj. Nie zgadzam się, że zawsze. A wektor znaków? Z jednej strony to jest wektor. Z drugiej strony to jest w zasadzie to samo, co string. Różnice są w dodatkowych metodach, ale one są raczej poboczne, nie wpływają na istotę rzeczy. > > Pisałem tutaj o zmienialnym stringu, zakładając, że to jest jedyny > > string w danym języku. Czyli kiedy złożony typ pełniący rolę typu > > wartościowego jest jednak zmienialny. Taka sytuacja jest kłopotliwa. > > Oj... nie bardzo to widzę. No i właśnie mówię, że to jest kłopotliwe. Lepiej tego unikać. W to C++ pasuje. W Perlu też; to jest jeden z nielicznych języków (obok Pascala, C i C++), który kopiuje zawartość stringa przy przypisaniu, choć przy przekazaniu jako argument funkcji formalnie już nie (ale w praktyce zwykle tak, bo większość funkcji zaczyna się od skopiowania argumentów do osobnych lokalnych zmiennych - specyfika Perla). Przykłady języków, które mają wyłącznie zmienialne stringi mimo paradygmatu, który do tego nie pasuje: Lisp, Scheme, OCaml, Ruby (czasem są zmienialne łącznie ze zmianą długości, a czasem nie). > > Mój model w wersji czystej wymaga zdecydowania się, który styl użycia > > jest tutaj dominujący. Pomieszanie styli grozi błędami aliasowania albo > > niepotrzebnymi kopiami. > > No właśnie - ale nie możesz zrobić tak, że w całym języku jeden model > obowiązuje wszystkie obiekty. Oczywiście, tego nie proponowałem. Byle był ustalony styl dla danego typu. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Marcin 'Qrczak'
Date: Sun, 11 Mar 2007 01:40
Date: Sun, 11 Mar 2007 01:40
143 lines
5771 bytes
5771 bytes
Dnia 10-03-2007, sob o godzinie 19:17 +0000, Sektor van Skijlen napisał(a): > Zrób sobie małą statystykę użycia takiego typu i ilość porównań, dla których > trafiasz na równość i dla których trafiasz na nierówność. Zrób statystykę, ile można stracić i ile można zaoszczędzić. Sprawa nie jest oczywista. Jest wiele czynników wpływających na opłacalność: statyczne bądź dynamiczne typowanie, statyczna wiedza kompilatora niekoniecznie wynikająca z systemu typów, reprezentacja obiektów czy zgoła wymagania semantyki operacji porównania w danym języku. Przykład. W OCamlu jest funkcja =, która porównuje zawartość dwóch obiektów tego samego, dowolnego typu. Porównuje głęboko, nie zważając na to, które fragmenty są zmienialne. Kompilator generuje specjalny kod dla pewnych typów (np. liczby różnego rodzaju albo typy wyliczeniowe). Jest też zmaterializowana w jednym miejscu uniwersalna funkcja porównująca, zaimplementowana w C, używana dla różnych złożonych typów oraz tam, gdzie typ nie jest statycznie znany (bo kod jest parametryzowany typem). Ta funkcja do niedawna zaczynała od porównania fizycznej reprezentacji argumentów, czyli albo wartości bezpośrednich, albo wskaźników. Jeśli były równe, to zwracała true bez wchodzenia do środka, a jeśli nie były równe, to dopiero sprawdzała, czy oba są wartościami bezpośrednimi albo oba wskaźnikami i czy mają ten sam numer konstruktora. Z punktu widzenia efektywności uznano, że warto. Zostało to zmienione z powodu typu float, który jest porównywany przez = zgodnie z arytmetyką IEEE: nan jest różne od samego siebie. Z tego wynika, że dowolna struktura zawierająca nan, np. lista [1.0; nan; 2.0], jest różna od samej siebie. Tymczasem w starej implementacji była równa albo różna w zależności od tego, czy była zaalokowana osobno, czy nie, co w przypadku listy nie powinno było mieć znaczenia. Co śmieszniejsze, ta sama samodzielna wartość nan była równa sobie albo nierówna w zależności od tego, czy miejsce aplikacji funkcji = było kompilowane ze świadomością, że argumenty są typu float (wtedy było generowane tylko zmiennoprzecinkowe porównanie zawartości), czy nie (wtedy używana była wspomniana uniwersalna implementacja, która najpierw porównywała adres). Tak więc zarzucono to z powodów semantycznych. Inny przykład. W Kogucie jest funkcja Is, która porównuje dwie wartości i z założenia jest najmniejszą relacją równoważności, która nie bierze pod uwagę fizycznej tożsamości tam gdzie nie musi (czyli przy większości obiektów niezmienialnych). Problemu z NaN nie ma, bo równość arytmetyczna, w której NaN jest różne od siebie, to osobna funkcja. Reprezentacja wartości jest taka, że małe liczby całkowite są oznaczone najmłodszym bitem równym 1, a wszystkie pozostałe wartości są wskaźnikami na obiekt, którego pierwsze słowo jest wskaźnikiem na tzw. deskryptor, którego jednym z pól jest wskaźnik na typ. Kompilator generuje specjalny kod dla aplikacji Is, jeśli jeden z argumentów jest znaną mu stałą. Poza tym jest jedna uniwersalna implementacja Is, która robi co następuje: 1. Jeśli wartości są fizycznie równe (taka sama mała liczba całkowita albo taki sam wskaźnik), to wynikiem jest True. 2. Jeśli któryś z argumentów jest małą liczbą całkowitą, to wynikiem jest False. 3. Jeśli wartości są różnych typów, to wynikiem jest False. 4. Wybierana i wykonywana jest implementacja Is zależna od typu (wspólnego dla obu argumentów), wyszukiwana w słowniku (standardowy mechanizm funkcji generycznych). Zauważmy, że 3 nie wprowadza dodatkowego kosztu, skoro tak czy siak czeka nas 4 (dzięki 3 w 4 wystarczy wziąć jeden typ), a 2 nie wprowadza dodatkowego kosztu, skoro czeka nas 3 (trzeba sprawdzić, czy dana wartość nie jest małą liczbą całkowitą, zanim sprawdzi się jej typ). W tej sytuacji punkt 1 narzuca się w sposób naturalny. Porównanie równych liczb całkowitych jest szybsze (wystarczy pierwszy punkt).. Porównanie różnych liczb całkowitych jest tak samo szybkie (dwa proste punkty potrzebne tak czy siak). Porównanie innych wartości jest albo nieznacznie wolniejsze (jedno dodatkowe porównanie, kiedy są już co najmniej dwa inne), albo znacznie szybsze (oszczędzenie punktów od 2 do 4 przy porównaniu np. Null z Null albo równych znaków mieszczących się w ISO-8859-1, a czasem i równych innych stringów, jeśli to ten sam obiekt). -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
Re: =?ISO-8859-2?Q?Warto¶ci?= i obiekty
Author: Sektor van Skijl
Date: Sun, 11 Mar 2007 15:29
Date: Sun, 11 Mar 2007 15:29
190 lines
8989 bytes
8989 bytes
Dnia Sun, 11 Mar 2007 00:11:42 +0100, Marcin 'Qrczak' Kowalczyk skrobie: > Dnia 10-03-2007, sob o godzinie 18:47 +0000, Sektor van Skijlen > napisa³(a): > > > Jest jeszcze trzecia kategoria le¿±ca pomiêdzy tymi dwiema: > > > wska¼niki na singletony, czyli na jedyne obiekty danego rodzaju, > > > np. true / false / nil. Te obiekty s± niezmienialne, ale to¿samo¶æ > > > tych obiektów jest dobrze zdefiniowana; rozró¿nianie ich po to¿samo¶ci > > > jest równowa¿ne rozró¿nianiu po cechach wewnêtrznych. > > > > Nie tworzy³bym specjalnej kategorii dla tych obiektów. > Zwykle mo¿na je traktowaæ razem z warto¶ciowymi. Ró¿nica objawia > siê tylko wtedy, kiedy w jêzyku mamy do dyspozycji operacjê jawnie > porównuj±c± dwa obiekty po to¿samo¶ci. Tê operacjê mo¿na uznaæ za > niskopoziomow± i rzadko siê jej wprost u¿ywa, ale w wielu jêzykach > jest dostêpna, bo mo¿e byæ tañsza od domy¶lnego porównania, a dla > pewnego zbioru obiektów jest mu równowa¿na (Lisp: EQ, Scheme: eq?, > Python: is, Kogut: Is, OCaml: ==). Na przyk³ad w Pythonie porównanie > "x is None" jest praktyczne, a "x is 5" nie jest. Qrczak - to wszystko prawda, ale to wci±¿ nie zmienia faktu: Obojêtnie, jak mamy zaimplementowany sposób porównania warto¶ci i to¿samo¶ci, obojêtnie te¿, czy typ jest warto¶ciowy, czy obiektowy, dla ka¿dego typu istnieje tylko i wy³±cznie jeden sensowny sposób porównania. Skoro tak, to nie potrzebujemy osobnych operatorów porównania - powinien byæ dostêpny jeden operator porównania. > > > Je¶li spróbowaæ dopasowaæ do tego modelu C++, to siê oka¿e, ¿e zmienn± > > > C++ zawieraj±c± obiekt mo¿na rozumieæ na dwa sposoby: > > > > > a) Jako zmienialny obiekt, przywi±zany na sta³e do swojej nazwy. > > > To t³umaczenie jest odpowiednie w przypadku obiektów z to¿samo¶ci±, > > > zw³aszcza z³o¿onych, bo pozwala wymodelowaæ mo¿liwo¶æ zmiany > > > indywidualnych pól obiektu z zachowaniem to¿samo¶ci ca³ego obiektu. > > > Takie obiekty s± zwykle przekazywane przez referencje C++ albo > > > wska¼niki C++, co odpowiada przekazaniu wska¼nika na obiekt > > > w modelu, a wiêc odpowiada naturalnemu sposobowi przekazania > > > warto¶ci w modelu. > > > > > b) Jako zmienn± zawieraj±c± warto¶æ, która sama jest niezmienialna. > > > To t³umaczenie jest lepsze dla atomowych typów warto¶ciowych, > > > bo pozwala wymodelowaæ warto¶æ wyabstrahowan± od miejsca > > > przechowywania. Takie obiekty s± w C++ zwykle kopiowane, > > > co odpowiada przekazaniu odczytanej bie¿±cej warto¶ci zmiennej > > > w modelu, czyli znowu jest naturalnym sposobem przekazania warto¶ci, > > > mimo ¿e w C++ jest inne ni¿ tamto. > > > > Szczerze mówi±c to nic z tego nie rozumiem. > Bo opisa³em odpowiedniki zmiennej w C++ jêzykiem (ludzkim) > przystosowanym do opisywania innych jêzyków (programowania). > Jeste¶ przyzwyczajony do jêzyka (ludzkiego) przystosowanego > do opisywania C++. Nie do koñca siê zgodzê, w szczególno¶ci nie zgodzê siê, ¿e opisa³e¶ to jêzykiem ludzkim :) > Je¶li w C++ mamy zmienn± zawieraj±c± obiekt udostêpniaj±cy jakie¶ metody > (w tym metody zmieniaj±ce jego stan), to w innym jêzyku odpowiednik tej > konstrukcji wygl±da z regu³y na jeden z dwóch sposobów, zale¿nie od > stylu, w jakim przewa¿nie wygodnie jest u¿ywaæ obiektów danego typu: > a) Typowy przyk³ad: tablica. > Zmienna wskazuje na obiekt udostêpniaj±cy analogiczne operacje jak > w C++. Obiekt jest tworzony na stercie. Do tej zmiennej nie jest > nigdy przypisywany wska¼nik na inny obiekt. Ale mówisz o tablicy surowej, tworzonej jako zmienna lokalna w funkcji. Pomówmy raczej o vectorze. > Tam, gdzie w C++ obiekt jest przekazywany przez referencjê, w innym > jêzyku przekazywana jest warto¶æ tej zmiennej (wskazuj±ca na ten > obiekt). Tam, gdzie w C++ obiekt jest przekazywany przez warto¶æ, > w innym jêzyku obiekt jest klonowany (czym¶ w rodzaju metody Clone). Tak - pod warunkiem, ¿e pozwala siê na klonowanie obiektów. > b) Typowy przyk³ad: liczba. > Zmienna wskazuje na niezmienialny obiekt innego jêzyka reprezentuj±cy > bie¿±cy stan obiektu C++. Metodom C++, które zmienia³y stan obiektu, > odpowiadaj± operacje zwracaj±ce nowy obiekt, który jest przypisywany > z powrotem tej zmiennej. Pod warunkiem, ¿e mamy mo¿liwo¶æ "zakodowania" przypisania do zmiennej trzymaj±cej ten niezmienialny obiekt. Tak zreszt± jest to w Javie i Javowe rozwi±zanie ma tylko jedn± wadê: operator porównania :). > Tam, gdzie w C++ obiekt jest przekazywany przez warto¶æ, w innym > jêzyku przekazywana jest bie¿±ca warto¶æ zmiennej. Tam, gdzie > w C++ obiekt jest przekazywany przez referencjê, w innym jêzyku > przekazywana jest referencja na zmienn±. A co z porównywaniem? > > String zawsze powinien byæ traktowany jak warto¶æ, natomiast wektor zawsze > > jak obiekt. > Zgodzê siê, ¿e zazwyczaj. Nie zgadzam siê, ¿e zawsze. Zgodzê siê co najwy¿ej, ¿e nie zawsze, tzn. wektor mo¿e s³u¿yæ jako szczegó³ implementacyjny jakiego¶ typu warto¶ciowego. Ale nie sam wektor, bo to jest mniej wiêcej co¶ takiego jak void* do przechowywania dynamicznych danych. > A wektor znaków? Z jednej strony to jest wektor. Z drugiej strony to > jest w zasadzie to samo, co string. Ró¿nica polega na tym, czym siê ró¿ni "to samo" od "w zasadzie to samo" ;) Nie, Qrczak. String to nie jest tablica znaków - jak ju¿ siê czepiamy skrzywionego my¶lenia, to i ja siê poczepiam: twoje my¶lenie jest skrzywione przez jêzyki, w których string jest reprezentowany przez listê znaków (jak np. Haskell). String charakteryzuje siê tym, ¿e posiada warto¶æ; napis jest po prostu jednym napisem, który mo¿e byæ taki sam jak inny lub ró¿ny od niego, napisy mo¿emy te¿ porz±dkowaæ po warto¶ci (bo maj± warto¶æ), "ten sam napis" oznacza nam napis sk³adaj±cy siê z dok³adnie takich samych znaków w tej samej kolejno¶ci. Vector natomiast jest zbiorem elementów - ich kolejno¶æ nie jest czêsto specjalnie istotna (je¶li ju¿, to najwy¿ej kwestie uporz±dkowany-nieuporz±dkowany), elementy czêsto przestawia siê w inne miejsce, wykonuje siê czêsto operacje na ka¿dym elemencie po kolei. W przypadku stringa te operacje s± w mniejszo¶ci, a sortowanie znaków w stringu uwa¿a³bym za powiew ezoteryki. To nie jest kwestia implementacji (string, vector), tylko kwestia logiki programu. Jasne, mo¿emy sobie obs³ugiwaæ napisy jako vector<char>, ale to bêd± dla nas i tak napisy (jêzyk C przecie¿ i tak obs³uguje napisy jako tablice znaków). Implementacja jest wiêc nieistotna - wa¿ne jest to, co to dla nas oznacza w programie. Dlatego dobre jêzyki programowania pozwalaj± na stworzenie osobnych typów, które maj± nawet wspólne podstawy implementacyjne, ale które logicznie oznaczaj± zupe³nie co innego. W³a¶nie dlatego, ¿e to narzuca nam sposób operowania takim typem. Mo¿na tablicê char'ów u¿ywaæ jako zbiór znaków i jako napis, oczywi¶cie. Ale wtedy trzeba samemu pamiêtaæ o tym, co jest czym i jak co mamy traktowaæ. Je¶li jêzyk jest s³aby i nie potrafi daæ mo¿liwo¶ci rozró¿nienia tych rzeczy po statycznym typie (jak w C), to musi jako¶ zapewniæ mo¿liwo¶æ alternatywnych sposobów porównañ za pomoc± osobnych operacji. > Ró¿nice s± w dodatkowych metodach, > ale one s± raczej poboczne, nie wp³ywaj± na istotê rzeczy. Dobrze, Qrczak, niech ci ju¿ bêdzie, bo w tym momencie rêce mi opad³y. > > > Pisa³em tutaj o zmienialnym stringu, zak³adaj±c, ¿e to jest jedyny > > > string w danym jêzyku. Czyli kiedy z³o¿ony typ pe³ni±cy rolê typu > > > warto¶ciowego jest jednak zmienialny. Taka sytuacja jest k³opotliwa. > > > > Oj... nie bardzo to widzê. > No i w³a¶nie mówiê, ¿e to jest k³opotliwe. Lepiej tego unikaæ. > W to C++ pasuje. Tak, ale w C++ zmiana stringa zmienia tylko t± zmienn±, która aktualnie przechowuje warto¶æ. Inaczej mówi±c, nadaje now± warto¶æ zmiennej. Mo¿na te¿ odnie¶æ siê czê¶ciowo do tego, ¿e niektóre implementacje stringa wspó³dziel± tablicê znaków. Wiêc dwie ró¿ne zmienne mog³yby wskazywaæ na ró¿ne tablice, co bardzo przypomina³oby wskazywanie na dwa obiekty przez dwie zmienne referencyjne. Ale w takim przypadku przyda³oby siê te¿ jakie¶ sprytne COW, które by powodowa³o, ¿e w razie zmiany przez jedn± z tych zmiennych, ka¿da z nich bêdzie mia³a od teraz w³asn± kopiê. Inaczej mówi±c, nawet je¶li jaka¶ zmienna wspó³dzieli obiekt tablicy z innymi zmiennymi, to modyfikacja tej zmiennej nie zmienia warto¶ci w pozosta³ych zmiennych (a jedynie traci z nimi powi±zanie). > Przyk³ady jêzyków, które maj± wy³±cznie zmienialne stringi mimo > paradygmatu, który do tego nie pasuje: Lisp, Scheme, OCaml, Ruby > (czasem s± zmienialne ³±cznie ze zmian± d³ugo¶ci, a czasem nie). Tzn. jak? Musisz jawnie skopiowaæ string, je¶li chcesz, ¿eby ¼ród³owy siê nie zmieni³? -- // _ ___ 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"
Re: Wartości i obiekty
Author: Marcin 'Qrczak'
Date: Sun, 11 Mar 2007 23:15
Date: Sun, 11 Mar 2007 23:15
158 lines
6139 bytes
6139 bytes
Dnia 11-03-2007, nie o godzinie 15:29 +0000, Sektor van Skijlen napisał(a): > Obojętnie, jak mamy zaimplementowany sposób porównania wartości i tożsamości, > obojętnie też, czy typ jest wartościowy, czy obiektowy, dla każdego typu > istnieje tylko i wyłącznie jeden sensowny sposób porównania. To jest prawie prawda. Po pierwsze, co tłumaczę od paru postów, zdarza się, że typ ma niejednoznaczny charakter i czasem jest używany w roli typu wartościowego, a czasem typu z tożsamością. Zgadzam się, że to jest kłopotliwe, ale to bywa faktem. Po drugie czasem (rzadko) chcemy porównać tożsamość obiektów typów wartościowych dla niskopoziomowych optymalizacji. Na przykład jeśli rekurencyjna funkcja przekształcająca drzewo ma tę własność, że dla wielu podfragmentów wynikiem jest sam argument, to można uniknąć alokacji węzła wyniku w sytuacji, kiedy wywołania rekurencyjne nic nie zmieniły i my też nie zamierzamy nic zmieniać. Przykład funkcji o tej własności: uproszczenie wyrażenia algebraicznego. Po trzecie są relacje, które - jeśli się uprzeć - można nazwać inaczej niż równość, ale potocznie są to jakieś odmiany równości. Na przykład sprawdzenie, czy dwa ciągi mają równe odpowiadające sobie elementy, bez sprawdzenia, czy te ciągi w ogóle są tego samego typu. Po czwarte tradycyjna równość zmiennoprzecinkowa nie jest relacją równoważności (z powodu NaN) ani nie jest zachowywana przez operacje arytmetyczne (z powodu -0.0). Jest więc powód, żeby traktować ją jako osobną operację niż podstawowa równość. A to jeszcze nie wszystko. > > a) Typowy przykład: tablica. > > > Zmienna wskazuje na obiekt udostępniający analogiczne operacje jak > > w C++. Obiekt jest tworzony na stercie. Do tej zmiennej nie jest > > nigdy przypisywany wskaźnik na inny obiekt. > > Ale mówisz o tablicy surowej, tworzonej jako zmienna lokalna w funkcji. > > Pomówmy raczej o vectorze. Miałem na myśli vector (tworzony jako zmienna lokalna w funkcji). > > w innym języku obiekt jest klonowany (czymś w rodzaju metody Clone). > > Tak - pod warunkiem, że pozwala się na klonowanie obiektów.. Zawsze "się pozwala", bo nie ma czego zabraniać - to jest operacja jak każda inna, jeśli się nie oczekuje, że będzie automatycznie dostępna dla dowolnego typu. > > b) Typowy przykład: liczba. > > > Zmienna wskazuje na niezmienialny obiekt innego języka reprezentujący > > bieżący stan obiektu C++. Metodom C++, które zmieniały stan obiektu, > > odpowiadają operacje zwracające nowy obiekt, który jest przypisywany > > z powrotem tej zmiennej. > > Pod warunkiem, że mamy możliwość "zakodowania" przypisania do zmiennej > trzymającej ten niezmienialny obiekt. Jasne; miałem na myśli imperatywną, przypisywalną zmienną. Słowo "zmienna" jest niestety wieloznaczne i część języków programowania, tak jak matematyka, używa go w znaczeniu lokalnej nazwy jakiejś wartości, niekoniecznie zmieniającej się w czasie. > > Tam, gdzie w C++ obiekt jest przekazywany przez wartość, w innym > > języku przekazywana jest bieżąca wartość zmiennej. Tam, gdzie > > w C++ obiekt jest przekazywany przez referencję, w innym języku > > przekazywana jest referencja na zmienną. > > A co z porównywaniem? Nie rozumiem pytania. Dla obiektów tej kategorii porównanie jest dość podstawową operacją, zdefiniowaną zależnie od typu. No i normalnie jest oferowane, najczęściej w formie wspólnego interfejsu dla różnych typów. > Nie, Qrczak. String to nie jest tablica znaków - jak już się czepiamy > skrzywionego myślenia, to i ja się poczepiam: twoje myślenie jest skrzywione > przez języki, w których string jest reprezentowany przez listę znaków (jak np. > Haskell). Etam. W C string też jest w zasadzie tablicą znaków, a w C++ mało do tego brakuje. Szablon basic_string jest nawet parametryzowany typem znaku. Ten typ ma trochę więcej wymagań niż typ elementu wektora, ale poza tym różnica jest mała. W Kogucie, podobnie jak w Pythonie i Perlu, w ogóle nie ma osobnego typu znakowego. Kiedy znak jest materializowany w programie, jest reprezentowany przez string długości 1. Na pewno więc string jako tablica znaków nie jest moim skrzywieniem. > > Przykłady języków, które mają wyłącznie zmienialne stringi mimo > > paradygmatu, który do tego nie pasuje: Lisp, Scheme, OCaml, Ruby > > (czasem są zmienialne łącznie ze zmianą długości, a czasem nie). > > Tzn. jak? Musisz jawnie skopiować string, jeśli chcesz, żeby źródłowy się nie > zmienił? Tak. Nie jest to aż tak błędogenne, jak mogłoby się wydawać, jeśli się stosuje konwencję, że zmienia się tylko te stringi, które się przed chwilą utworzyło. Czyli string jest w zasadzie traktowany jako typ niezmienialny, imperatywne jest tylko jego tworzenie. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
Re: =?ISO-8859-2?Q?Warto¶ci?= i obiekty
Author: Sektor van Skijl
Date: Mon, 12 Mar 2007 21:28
Date: Mon, 12 Mar 2007 21:28
250 lines
11777 bytes
11777 bytes
Dnia Sun, 11 Mar 2007 23:15:23 +0100, Marcin 'Qrczak' Kowalczyk skrobie: > Dnia 11-03-2007, nie o godzinie 15:29 +0000, Sektor van Skijlen > napisa³(a): > > Obojêtnie, jak mamy zaimplementowany sposób porównania warto¶ci i to¿samo¶ci, > > obojêtnie te¿, czy typ jest warto¶ciowy, czy obiektowy, dla ka¿dego typu > > istnieje tylko i wy³±cznie jeden sensowny sposób porównania. > To jest prawie prawda. > Po pierwsze, co t³umaczê od paru postów, zdarza siê, ¿e typ ma > niejednoznaczny charakter i czasem jest u¿ywany w roli typu > warto¶ciowego, a czasem typu z to¿samo¶ci±. Zgadzam siê, ¿e to > jest k³opotliwe, ale to bywa faktem. A ja równie¿ t³umaczê od paru postów, ¿e na tak± okoliczno¶æ powinny zostaæ stworzone osobne typy statyczne. To prawda, ¿e mo¿esz u¿ywaæ tego samego typu jêzyka jako logicznego typu warto¶ciowego i niewarto¶ciowego, tyle ¿e to sprowadza jêzyk do niskopoziomowego rozwi±zania, w którym tego samego typu mo¿na u¿ywaæ do przechowywania logicznie ró¿nych rzeczy. Je¶li mamy jêzyk taki, jak C, to rozumiem, ¿e za bardzo nie mamy wyj¶cia. Dlatego tam u¿ywa siê tego samego typu - tablicy char - jako ³añcucha tekstowego i jako tablicy o elementach typu char. Natomiast dla jêzyka wysokopoziomowego to po prostu wstyd, ¿eby nie zrobiæ tego na osobnych typach. Rozumieli to zarówno twórcy C++, jak i Javy, i C# (nb. Tcl-a te¿, dlatego te¿ tam trzeba stosowaæ pewne myki, ¿eby móc przekszta³ciæ napis na listê znaków). Najwyra¼niej nie zrozumieli tego twórcy jêzyków Haskell i D. Je¶li taki typ ma osobne specyfiki dla ró¿nych przypadków, to i tak przynajmniej jednej specyfiki zawsze trzyma siê jeden obiekt (czyli nie zmienia siê nagle z typu obiektowego w warto¶ciowy w trakcie dzia³ania). Je¶li tak, to mo¿na u¿yæ osobnych definicji typów dla ka¿dego obiektu u¿ywaj±cego okre¶lonej specyfiki. > Po drugie czasem (rzadko) chcemy porównaæ to¿samo¶æ obiektów typów > warto¶ciowych dla niskopoziomowych optymalizacji. Rozumiem - ale taka niskopoziomowa optymalizacja powinna byæ operacj± szczególnego rodzaju, byæ dostêpna tylko dla operacji bezpo¶rednio operuj±cych na takim typie (lub specjalnie do tego dozwolonych), a przynajmniej powinna byæ wykonywalna za pomoc± osobnych funkcji porównania. Nie chodzi mi przecie¿ o to, ¿eby ca³kowicie zabroniæ mo¿liwo¶ci sprawdzania to¿samo¶ci obiektów typów warto¶ciowych. Chodzi o to, ¿eby ka¿dy typ posiada³ operator porównania, który porównuje w sposób adekwatny do rodzaju typu. > Po trzecie s± relacje, które - je¶li siê uprzeæ - mo¿na nazwaæ inaczej > ni¿ równo¶æ, ale potocznie s± to jakie¶ odmiany równo¶ci. Na przyk³ad > sprawdzenie, czy dwa ci±gi maj± równe odpowiadaj±ce sobie elementy, bez > sprawdzenia, czy te ci±gi w ogóle s± tego samego typu. Mo¿na, owszem, ale to nie jest porównanie warto¶ci, tylko porównanie zawarto¶ci zbiorników (operacja specyficzna dla zbiornika, bo nie da siê takiej operacji uogólniæ na "po prostu obiekt"). Powinna byæ zatem dozwolona, ale jako specyficzna operacja, a nie porównanie. Dlaczego w C++ zbiorniki nie posiadaj± zdefiniowanego operatora porównania, tylko tego typu porównania wykonuje siê algorytmami equal i mismatch? > Po czwarte tradycyjna równo¶æ zmiennoprzecinkowa nie jest relacj± > równowa¿no¶ci (z powodu NaN) ani nie jest zachowywana przez operacje > arytmetyczne (z powodu -0.0). Jest wiêc powód, ¿eby traktowaæ j± jako > osobn± operacjê ni¿ podstawowa równo¶æ. Nie no równo¶æ warto¶ci zmiennoprzecinkowych to jest ju¿ osobna bajka. Jest to drobny wy³om w systemie typów warto¶ciowych/obiektowych. Problem jest w³a¶nie z tym NaN, bo gdyby nie to, to jeszcze na upartego zachowa³aby siê zasada, ¿e warto¶æ a skopiowana z b jest równa b. Nie wiem w tym momencie, czy typy zmiennoprzecinkowe mo¿na traktowaæ jak warto¶ci. Dla mnie najsensowniejszym rozwi±zaniem by³oby zdefiniowanie jako operatora porównania porównania "wewnêtrznego", czyli z zachowaniem zale¿no¶ci miêdzy przypisaniem a porównaniem. Natomiast osobno do tego nale¿a³oby stworzyæ funkcjê porównuj±c± dwie liczby zmiennoprzecinkowe z zadanym epsilonem. Ci, co wymy¶lili ten numer z NaN, najwyra¼niej nie zdawali sobie sprawy z tego, jakie zamieszanie tym zrobi±. Zastanawiam siê nawet, czy nie by³oby znacznie sensowniejsze uznanie liczb zmiennoprzecinkowych za typy niewarto¶ciowe. To¿samo¶æ przez obiekt lepiej by siê dla nich sprawdza³a. > A to jeszcze nie wszystko. No to co jeszcze? Przecie¿ mo¿na by do tej wyliczanki do³o¿yæ stringa, którego mo¿esz porównywaæ np. bez case'a, z pominiêciem znaków kontrolnych itp. Powtarzam: nie zaprzeczam, ¿e powinny byæ zdefiniowane ró¿ne metody porównywania dostêpne dla danego obiektu, ale powinna byæ zawsze JEDNA operacja najw³a¶ciwszego porównania zdefiniowana dla danego typu. > > > w innym jêzyku obiekt jest klonowany (czym¶ w rodzaju metody Clone). > > > > Tak - pod warunkiem, ¿e pozwala siê na klonowanie obiektów. > Zawsze "siê pozwala", bo nie ma czego zabraniaæ - to jest operacja jak > ka¿da inna, je¶li siê nie oczekuje, ¿e bêdzie automatycznie dostêpna > dla dowolnego typu. Niestety, bzdury opowiadasz. Istnieje co¶ takiego, jak unikalne warto¶ci - warto¶æ jednego pola, która w ka¿dym obiekcie musi byæ inna. Czêsto s± to nawet obiekty generowane na rzecz innych, istniej±cych obiektów. Efekt jest taki, ¿e ¿eby¶ móg³ poprawnie tworzyæ obiekt przez klonowanie, to musia³by¶ podczas klonowania uwzglêdniæ fakt, ¿e warto¶ci niektórych jego pól nie mog± byæ skopiowane, tylko musz± zostaæ wygenerowane na nowo. Czy taki obiekt bêdzie jeszcze klonem? Klonowanie zreszt± to nie jest taka prosta sprawa. Pamiêtam, jak w mudzie by³a funkcja klonuj±ca moba. Trzeba by³o tam uwzglêdniæ mnóstwo rzeczy: je¶li postaæ by³a wierzchowcem, to nowa postaæ by³a "nieosiod³ana". Je¶li postaæ dosiada³a wierzchowca, to nowa postaæ by³a tworzona na ziemi. Je¶li postaæ zajmowa³a mebel, to nowa postaæ musia³a równie¿ staæ obok (tzn. tak by³o po wniesieniu mojej poprawki do buga, bo poprzednio nowa postaæ by³a tworzona na tym samym meblu - autor najwyra¼niej zapomnia³, ¿e meble maj± te¿ swoj± pojemno¶æ i niekoniecznie dwie postacie bêd± mog³y siedzieæ na jednym krze¶le). Kolejnym problemem jest to, czy klonowanie postaci powinno poci±gaæ za sob± klonowanie posiadanych przez ni± przedmiotów, czy te¿ nowa postaæ ma byæ stworzona "na golasa" (nie pamiêtam ju¿, jak to rozwi±zano). Gdyby poci±gaæ za sob± tworzenie przedmiotów, to dodatkowo niektóre mudy maj± wprowadzon± ekonomiê - czyli takie sklonowanie poci±ga za sob± dodatkowo deflacjê. I tak mo¿na by wyliczaæ bez koñca. Co wiêcej, czêsto ¼ród³em danych dla tworzenia nowego obiektu s± jakie¶ specyficzne dane, które trzeba odpowiednio pobraæ (byæ mo¿e zarejestrowaæ, skojarzyæ z czym¶). W takim przypadku nie da siê stworzyæ obiektu na podstawie danych z innego obiektu, bo dane, które posiada ten hipotetyczny obiekt ¼ród³owy s± przygotowane tylko i wy³±cznie dla niego. Jak ty sobie wyobra¿asz np. sklonowanie obiektu oznaczaj±cego plik, gniazdo, sesjê, czy zbiornik w³a¶cicielski (zbiornik z dynamicznie tworzonymi obiektami, które zbiornik posiada na w³asno¶æ, tzn. usuwa je razem ze sob±)? Wiêc co oznacza "zawsze siê pozwala"? Nie mówi±c o tym, ¿e w dalszej czê¶ci zdania twierdzisz, ¿e mo¿na zabroniæ, wiêc nie rozumiem... > > > b) Typowy przyk³ad: liczba. > > > > > Zmienna wskazuje na niezmienialny obiekt innego jêzyka reprezentuj±cy > > > bie¿±cy stan obiektu C++. Metodom C++, które zmienia³y stan obiektu, > > > odpowiadaj± operacje zwracaj±ce nowy obiekt, który jest przypisywany > > > z powrotem tej zmiennej. > > > > Pod warunkiem, ¿e mamy mo¿liwo¶æ "zakodowania" przypisania do zmiennej > > trzymaj±cej ten niezmienialny obiekt. > Jasne; mia³em na my¶li imperatywn±, przypisywaln± zmienn±. S³owo > "zmienna" jest niestety wieloznaczne i czê¶æ jêzyków programowania, > tak jak matematyka, u¿ywa go w znaczeniu lokalnej nazwy jakiej¶ > warto¶ci, niekoniecznie zmieniaj±cej siê w czasie. Wiem, o co chodzi ze zmienn± w obu przypadkach. Problem tylko w tym, czy jêzyk pozwala zrobiæ jaki¶ trik, który zakoduje operacjê modyfikuj±c± obiekt tak, ¿eby wygl±da³a jak modyfikuj±ca, a w rzeczywisto¶ci bêdzie tworzyæ now± kopiê obiektu. > > > Tam, gdzie w C++ obiekt jest przekazywany przez warto¶æ, w innym > > > jêzyku przekazywana jest bie¿±ca warto¶æ zmiennej. Tam, gdzie > > > w C++ obiekt jest przekazywany przez referencjê, w innym jêzyku > > > przekazywana jest referencja na zmienn±. > > > > A co z porównywaniem? > Nie rozumiem pytania. Dla obiektów tej kategorii porównanie jest do¶æ > podstawow± operacj±, zdefiniowan± zale¿nie od typu. No i normalnie jest > oferowane, najczê¶ciej w formie wspólnego interfejsu dla ró¿nych typów. No w³a¶nie. A co z implementacj±? > > Nie, Qrczak. String to nie jest tablica znaków - jak ju¿ siê czepiamy > > skrzywionego my¶lenia, to i ja siê poczepiam: twoje my¶lenie jest skrzywione > > przez jêzyki, w których string jest reprezentowany przez listê znaków (jak np. > > Haskell). > Etam. W C string te¿ jest w zasadzie tablic± znaków, Ale Haskel, w odró¿nieniu od C, nie jest jêzykiem niskopoziomowym, z siermiê¿nymi w³a¶ciwo¶ciami umo¿liwiaj±cymi ledwie co zrobienie struktur, ¿eby jako¶ operowaæ w³asnymi typami. > a w C++ ma³o do > tego brakuje. Nawet je¶li mo¿na trochê ponaci±gaæ fakty, ¿eby to stwierdziæ, to nie zmienia faktu, ¿e jednak zrobiono do tego osobne typy. > Szablon basic_string jest nawet parametryzowany typem > znaku. Complex te¿ jest parametryzowany typem warto¶ci zmiennoprzecinkowej, i co z tego? > Ten typ ma trochê wiêcej wymagañ ni¿ typ elementu wektora, ale > poza tym ró¿nica jest ma³a. Ró¿nica jest zasadnicza. Gdyby nie to, nikt by siê nie sili³ na robienie osobnego typu dla stringa i vectora. Popatrz na jêzyk D - tam nie ma osobnego typu dla stringa, a string jest jednocze¶nie tablic± znaków (czyli, inaczej mówi±c, tablica znaków posiada ca³± funkcjonalno¶æ potrzebn± dla stringa). > W Kogucie, podobnie jak w Pythonie i Perlu, w ogóle nie ma osobnego > typu znakowego. Kiedy znak jest materializowany w programie, jest > reprezentowany przez string d³ugo¶ci 1. W Tcl-u te¿ tak jest, wiêc to chyba nic niezwyk³ego jak na jêzyk skryptowy. > Na pewno wiêc string jako > tablica znaków nie jest moim skrzywieniem. Rozumiem, ¿e musisz siê jako¶ broniæ ;). Ale na powa¿nie - fakt, ¿e w wielu jêzykach string jest to¿samy z tablic± znaków, uwa¿am za pomy³kê. Tablica znaków jest czym¶ koncepcyjnie innym od stringa, a je¶li co¶ jest koncepcyjnie inne, to system typów powinien pozwalaæ na wyra¿enie tego osobnym typem. Jêzyk, który tego nie ma, ma "nalecia³o¶ci asemblerowe". > > > Przyk³ady jêzyków, które maj± wy³±cznie zmienialne stringi mimo > > > paradygmatu, który do tego nie pasuje: Lisp, Scheme, OCaml, Ruby > > > (czasem s± zmienialne ³±cznie ze zmian± d³ugo¶ci, a czasem nie). > > > > Tzn. jak? Musisz jawnie skopiowaæ string, je¶li chcesz, ¿eby ¼ród³owy siê nie > > zmieni³? > Tak. Nie jest to a¿ tak b³êdogenne, jak mog³oby siê wydawaæ, je¶li siê > stosuje konwencjê, ¿e zmienia siê tylko te stringi, które siê przed > chwil± utworzy³o. Ale¿ jaja sobie robisz. Nie jest to a¿ tak b³êdogenne, je¶li siê pamiêta. Nie zapominaj, ¿e bardzo czêsto u¿ywasz tego argumentu przeciwko C++. > Czyli string jest w zasadzie traktowany jako typ > niezmienialny, imperatywne jest tylko jego tworzenie. Bardzo dobrze - ale niech w takim razie jêzyk sam zadba o to, ¿eby tego stringa nie da³o siê zmieniæ po jego utworzeniu. -- // _ ___ 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"
Re: =?ISO-8859-2?Q?Warto¶ci?= i obiekty
Author: Sektor van Skijl
Date: Tue, 13 Mar 2007 08:43
Date: Tue, 13 Mar 2007 08:43
16 lines
641 bytes
641 bytes
Dnia Mon, 12 Mar 2007 21:28:52 +0000 (UTC), Sektor van Skijlen skrobie: > > Szablon basic_string jest nawet parametryzowany typem > > znaku. > Complex te¿ jest parametryzowany typem warto¶ci zmiennoprzecinkowej, i co z > tego? Zapomnia³em dopisaæ: Dlaczego complex ma swój w³asny osobny typ, zamiast ¿eby u¿ywa³o siê do tego celu np. pair<double,double> ? -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Tue, 13 Mar 2007 19:24
Date: Tue, 13 Mar 2007 19:24
221 lines
8119 bytes
8119 bytes
Sektor van Skijlen wrote: >> > Portfel nie jest typem warto¶ciowym. >> > >> > Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu, >> > podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i >> > materia³, z którego go wykonano. > >> I w _ka¿dym_ systemie tak to modelujesz? Z pe³n± otoczk±? Piêkny przyk³ad >> wzorca "swiss army knife". > > Nie u¿ywaj pojêæ, których znaczenia nie rozumiesz. Nie czyñ za³o¿eñ, na które nie masz dowodów. > Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ > pieni±dze, laptopy, meble, samochody, kontenery i elektrownie. Nie. Swiss army knife oznacza, ¿e modelujesz wszystkie elementy rzeczywisto¶ci czy tego wymaga system czy nie. Dlatego nie ma np. uniwersalnej implementacji portfela, która jest dobra w ka¿dym systemie. Gdyby tak by³o, jak grzyby po deszczu powstawa³yby biblioteki, które implementuj± obiekty naszej codzienno¶ci. > Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel nie > mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ jeszcze wiele > innych stanów i atrytbutów. Wychodz±c z tego za³o¿enia stanem "obiektu" "klasy" int jest np. 2. Stan ten mo¿na zmieniæ "funkcj±" zmiany stanu, np. ++. Kto z nas nie rozró¿nia warto¶ci od stanu? > >> > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor >> > mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany >> > tam kod koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z >> > ka¿dej kartki najpierw sprawdziæ, czy te obie kartki to czasem nie jest >> > jedna i ta sama kartka. Jaki to ma sens? > >> Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: data >> naniesienia, technika wykonania i stopieñ nas³onecznienia, które >> pozwalaj± obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê >> porównaæ dwóch "czerwonych". Odsy³am do ekspertów - lakierników >> samochodowych. > > Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o > kolorze. Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz > przypadkiem te¿ nie stanem) lakieru. Ja tylko poszed³em Twoj± logik±. Zwa¿, ¿e w systemie, o którym pisa³em przy portfelu nie wspomina³em o istnieniu kart kredytowych. > No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz siê i > zg³osisz za tydzieñ? Do kogo mia³bym siê zg³osiæ? > >> >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a >> >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same" >> >> a wiêc na pewno "takie same" obiekty. >> > >> > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej >> > bêdzie wylot. > >> W operatorze porównania? Nie s±dzê... > > W operatorze przypisania. Co mia³oby sprawiæ "wylot" w operatorze przypisania? >> > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie. > >> W pewnych przypadkach mo¿e tak byæ. > > Statystycznie jest to 99% przypadków. Statystycznie, to ja bijê swoj± ¿onê co miesi±c. Ty, je¶li jeste¶ ¿onaty równie¿. Takie szacunki trzeba robiæ dla konkretnych klas a nie generalizowaæ. >> Implementuj±c operator warto >> oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów. > > Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla > których trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ. > > Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez (...) > > Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e ten > przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê, ¿e > da³oby siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to nie > ma wiêkszego znaczenia. Nie bêdê ani analizowa³ Twojego przyk³adu, ani mu zaprzecza³. Zak³adam, ¿e jest s³uszny. To jednak tylko przyk³ad, z którego do sformu³owania regu³y jeszcze daleko. > W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania analizy, > która dowiedzie, czy to siê nam op³aca, czy nie. Ty przyjmujesz "w > ciemno", ¿e sprawdzanie najpierw to¿samo¶ci bêdzie zawsze bardziej > op³acalne. W ostateczno¶ci zgadzasz siê nawet, ¿e "najczê¶ciej". Ty dla odmiany uwa¿asz, ¿e najczê¶ciej nie. Na razie jednak nie potrafisz udowodniæ dlaczego Twoja teza jest lepsza od mojej. > No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i > oszacuj ilo¶æ porównañ trafionych i nietrafionych w typowych algorytmach, > które go u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym rozmawiamy. Nie chodzi o sam typ, tylko kontekst u¿ycia. > >> Generalnie jednak - nie zgadzam siê. > > Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie potrafiê > to uzasadniæ. W odró¿nieniu od Ciebie unikam jednoznacznych stwierdzeñ na temat swoich umiejêtno¶ci. Pozwalam to oceniæ innym. Równie¿ Tobie, choæ przyznam, ¿e nie odbieram tych ocen zbyt serio. Daj szansê innym pochwaliæ Twoje umiejêtno¶ci. Mo¿e kiedy¶ to nast±pi. >> >> "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku >> >> szablonów, które wed³ug mojej praktyki z regu³y s± po prostu >> >> przeznaczone dla obiektów oferuj±cych okre¶lony interfejs. I innych >> >> ograniczeñ w ich u¿yciu w³a¶ciwie nie ma. >> > >> > Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿ >> > typy obiektowe. > >> Znowu ogólnik: "zwykle"... "Sprzedajesz" nam teoriê, która ma dzia³aæ w >> praktyce, u³atwiaæ j±. Chcia³by¶, ¿eby Twój samochód "zwykle" dzia³a³? > > Oczywi¶cie teoretycznie mo¿e istnieæ taki wzorzec, który typom nie stawia > ¿adnych wymagañ, ale w praktyce nie spotka³em siê z takim. > > Wymagania co do typów zawsze okre¶laj± poszczególne operacje, które na > typie mo¿na wykonaæ. I te operacje ¶wiadcz± te¿ o tym, czy typ jest > warto¶ciowy, czy nie. > > Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym. > Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym > nastêpuj±ce wymagania wzglêdem typu: > - przypisywalny > - kopiowalny > - domy¶lnie-konstruowalny Rozumiem, ¿e je¶li stworzê sobie jaki¶ widget, powiedzmy combo-box, który spe³nia powy¿sze wymagania, to nie bêdê móg³, go przechowywaæ w std::list, bo pogwa³cê Twoj± teoriê? >> >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z >> >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ. >> > >> >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo. >> > >> > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ) >> > Oraz obiekt: historia transakcji >> > Oraz... > >> Jak wy¿ej: zale¿y od kontekstu. > > Nic nie zale¿y od ¿adnego kontekstu. > > Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest > obiektem. Niepotrzebnie wi±¿esz terminy z ¿ycia (stan konta) z terminami informatycznymi (stan obiektu). Osobom z ma³ym do¶wiadczeniem to siê czêsto zdarza, nie przejmuj siê. > >> Mo¿emy nie wi±zaæ obiektów transakcji do >> konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do >> konta. > > Ale co to ma do rzeczy? To, ¿e obiekt konto nie musi przechowywaæ historii, je¶li tylko zechcê tak to zamodelowaæ. > > Transakcja te¿ jest obiektem, tzw. "warto¶æ transakcji" jest atrybutem > obiektu transakcji, a ilo¶æ pieniêdzy, na któr± opiewa transakcja, jest > warto¶ci±. Otó¿ to! > >> I podobnie z w³a¶cicielem. Krótko mówi±c "konto jest anonimowe" i >> przechowuje jedynie swoje saldo (warto¶æ) oraz numer (to¿samo¶æ). > > Numer jest atrybutem obiektu (unikalnym, wiêc jest ¶ci¶le zwi±zany z > to¿samo¶ci±), w³a¶ciciel te¿ jest obiektem (w bazie banku jest osobnym > obiektem, który mo¿e byæ podmapowany do kilku kont). Saldo jest stanem > konta, a warto¶æ salda to ilo¶æ pieniêdzy znajduj±cych siê na koncie. Dlaczego "ilo¶æ" nie jest wed³ug Ciebie "warto¶ci±"? >> Nie wiem, czy to ma sens, ale nie mo¿esz chyba wykluczyæ, ¿e w jakim¶ >> tam systemie mo¿e mieæ. > > Niestety nie. Przykro mi. Cieszê siê, ¿e choæ raz przyznajesz mi racjê i nie próbujesz tego wykluczyæ. > >> > Czy ty w ogóle wiesz, co to jest "warto¶æ"? > >> Element ze zbioru (tu: typ, klasa). > > To znaczy? Odsy³am do ksi±¿ki "Matematyka dla klas drugich". -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Wed, 14 Mar 2007 00:13
Date: Wed, 14 Mar 2007 00:13
299 lines
11858 bytes
11858 bytes
Dnia Tue, 13 Mar 2007 19:24:26 +0100, Mariusz Lotko skrobie: > Sektor van Skijlen wrote: > >> > Portfel nie jest typem warto¶ciowym. > >> > > >> > Ilo¶æ pieniêdzy w portfelu jest jedynie jednym ze stanów tego obiektu, > >> > podobnie jak ilo¶æ kart kredytowych w ¶rodku, kolor portfela i > >> > materia³, z którego go wykonano. > > > >> I w _ka¿dym_ systemie tak to modelujesz? Z pe³n± otoczk±? Piêkny przyk³ad > >> wzorca "swiss army knife". > > > > Nie u¿ywaj pojêæ, których znaczenia nie rozumiesz. > Nie czyñ za³o¿eñ, na które nie masz dowodów. > > Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ > > pieni±dze, laptopy, meble, samochody, kontenery i elektrownie. > Nie. Swiss army knife oznacza, ¿e modelujesz wszystkie elementy > rzeczywisto¶ci czy tego wymaga system czy nie. Nie wiem, jak ty, ale ja pojêcie "swiss army knife" znam jako jeden z b³êdów OO, który polega na stworzeniu klasy o zbyt du¿ym zakresie odpowiedzialno¶ci. Dok³adno¶æ modelowania to zupe³nie inna sprawa. Zreszt±, je¶li dla ciebie programowanie obiektowe jest modelowaniem rzeczywisto¶ci, to obawiam siê, ¿e mo¿emy nasz± dyskusjê wznowiæ za parê lat, jak bêdziesz ju¿ mówi³ jêzykiem w³asnego do¶wiadczenia, a nie ksi±¿kowym. (Na marginesie: to bardzo dobrze, ¿e literatura do OO twierdzi, ¿e programowanie obiektowe jest modelowaniem rzeczywisto¶ci. Tak bowiem nale¿y t± sprawê t³umaczyæ pocz±tkuj±cym. Im wiêcej jednak cz³owiek programuje obiektowo, tym bardziej siê przekonuje, ¿e to nie ma nic wspólnego z prawd±. To jest jeden ze znaków rozpoznawczych, czy kto¶ potrafi my¶leæ samodzielnie rzeczywi¶cie dysponuje do¶wiadczeniem zawodowym, czy recytuje z pamiêci wiedzê ksi±¿kow±.) Cofaj±c jednak t± ca³± dygresjê, któr± nie wiem po co wprowadzi³e¶ - poda³em ci tylko przyk³ad, dlaczego portfel nie mo¿e byæ typem warto¶ciowym. Je¶li nie zrozumia³e¶ nadal, to wyt³umaczê ci bardziej ³opatologicznie: portfel zawieraj±cy tyle samo pieniêdzy, to nie ten sam portfel (mówiê tak, bo twierdzi³e¶, ¿e ilo¶æ pieniêdzy mo¿e byæ warto¶ci± potrfela). > > Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel nie > > mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ jeszcze wiele > > innych stanów i atrytbutów. > Wychodz±c z tego za³o¿enia stanem "obiektu" "klasy" int jest np. 2. Stan > ten mo¿na zmieniæ "funkcj±" zmiany stanu, np. ++. > Kto z nas nie rozró¿nia warto¶ci od stanu? int x = 2; int y = 2; Powiedz mi teraz, czy "x jest y". > >> > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu kolor > >> > mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru zapisany > >> > tam kod koloru jest ten sam. Ty chcesz, ¿eby przed odczytaniem numeru z > >> > ka¿dej kartki najpierw sprawdziæ, czy te obie kartki to czasem nie jest > >> > jedna i ta sama kartka. Jaki to ma sens? > > > >> Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: data > >> naniesienia, technika wykonania i stopieñ nas³onecznienia, które > >> pozwalaj± obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê > >> porównaæ dwóch "czerwonych". Odsy³am do ekspertów - lakierników > >> samochodowych. > > > > Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o > > kolorze. Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz > > przypadkiem te¿ nie stanem) lakieru. > Ja tylko poszed³em Twoj± logik±. Zwa¿, ¿e w systemie, o którym pisa³em > przy portfelu nie wspomina³em o istnieniu kart kredytowych. Nie poszed³e¶ moj± logik±. Mówi³em o kolorze, a ty wzi±³e¶ sobie nie wiem po co lakier samochodowy. Podobnie typem warto¶ciowym mog± byæ "pieni±dze". Ale nie kieszeñ, portfel, konto, sejf, czy gdzie to tam jeszcze chcesz przechowywaæ. > > No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz siê i > > zg³osisz za tydzieñ? > Do kogo mia³bym siê zg³osiæ? No có¿, wydawa³o mi siê, ¿e ka¿dy, kto studiowa³, s³ysza³ to s³ynne okre¶lenie. W czym¶ siê widaæ pomyli³em. > >> >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a > >> >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te same" > >> >> a wiêc na pewno "takie same" obiekty. > >> > > >> > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej > >> > bêdzie wylot. > > > >> W operatorze porównania? Nie s±dzê... > > > > W operatorze przypisania. > Co mia³oby sprawiæ "wylot" w operatorze przypisania? Sprawdzenie, czy nie przypisujemy samego siebie. Fakt, ¿e musisz u¿yæ operatora porównania dla to¿samo¶ci jest przykr± konieczno¶ci±, bo bez tego usun±³by¶ czê¶æ obiektu, z którego za chwilê masz zamiar czytaæ. > >> > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie. > > > >> W pewnych przypadkach mo¿e tak byæ. > > > > Statystycznie jest to 99% przypadków. > Statystycznie, to ja bijê swoj± ¿onê co miesi±c. Ty, je¶li jeste¶ ¿onaty > równie¿. Takie szacunki trzeba robiæ dla konkretnych klas a nie > generalizowaæ. No widzisz. A ja mogê sobie pozwoliæ na generalizacjê. Chodzi o bardzo prost± rzecz: jakiej wielko¶ci jest zwykle typ warto¶ciowy? Niewielkiej. Musi byæ niewielki, bo im wiêkszy, tym wiêcej zasobów zajmuje jego warto¶æ, d³u¿ej siê kopiuje, a i porównanie warto¶ci - dosæ czêsta operacja - trwa do¶æ d³ugo. Dlatego w³a¶nie typy warto¶ciowe robi siê z za³o¿enia JAK NAJMNIEJSZE - w³a¶nie po to, ¿eby te operacje by³y jak najszybsze. Skoro istnieje taka presja na obiekty warto¶ciowe, to gdzie masz w takim razie pole dla obiektów, w których porównanie mo¿na "przyspieszyæ" poprzez najpierw sprawdzanie to¿samo¶ci? > >> Implementuj±c operator warto > >> oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów. > > > > Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla > > których trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ. > > > > Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez > (...) > > > > Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e ten > > przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê, ¿e > > da³oby siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to nie > > ma wiêkszego znaczenia. > Nie bêdê ani analizowa³ Twojego przyk³adu, ani mu zaprzecza³. Zak³adam, > ¿e jest s³uszny. To jednak tylko przyk³ad, z którego do sformu³owania > regu³y jeszcze daleko. To by³ przyk³ad wykonania analizy, który pokaza³, ¿e siê nie op³aca. Czy jeste¶w stanie podaæ mi kontrprzyk³ad - czyli taki, który udowodni, ¿e siê op³aca? > > W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania analizy, > > która dowiedzie, czy to siê nam op³aca, czy nie. Ty przyjmujesz "w > > ciemno", ¿e sprawdzanie najpierw to¿samo¶ci bêdzie zawsze bardziej > > op³acalne. W ostateczno¶ci zgadzasz siê nawet, ¿e "najczê¶ciej". > Ty dla odmiany uwa¿asz, ¿e najczê¶ciej nie. Na razie jednak nie potrafisz > udowodniæ dlaczego Twoja teza jest lepsza od mojej. Potrafiê, tylko ty nie potrafisz jej zrozumieæ, albo uparcie zaprzeczasz faktom. Moja teza jest lepsza, bo jest oparta na rzetelnej analizie (nb. analiza Qrczaka równie¿). Twoja teza, ¿e to jest "oczywiste, ¿e tak siê powinno zawsze robiæ" nie jest poparta niczym. > > No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i > > oszacuj ilo¶æ porównañ trafionych i nietrafionych w typowych algorytmach, > > które go u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym rozmawiamy. > Nie chodzi o sam typ, tylko kontekst u¿ycia. Brawo! Zatem s³ucham. > >> Generalnie jednak - nie zgadzam siê. > > > > Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie potrafiê > > to uzasadniæ. > W odró¿nieniu od Ciebie unikam jednoznacznych stwierdzeñ na temat swoich > umiejêtno¶ci. Z t± "oczywisto¶ci±", ¿e operator porównania powinien najpierw sprawdziæ to¿samo¶æ, niespecjalnie ci to wysz³o. > Pozwalam to oceniæ innym. Równie¿ Tobie, choæ przyznam, ¿e > nie odbieram tych ocen zbyt serio. > Daj szansê innym pochwaliæ Twoje umiejêtno¶ci. Mo¿e kiedy¶ to nast±pi. Ju¿ nast±pi³o, o to siê nie martw. > >> >> "Prawdopodobnie" to dla mnie trochê za ma³o. Szczególnie w przypadku > >> >> szablonów, które wed³ug mojej praktyki z regu³y s± po prostu > >> >> przeznaczone dla obiektów oferuj±cych okre¶lony interfejs. I innych > >> >> ograniczeñ w ich u¿yciu w³a¶ciwie nie ma. > >> > > >> > Tak, dok³adnie. Ale typy warto¶ciowe zwykle maj± inny interfejs, ni¿ > >> > typy obiektowe. > > > >> Znowu ogólnik: "zwykle"... "Sprzedajesz" nam teoriê, która ma dzia³aæ w > >> praktyce, u³atwiaæ j±. Chcia³by¶, ¿eby Twój samochód "zwykle" dzia³a³? > > > > Oczywi¶cie teoretycznie mo¿e istnieæ taki wzorzec, który typom nie stawia > > ¿adnych wymagañ, ale w praktyce nie spotka³em siê z takim. > > > > Wymagania co do typów zawsze okre¶laj± poszczególne operacje, które na > > typie mo¿na wykonaæ. I te operacje ¶wiadcz± te¿ o tym, czy typ jest > > warto¶ciowy, czy nie. > > > > Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym. > > Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym > > nastêpuj±ce wymagania wzglêdem typu: > > - przypisywalny > > - kopiowalny > > - domy¶lnie-konstruowalny > Rozumiem, ¿e je¶li stworzê sobie jaki¶ widget, powiedzmy combo-box, który > spe³nia powy¿sze wymagania, to nie bêdê móg³, go przechowywaæ w std::list, > bo pogwa³cê Twoj± teoriê? Nie. Bo jak wykonasz na nim algorytm std::remove, to zdrowo siê zdziwisz, co po tym powsta³o. > >> >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z > >> >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ. > >> > > >> >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo. > >> > > >> > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ) > >> > Oraz obiekt: historia transakcji > >> > Oraz... > > > >> Jak wy¿ej: zale¿y od kontekstu. > > > > Nic nie zale¿y od ¿adnego kontekstu. > > > > Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest > > obiektem. > Niepotrzebnie wi±¿esz terminy z ¿ycia (stan konta) z terminami > informatycznymi (stan obiektu). Osobom z ma³ym do¶wiadczeniem to siê > czêsto zdarza, nie przejmuj siê. Parafrazuj±c, "Skoñczy³ siê czas argumentów. Teraz jest czas inwektyw". A mo¿e tak co¶ do tematu? > >> Mo¿emy nie wi±zaæ obiektów transakcji do > >> konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do > >> konta. > > > > Ale co to ma do rzeczy? > To, ¿e obiekt konto nie musi przechowywaæ historii, je¶li tylko zechcê tak > to zamodelowaæ. No mo¿e, i nadal, co z tego? > > > > Transakcja te¿ jest obiektem, tzw. "warto¶æ transakcji" jest atrybutem > > obiektu transakcji, a ilo¶æ pieniêdzy, na któr± opiewa transakcja, jest > > warto¶ci±. > Otó¿ to! No w³a¶nie. Wiêc co tu mo¿e, a co nie mo¿e byæ warto¶ci±? > >> I podobnie z w³a¶cicielem. Krótko mówi±c "konto jest anonimowe" i > >> przechowuje jedynie swoje saldo (warto¶æ) oraz numer (to¿samo¶æ). > > > > Numer jest atrybutem obiektu (unikalnym, wiêc jest ¶ci¶le zwi±zany z > > to¿samo¶ci±), w³a¶ciciel te¿ jest obiektem (w bazie banku jest osobnym > > obiektem, który mo¿e byæ podmapowany do kilku kont). Saldo jest stanem > > konta, a warto¶æ salda to ilo¶æ pieniêdzy znajduj±cych siê na koncie. > Dlaczego "ilo¶æ" nie jest wed³ug Ciebie "warto¶ci±"? Widzê, ¿e ca³kiem siê ju¿ pogubi³e¶ ;) Oczywi¶cie, ¿e jest. > >> > Czy ty w ogóle wiesz, co to jest "warto¶æ"? > > > >> Element ze zbioru (tu: typ, klasa). > > > > To znaczy? > Odsy³am do ksi±¿ki "Matematyka dla klas drugich". Có¿, osobliwy masz wybór literatury do nauki programowania, ale to ju¿ nie moja sprawa. -- // _ ___ 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"
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Mariusz Lotko
Date: Thu, 15 Mar 2007 06:12
Date: Thu, 15 Mar 2007 06:12
323 lines
12310 bytes
12310 bytes
Sektor van Skijlen wrote: >> > Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ >> > pieni±dze, laptopy, meble, samochody, kontenery i elektrownie. > >> Nie. Swiss army knife oznacza, ¿e modelujesz wszystkie elementy >> rzeczywisto¶ci czy tego wymaga system czy nie. > > Nie wiem, jak ty, ale ja pojêcie "swiss army knife" znam jako jeden z > b³êdów OO, który polega na stworzeniu klasy o zbyt du¿ym zakresie > odpowiedzialno¶ci. Ja te¿. Dlaczego uwa¿asz, ¿e modelowanie wiêkszej czê¶ci rzeczywisto¶ci od wymaganej nie jest "zbyt du¿ym zakresem odpowiedzialno¶ci"? > Dok³adno¶æ modelowania to zupe³nie inna sprawa. Inny bêdzie poziom szczegó³owo¶ci klasy Samochód w kartotece samochodów w Urzêdzie Miasta, a inny w kartotece warsztatu samochodowego. Mój kolega jaki¶ czas temu wymy¶li³ dobry polski odpowiednik swiss army knife: "przyda¶". Bierze siê to z podej¶cia "przyda siê, zaimplementujê". > Zreszt±, je¶li dla ciebie programowanie obiektowe jest modelowaniem > rzeczywisto¶ci, to obawiam siê, ¿e mo¿emy nasz± dyskusjê wznowiæ za parê > lat, jak bêdziesz ju¿ mówi³ jêzykiem w³asnego do¶wiadczenia, a nie > ksi±¿kowym. I znowu za³o¿enia... Za³ó¿ przez chwilê, ¿e nie jeste¶ jednak nieomylny. > (Na marginesie: to bardzo dobrze, ¿e literatura do OO twierdzi, ¿e > programowanie obiektowe jest modelowaniem rzeczywisto¶ci. Tak bowiem > nale¿y t± sprawê t³umaczyæ pocz±tkuj±cym. Im wiêcej jednak cz³owiek > programuje obiektowo, tym bardziej siê przekonuje, ¿e to nie ma nic > wspólnego z prawd±. To jest jeden ze znaków rozpoznawczych, czy kto¶ > potrafi my¶leæ samodzielnie rzeczywi¶cie dysponuje do¶wiadczeniem > zawodowym, czy recytuje z pamiêci wiedzê ksi±¿kow±.) Dla mnie odnoszenie siê do rzeczywisto¶ci jest wygodn± praktyk± w takich bezsensownych dyskusjach jak ta. Podobnie jak to siê czyni w literaturze. Niektórzy jednak przyjmuj± ksi±¿kowe przyk³ady za pewnik: "tak nale¿y modelowaæ rzeczywiste systemy". I to jest rzeczywi¶cie smutne. > > Cofaj±c jednak t± ca³± dygresjê, któr± nie wiem po co wprowadzi³e¶ - > poda³em ci tylko przyk³ad, dlaczego portfel nie mo¿e byæ typem > warto¶ciowym. > > Je¶li nie zrozumia³e¶ nadal, to wyt³umaczê ci bardziej ³opatologicznie: > portfel zawieraj±cy tyle samo pieniêdzy, to nie ten sam portfel (mówiê > tak, bo twierdzi³e¶, ¿e ilo¶æ pieniêdzy mo¿e byæ warto¶ci± potrfela). Mo¿e byæ. Je¶li zastanawia³bym siê "czy to ten sam portfel" to rozwa¿a³bym to¿samo¶æ a nie warto¶æ portfela. Rozumiesz? >> > Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel >> > nie mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ >> > jeszcze wiele innych stanów i atrytbutów. Taki poda³e¶ wcze¶niej argument. Dla mnie podzia³ na obiekty warto¶ciowe i niewarto¶ciowe jest sztuczny, ¿eby nie powiedzieæ nieistniej±cy, wiêc nie dziw siê, ¿e opornie pod±¿am za t± teori±. >> Wychodz±c z tego za³o¿enia stanem "obiektu" "klasy" int jest np. 2. Stan >> ten mo¿na zmieniæ "funkcj±" zmiany stanu, np. ++. >> Kto z nas nie rozró¿nia warto¶ci od stanu? > > int x = 2; > int y = 2; > > Powiedz mi teraz, czy "x jest y". W C++? Nie. Odsy³am do Stroustrupa jakie mechanizmy tego jêzyka tutaj zadzia³a³y, a przestaniesz zadawaæ takie pytania. >> >> > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu >> >> > kolor mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru >> >> > zapisany tam kod koloru jest ten sam. Ty chcesz, ¿eby przed >> >> > odczytaniem numeru z ka¿dej kartki najpierw sprawdziæ, czy te obie >> >> > kartki to czasem nie jest jedna i ta sama kartka. Jaki to ma sens? >> > >> >> Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: >> >> data naniesienia, technika wykonania i stopieñ nas³onecznienia, które >> >> pozwalaj± obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê >> >> porównaæ dwóch "czerwonych". Odsy³am do ekspertów - lakierników >> >> samochodowych. >> > >> > Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o >> > kolorze. Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz >> > przypadkiem te¿ nie stanem) lakieru. > >> Ja tylko poszed³em Twoj± logik±. Zwa¿, ¿e w systemie, o którym pisa³em >> przy portfelu nie wspomina³em o istnieniu kart kredytowych. > > Nie poszed³e¶ moj± logik±. Mówi³em o kolorze, a ty wzi±³e¶ sobie nie wiem > po co lakier samochodowy. Oj, lakier to ju¿ by³a taka wisienka na torcie. Ka¿dy kolor p³owieje w rzeczywisto¶ci, a wiêc... (odsy³am parê akapitów wy¿ej). > Podobnie typem warto¶ciowym mog± byæ "pieni±dze". Ale nie kieszeñ, > portfel, konto, sejf, czy gdzie to tam jeszcze chcesz przechowywaæ. > >> > No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz >> > siê i zg³osisz za tydzieñ? > >> Do kogo mia³bym siê zg³osiæ? > > No có¿, wydawa³o mi siê, ¿e ka¿dy, kto studiowa³, s³ysza³ to s³ynne > okre¶lenie. W czym¶ siê widaæ pomyli³em. Nie mierz innych swoj± miar±. Nie przypominam sobie, ¿eby który¶ z wyk³adowców musia³ siê w ten sposób nade mn± litowaæ. > >> >> >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a >> >> >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te >> >> >> same" a wiêc na pewno "takie same" obiekty. >> >> > >> >> > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej >> >> > bêdzie wylot. >> > >> >> W operatorze porównania? Nie s±dzê... >> > >> > W operatorze przypisania. > >> Co mia³oby sprawiæ "wylot" w operatorze przypisania? > > Sprawdzenie, czy nie przypisujemy samego siebie. Fakt, ¿e musisz u¿yæ > operatora porównania dla to¿samo¶ci jest przykr± konieczno¶ci±, bo bez > tego usun±³by¶ czê¶æ obiektu, z którego za chwilê masz zamiar czytaæ. Zagadnienie pomocnicze int a; a = a; Pytanie: co nast±pi wcze¶niej odczyt czy zapis warto¶ci a? Ponawiam pytanie podstawowe: jaki wylot masz na my¶li? > >> >> > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie. >> > >> >> W pewnych przypadkach mo¿e tak byæ. >> > >> > Statystycznie jest to 99% przypadków. > >> Statystycznie, to ja bijê swoj± ¿onê co miesi±c. Ty, je¶li jeste¶ ¿onaty >> równie¿. Takie szacunki trzeba robiæ dla konkretnych klas a nie >> generalizowaæ. > > No widzisz. A ja mogê sobie pozwoliæ na generalizacjê. Mo¿esz. Ale nie wpieraj, ¿e jest ona poprawna. > Chodzi o bardzo prost± rzecz: jakiej wielko¶ci jest zwykle typ > warto¶ciowy? Niewielkiej. Musi byæ niewielki, bo im wiêkszy, tym wiêcej > zasobów zajmuje jego warto¶æ, d³u¿ej siê kopiuje, a i porównanie warto¶ci > - dosæ czêsta operacja - trwa do¶æ d³ugo. Dlatego w³a¶nie typy warto¶ciowe > robi siê z za³o¿enia JAK NAJMNIEJSZE - w³a¶nie po to, ¿eby te operacje > by³y jak najszybsze. Skoro istnieje taka presja na obiekty warto¶ciowe, to > gdzie masz w takim razie pole dla obiektów, w których porównanie mo¿na > "przyspieszyæ" poprzez najpierw sprawdzanie to¿samo¶ci? To jest przypadek szczególny a nie ogólny. Nie twierdzê jednak, ¿e przypadek odwrotny, czyli taki jest ogólny, uniwersalny i najlepszy. > >> >> Implementuj±c operator warto >> >> oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów. >> > >> > Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla >> > których trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ. >> > >> > Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez >> (...) >> > >> > Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e >> > ten przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê, >> > ¿e da³oby siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to >> > nie ma wiêkszego znaczenia. > >> Nie bêdê ani analizowa³ Twojego przyk³adu, ani mu zaprzecza³. Zak³adam, >> ¿e jest s³uszny. To jednak tylko przyk³ad, z którego do sformu³owania >> regu³y jeszcze daleko. > > To by³ przyk³ad wykonania analizy, który pokaza³, ¿e siê nie op³aca. Czy > jeste¶w stanie podaæ mi kontrprzyk³ad - czyli taki, który udowodni, ¿e siê > op³aca? Proponujê przypomnieæ sobie na czym polega³ _dowód_, a nie przyk³ad potwierdzaj±cy s³uszno¶æ danego twierdzenia. >> > W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania >> > analizy, która dowiedzie, czy to siê nam op³aca, czy nie. Ty >> > przyjmujesz "w ciemno", ¿e sprawdzanie najpierw to¿samo¶ci bêdzie >> > zawsze bardziej op³acalne. W ostateczno¶ci zgadzasz siê nawet, ¿e >> > "najczê¶ciej". Je¶li przyjmowanie w ciemno to f(n), to jeste¶ zaledwie na etapie f(n)-1. Warto by³o siê napracowaæ? >> Ty dla odmiany uwa¿asz, ¿e najczê¶ciej nie. Na razie jednak nie potrafisz >> udowodniæ dlaczego Twoja teza jest lepsza od mojej. > > Potrafiê, tylko ty nie potrafisz jej zrozumieæ, albo uparcie zaprzeczasz > faktom. Nie zaprzeczam, tylko wskazujê, ¿e s± to zaledwie pojedyncze fakty, a nie ogólna zale¿no¶æ. Nawet nie: nie zaprzeczam zale¿no¶ci, ale Twojemu sposobowi pseudodowodzenia. > Moja teza jest lepsza, bo jest oparta na rzetelnej analizie (nb. analiza > Qrczaka równie¿). Twoja teza, ¿e to jest "oczywiste, ¿e tak siê powinno > zawsze robiæ" nie jest poparta niczym. Nic takiego nie napisa³em. Oczywiste jest dla mnie, ¿e nie zawsze powinno siê robiæ tak jak Ty piszesz. >> > No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i >> > oszacuj ilo¶æ porównañ trafionych i nietrafionych w typowych >> > algorytmach, które go u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym >> > rozmawiamy. > >> Nie chodzi o sam typ, tylko kontekst u¿ycia. > > Brawo! Zatem s³ucham. U¿ycie typu jako klucza w hash mapie. >> >> Generalnie jednak - nie zgadzam siê. >> > >> > Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie >> > potrafiê to uzasadniæ. > >> W odró¿nieniu od Ciebie unikam jednoznacznych stwierdzeñ na temat swoich >> umiejêtno¶ci. > > Z t± "oczywisto¶ci±", ¿e operator porównania powinien najpierw sprawdziæ > to¿samo¶æ, niespecjalnie ci to wysz³o. W wiêkszo¶ci przypadków, je¶li analiza wyka¿e, ¿e siê op³aca. Nie przekrêcaj moich s³ów. >> > Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym. >> > Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym >> > nastêpuj±ce wymagania wzglêdem typu: >> > - przypisywalny >> > - kopiowalny >> > - domy¶lnie-konstruowalny > >> Rozumiem, ¿e je¶li stworzê sobie jaki¶ widget, powiedzmy combo-box, który >> spe³nia powy¿sze wymagania, to nie bêdê móg³, go przechowywaæ w >> std::list, bo pogwa³cê Twoj± teoriê? > > Nie. Bo jak wykonasz na nim algorytm std::remove, to zdrowo siê zdziwisz, > co po tym powsta³o. Nie pisa³em nic o chêci u¿ycia któregokolwiek z algorytmów. >> >> >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z >> >> >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ. >> >> > >> >> >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo. >> >> > >> >> > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ) >> >> > Oraz obiekt: historia transakcji >> >> > Oraz... >> > >> >> Jak wy¿ej: zale¿y od kontekstu. >> > >> > Nic nie zale¿y od ¿adnego kontekstu. >> > >> > Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest >> > obiektem. > >> Niepotrzebnie wi±¿esz terminy z ¿ycia (stan konta) z terminami >> informatycznymi (stan obiektu). Osobom z ma³ym do¶wiadczeniem to siê >> czêsto zdarza, nie przejmuj siê. > > Parafrazuj±c, "Skoñczy³ siê czas argumentów. Teraz jest czas inwektyw". Trafi³em widzê na wra¿liwca. > A mo¿e tak co¶ do tematu? > >> >> Mo¿emy nie wi±zaæ obiektów transakcji do >> >> konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do >> >> konta. >> > >> > Ale co to ma do rzeczy? > >> To, ¿e obiekt konto nie musi przechowywaæ historii, je¶li tylko zechcê >> tak to zamodelowaæ. > > No mo¿e, i nadal, co z tego? Guzik. Polecam lecytynkê, bo nie pamiêtasz ju¿ co napisa³e¶ kilka postów temu i dlaczego staram siê uwaliæ pomys³, ¿e konto _musi_ przechowywaæ to tamto i sramto. > >> >> > Czy ty w ogóle wiesz, co to jest "warto¶æ"? >> > >> >> Element ze zbioru (tu: typ, klasa). >> > >> > To znaczy? > >> Odsy³am do ksi±¿ki "Matematyka dla klas drugich". > > Có¿, osobliwy masz wybór literatury do nauki programowania, ale to ju¿ nie > moja sprawa. Widzê, ¿e pozycja, o której wspomnia³em jest Ci obca. W przeciwnym razie wiedzia³by¶, ¿e nie ma tam s³owa o programowaniu. -- Mariusz Lotko
Re: pl.comp.objects FAQ (Frequently Asked Questions and more)
Author: Sektor van Skijl
Date: Fri, 16 Mar 2007 16:39
Date: Fri, 16 Mar 2007 16:39
435 lines
17389 bytes
17389 bytes
Dnia Thu, 15 Mar 2007 06:12:44 +0100, Mariusz Lotko skrobie: > Sektor van Skijlen wrote: > >> > Swiss army knife to by by³o, gdyby ten portfel móg³ przechowywaæ > >> > pieni±dze, laptopy, meble, samochody, kontenery i elektrownie. > > > >> Nie. Swiss army knife oznacza, ¿e modelujesz wszystkie elementy > >> rzeczywisto¶ci czy tego wymaga system czy nie. > > > > Nie wiem, jak ty, ale ja pojêcie "swiss army knife" znam jako jeden z > > b³êdów OO, który polega na stworzeniu klasy o zbyt du¿ym zakresie > > odpowiedzialno¶ci. > Ja te¿. Dlaczego uwa¿asz, ¿e modelowanie wiêkszej czê¶ci rzeczywisto¶ci > od wymaganej nie jest "zbyt du¿ym zakresem odpowiedzialno¶ci"? Bo odpowiedzialno¶æ jest jedna, niezale¿nie od dok³adno¶ci modelowania. > > Dok³adno¶æ modelowania to zupe³nie inna sprawa. > Inny bêdzie poziom szczegó³owo¶ci klasy Samochód w kartotece > samochodów w Urzêdzie Miasta, a inny w kartotece warsztatu > samochodowego. To nie ma znaczenia. > > Zreszt±, je¶li dla ciebie programowanie obiektowe jest modelowaniem > > rzeczywisto¶ci, to obawiam siê, ¿e mo¿emy nasz± dyskusjê wznowiæ za parê > > lat, jak bêdziesz ju¿ mówi³ jêzykiem w³asnego do¶wiadczenia, a nie > > ksi±¿kowym. > I znowu za³o¿enia... Za³ó¿ przez chwilê, ¿e nie jeste¶ jednak > nieomylny. Ja tylko stwierdzam fakt. > > (Na marginesie: to bardzo dobrze, ¿e literatura do OO twierdzi, ¿e > > programowanie obiektowe jest modelowaniem rzeczywisto¶ci. Tak bowiem > > nale¿y t± sprawê t³umaczyæ pocz±tkuj±cym. Im wiêcej jednak cz³owiek > > programuje obiektowo, tym bardziej siê przekonuje, ¿e to nie ma nic > > wspólnego z prawd±. To jest jeden ze znaków rozpoznawczych, czy kto¶ > > potrafi my¶leæ samodzielnie rzeczywi¶cie dysponuje do¶wiadczeniem > > zawodowym, czy recytuje z pamiêci wiedzê ksi±¿kow±.) > Dla mnie odnoszenie siê do rzeczywisto¶ci jest wygodn± praktyk± > w takich bezsensownych dyskusjach jak ta. Wygodn±, ale niekoniecznie w³a¶ciw±. Bo wiele systemów i szczegó³ów definicyjnych nie posiada odniesienia w rzeczywisto¶ci. Mo¿na wiêc rzeczywisto¶æ przywo³ywaæ dla porównania ("przypowie¶ci"), ale nie do dowodzenia. > > Cofaj±c jednak t± ca³± dygresjê, któr± nie wiem po co wprowadzi³e¶ - > > poda³em ci tylko przyk³ad, dlaczego portfel nie mo¿e byæ typem > > warto¶ciowym. > > > > Je¶li nie zrozumia³e¶ nadal, to wyt³umaczê ci bardziej ³opatologicznie: > > portfel zawieraj±cy tyle samo pieniêdzy, to nie ten sam portfel (mówiê > > tak, bo twierdzi³e¶, ¿e ilo¶æ pieniêdzy mo¿e byæ warto¶ci± potrfela). > Mo¿e byæ. Je¶li zastanawia³bym siê "czy to ten sam portfel" to rozwa¿a³bym > to¿samo¶æ a nie warto¶æ portfela. Rozumiesz? To ty nie rozumiesz. 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. > >> > Ilo¶æ pieniêdzy nie jest warto¶ci± portfela. Jest jego stanem. Portfel > >> > nie mo¿e mieæ warto¶ci - i to nie dlatego, ¿e poza tym mo¿e mieæ > >> > jeszcze wiele innych stanów i atrytbutów. > Taki poda³e¶ wcze¶niej argument. Dla mnie podzia³ na obiekty warto¶ciowe > i niewarto¶ciowe jest sztuczny, ¿eby nie powiedzieæ nieistniej±cy, wiêc > nie dziw siê, ¿e opornie pod±¿am za t± teori±. To jest wyja¶nienie, nie argument. Je¶li jeste¶ betonowy na t± teoriê, to ja ci nic nie poradzê. Nie powiem, ¿eby mnie to martwi³o. > >> Wychodz±c z tego za³o¿enia stanem "obiektu" "klasy" int jest np. 2. Stan > >> ten mo¿na zmieniæ "funkcj±" zmiany stanu, np. ++. > >> Kto z nas nie rozró¿nia warto¶ci od stanu? > > > > int x = 2; > > int y = 2; > > > > Powiedz mi teraz, czy "x jest y". > W C++? Nie. Odsy³am do Stroustrupa jakie mechanizmy tego jêzyka tutaj > zadzia³a³y, a przestaniesz zadawaæ takie pytania. No i jakie twoim zdaniem mechanizmy jêzyka tu zadzia³a³y? Oczywi¶cie, ¿e x to jest y. Dowód: int f( int ); // dowolna funkcja deterministyczna i bezstanowa f( x ) == f( y ) // zawsze prawdziwe > >> >> > Typem warto¶ciowym mo¿e byæ kolor. Porównanie dwóch obiektów typu > >> >> > kolor mo¿na porównaæ ze sprawdzeniem, czy na dwóch kartkach papieru > >> >> > zapisany tam kod koloru jest ten sam. Ty chcesz, ¿eby przed > >> >> > odczytaniem numeru z ka¿dej kartki najpierw sprawdziæ, czy te obie > >> >> > kartki to czasem nie jest jedna i ta sama kartka. Jaki to ma sens? > >> > > >> >> Id±c Twoj± logik±: niekoniecznie. Obiekt kolor ma jeszcze atrybuty: > >> >> data naniesienia, technika wykonania i stopieñ nas³onecznienia, które > >> >> pozwalaj± obliczyæ rzeczywisty kolor w czasie :> Wtedy nie da siê > >> >> porównaæ dwóch "czerwonych". Odsy³am do ekspertów - lakierników > >> >> samochodowych. > >> > > >> > Nie przypominam sobie, ¿ebym mówi³ o lakierze samochodowym. Mówi³em o > >> > kolorze. Kolor mo¿e byæ równie¿ atrybutem (a nie warto¶ci±, acz > >> > przypadkiem te¿ nie stanem) lakieru. > > > >> Ja tylko poszed³em Twoj± logik±. Zwa¿, ¿e w systemie, o którym pisa³em > >> przy portfelu nie wspomina³em o istnieniu kart kredytowych. > > > > Nie poszed³e¶ moj± logik±. Mówi³em o kolorze, a ty wzi±³e¶ sobie nie wiem > > po co lakier samochodowy. > Oj, lakier to ju¿ by³a taka wisienka na torcie. Jasne, bagatelizuj i konfabuluj, bo ¿adne argumenty ci ju¿ nie zosta³y. > Ka¿dy kolor p³owieje > w rzeczywisto¶ci, a wiêc... (odsy³am parê akapitów wy¿ej). Kolory nie p³owiej±. P³owiej± substancje koloruj±ce, czyli zmieniaj± one kolory. Ju¿ widzê, z czym masz problem. Ty przede wszystkim nie wiesz, czym jest kolor, albo czym jest liczba. Skoro tak, to nigdy nie zrozumiesz, co to takiego typ warto¶ciowy. > > Podobnie typem warto¶ciowym mog± byæ "pieni±dze". Ale nie kieszeñ, > > portfel, konto, sejf, czy gdzie to tam jeszcze chcesz przechowywaæ. > > > >> > No to jak, zrozumia³e¶ ju¿, co to takiego jest warto¶æ, czy douczysz > >> > siê i zg³osisz za tydzieñ? > > > >> Do kogo mia³bym siê zg³osiæ? > > > > No có¿, wydawa³o mi siê, ¿e ka¿dy, kto studiowa³, s³ysza³ to s³ynne > > okre¶lenie. W czym¶ siê widaæ pomyli³em. > Nie mierz innych swoj± miar±. Nie przypominam sobie, ¿eby który¶ z > wyk³adowców musia³ siê w ten sposób nade mn± litowaæ. Zale¿y na jakiej uczelni studiowa³e¶. > >> >> >> Z tym, ¿e w obu przypadkach nie chodzi o "przykr± konieczno¶æ", a > >> >> >> o "wspania³± mo¿liwo¶æ" szybkiego stwierdzenia, ¿e chodzi o "te > >> >> >> same" a wiêc na pewno "takie same" obiekty. > >> >> > > >> >> > To jest przykra konieczno¶æ. Musisz to po prostu zrobiæ, bo inaczej > >> >> > bêdzie wylot. > >> > > >> >> W operatorze porównania? Nie s±dzê... > >> > > >> > W operatorze przypisania. > > > >> Co mia³oby sprawiæ "wylot" w operatorze przypisania? > > > > Sprawdzenie, czy nie przypisujemy samego siebie. Fakt, ¿e musisz u¿yæ > > operatora porównania dla to¿samo¶ci jest przykr± konieczno¶ci±, bo bez > > tego usun±³by¶ czê¶æ obiektu, z którego za chwilê masz zamiar czytaæ. > Zagadnienie pomocnicze > int a; > a = a; > Pytanie: co nast±pi wcze¶niej odczyt czy zapis warto¶ci a? > Ponawiam pytanie podstawowe: jaki wylot masz na my¶li? W ogólno¶ci zale¿y to od definicji operatora przypisania. W przypadku int argument przyjmowany jest przez warto¶æ. Ale to nie musi byæ regu³a, nawet dla typów warto¶ciowych. Np. std::string jest typem warto¶ciowym, a jego operator przypisania przyjmuje argument przez referencjê. I wtedy musisz sprawdziæ. > >> >> > Ta "wspania³a mo¿liwo¶æ" z kolei powoduje dro¿sze porównanie. > >> > > >> >> W pewnych przypadkach mo¿e tak byæ. > >> > > >> > Statystycznie jest to 99% przypadków. > > > >> Statystycznie, to ja bijê swoj± ¿onê co miesi±c. Ty, je¶li jeste¶ ¿onaty > >> równie¿. Takie szacunki trzeba robiæ dla konkretnych klas a nie > >> generalizowaæ. > > > > No widzisz. A ja mogê sobie pozwoliæ na generalizacjê. > Mo¿esz. Ale nie wpieraj, ¿e jest ona poprawna. Nie wpieram, tylko twierdzê. > > Chodzi o bardzo prost± rzecz: jakiej wielko¶ci jest zwykle typ > > warto¶ciowy? Niewielkiej. Musi byæ niewielki, bo im wiêkszy, tym wiêcej > > zasobów zajmuje jego warto¶æ, d³u¿ej siê kopiuje, a i porównanie warto¶ci > > - dosæ czêsta operacja - trwa do¶æ d³ugo. Dlatego w³a¶nie typy warto¶ciowe > > robi siê z za³o¿enia JAK NAJMNIEJSZE - w³a¶nie po to, ¿eby te operacje > > by³y jak najszybsze. Skoro istnieje taka presja na obiekty warto¶ciowe, to > > gdzie masz w takim razie pole dla obiektów, w których porównanie mo¿na > > "przyspieszyæ" poprzez najpierw sprawdzanie to¿samo¶ci? > To jest przypadek szczególny a nie ogólny. Nie twierdzê jednak, ¿e przypadek > odwrotny, czyli taki jest ogólny, uniwersalny i najlepszy. Zgadza siê - bo takiego tutaj nie ma. Wszystkie przypadki tutaj s± szczególne. Ale przypadek, o którym ja wspomnia³em, mimo szczególno¶ci, wystêpuje w przewa¿aj±cej wiêkszo¶ci sytuacji, a to, co ty poda³e¶, jest akurat do niego odwrotny - co w zupe³no¶ci nie przeszkadza ci twierdziæ, ¿e jest przypadkiem ogólnym. > >> >> Implementuj±c operator warto > >> >> oszacowaæ prawdopodobieñstwo porównywania tych samych obiektów. > >> > > >> > Zrób sobie ma³± statystykê u¿ycia takiego typu i ilo¶æ porównañ, dla > >> > których trafiasz na równo¶æ i dla których trafiasz na nierówno¶æ. > >> > > >> > Prosty przyk³ad - iteratory. Masz pêtlê, w której przechodzisz przez > >> (...) > >> > > >> > Poda³em ci tylko przyk³ad, jak nale¿y prowadziæ tak± analizê - to, ¿e > >> > ten przyk³ad jest negatywny dla twojej tezy, nie ma znaczenia. My¶lê, > >> > ¿e da³oby siê znale¼æ przyk³ad, który by twoj± tezê potwierdza³, ale to > >> > nie ma wiêkszego znaczenia. > > > >> Nie bêdê ani analizowa³ Twojego przyk³adu, ani mu zaprzecza³. Zak³adam, > >> ¿e jest s³uszny. To jednak tylko przyk³ad, z którego do sformu³owania > >> regu³y jeszcze daleko. > > > > To by³ przyk³ad wykonania analizy, który pokaza³, ¿e siê nie op³aca. Czy > > jeste¶w stanie podaæ mi kontrprzyk³ad - czyli taki, który udowodni, ¿e siê > > op³aca? > Proponujê przypomnieæ sobie na czym polega³ _dowód_, a nie przyk³ad > potwierdzaj±cy s³uszno¶æ danego twierdzenia. Nie przypominam sobie ¿adnego dowodu. > >> > W odró¿nieniu od ciebie jednak, ja rozumiem konieczno¶æ wykonania > >> > analizy, która dowiedzie, czy to siê nam op³aca, czy nie. Ty > >> > przyjmujesz "w ciemno", ¿e sprawdzanie najpierw to¿samo¶ci bêdzie > >> > zawsze bardziej op³acalne. W ostateczno¶ci zgadzasz siê nawet, ¿e > >> > "najczê¶ciej". > Je¶li przyjmowanie w ciemno to f(n), to jeste¶ zaledwie na etapie f(n)-1. > Warto by³o siê napracowaæ? A jeste¶ w stanie to udowodniæ? To s³ucham. > >> Ty dla odmiany uwa¿asz, ¿e najczê¶ciej nie. Na razie jednak nie potrafisz > >> udowodniæ dlaczego Twoja teza jest lepsza od mojej. > > > > Potrafiê, tylko ty nie potrafisz jej zrozumieæ, albo uparcie zaprzeczasz > > faktom. > Nie zaprzeczam, tylko wskazujê, ¿e s± to zaledwie pojedyncze fakty, a nie > ogólna zale¿no¶æ. Nawet nie: nie zaprzeczam zale¿no¶ci, ale Twojemu > sposobowi pseudodowodzenia. To nie jest dowód, a przedstawiona teoria nie jest zale¿no¶ci±. Jest to tylko stwierdzenie poprawne w statystycznej wiêkszo¶ci przypadków - ale to nie ma znaczenia. Ty uparcie twierdzisz, ¿e odwrotne postêpowanie jest przypadkiem ogólnym, wiêc w ogólno¶ci ¿eby twoje bzdury obaliæ wystarczy mi podaæ jeden przyk³ad. Fakt, ¿e ten przyk³ad reprezentuje wiêkszo¶æ statystyczn± nie ma tu nawet znaczenia. > > Moja teza jest lepsza, bo jest oparta na rzetelnej analizie (nb. analiza > > Qrczaka równie¿). Twoja teza, ¿e to jest "oczywiste, ¿e tak siê powinno > > zawsze robiæ" nie jest poparta niczym. > Nic takiego nie napisa³em. Oczywiste jest dla mnie, ¿e nie zawsze powinno > siê robiæ tak jak Ty piszesz. Dobra, dyskusja zaczyna mi siê nudziæ, skoro zaczynasz zaprzeczaæ swoim niedawnym stanowczym wypowiedziom (równie stanowczo zreszt±). > >> > No to podaj mi przyk³ad typu warto¶ciowego, w którym to siê op³aca, i > >> > oszacuj ilo¶æ porównañ trafionych i nietrafionych w typowych > >> > algorytmach, które go u¿ywaj±. Wtedy bêdziemy wiedzieli, o czym > >> > rozmawiamy. > > > >> Nie chodzi o sam typ, tylko kontekst u¿ycia. > > > > Brawo! Zatem s³ucham. > U¿ycie typu jako klucza w hash mapie. No fajnie - czyli, jak rozumiem, masz taki klucz, którego porównanie z istniej±cym zaczynasz od sprawdzenia to¿samo¶ci klucza? No dobrze. Jak zatem wygl±da definicja typu klucza? > >> >> Generalnie jednak - nie zgadzam siê. > >> > > >> > Ale¿ masz pe³ne prawo siê nie zgadzaæ. Ja w odró¿nieniu od ciebie > >> > potrafiê to uzasadniæ. > > > >> W odró¿nieniu od Ciebie unikam jednoznacznych stwierdzeñ na temat swoich > >> umiejêtno¶ci. > > > > Z t± "oczywisto¶ci±", ¿e operator porównania powinien najpierw sprawdziæ > > to¿samo¶æ, niespecjalnie ci to wysz³o. > W wiêkszo¶ci przypadków, je¶li analiza wyka¿e, ¿e siê op³aca. Nie przekrêcaj > moich s³ów. O analizie to dopiero ja zacz±³em mówiæ, wiêc nie wmawiaj, ¿e cokolwiek takiego twierdzi³e¶. Jestem i tak za leniwy, ¿eby zajrzeæ do wcze¶niejszych wiadomo¶ci i skompromitowaæ ciê twoimi wcze¶niejszymi wypowiedziami. Poza tym, podoba mi siê to: w wiêkszo¶ci przypadków, je¶li analiza wyka¿e, ¿e siê op³aca. Super. Analiza mo¿e wykazaæ, ¿e w 90% przypadków siê nie op³aca, ale to i tak te 10% to bêdzie dla ciebie wiêkszo¶æ. > >> > Przyk³adowo, typ przechowywany w std::list musi byæ typem warto¶ciowym. > >> > Niestety, tak jest skonstruowany szablon std::list. ¦wiadcz± o tym > >> > nastêpuj±ce wymagania wzglêdem typu: > >> > - przypisywalny > >> > - kopiowalny > >> > - domy¶lnie-konstruowalny > > > >> Rozumiem, ¿e je¶li stworzê sobie jaki¶ widget, powiedzmy combo-box, który > >> spe³nia powy¿sze wymagania, to nie bêdê móg³, go przechowywaæ w > >> std::list, bo pogwa³cê Twoj± teoriê? > > > > Nie. Bo jak wykonasz na nim algorytm std::remove, to zdrowo siê zdziwisz, > > co po tym powsta³o. > Nie pisa³em nic o chêci u¿ycia któregokolwiek z algorytmów. Dobrze, zrób sobie cokolwiek - nawet sortowanie (sortowanie listy jest algorytmem wewnêtrznym listy, a nie ogólnym), scalanie z inn± list±, czy cokolwiek innego. Pomijaj±c ju¿ fakt, jak zamierzasz okre¶liæ "kopiowalno¶æ" wid¿etu, oraz jak zamierzasz okre¶liæ jego porównywalno¶æ (potrzebn± do find) i porz±dkowalno¶æ (potrzebn± do sort). W ró¿nych przypadkach, przy ró¿nych operacjach, funkcje operuj±ce na li¶cie potrafi± ci skopiowaæ okre¶lony obiekt, przechowaæ kopiê w obiekcie tymczasowym i wrzuciæ do listy, a stary usun±æ - tak w³a¶nie dzia³a np. sortowanie, czy odwracanie (w szczególno¶ci wszystkie algorytmy zmieniaj±ce, w tym równie¿ algorytmy zaimplementowane jako metody listy). > >> >> >> > Je¶li mówimy ju¿ o rzeczywisto¶ci - podaj mi przyk³ad obiektu z > >> >> >> > rzeczywisto¶ci, który posiada jednocze¶nie warto¶æ i to¿samo¶æ. > >> >> > > >> >> >> Konto bankowe. To¿samo¶æ: numer, warto¶æ: saldo. > >> >> > > >> >> > Oraz warto¶æ: w³a¶ciciel (mo¿na go potem kiedy¶ zmieniæ) > >> >> > Oraz obiekt: historia transakcji > >> >> > Oraz... > >> > > >> >> Jak wy¿ej: zale¿y od kontekstu. > >> > > >> > Nic nie zale¿y od ¿adnego kontekstu. > >> > > >> > Saldo jest stanem (cz±stkowym) konta. Saldo jest warto¶ci±. Konto jest > >> > obiektem. > > > >> Niepotrzebnie wi±¿esz terminy z ¿ycia (stan konta) z terminami > >> informatycznymi (stan obiektu). Osobom z ma³ym do¶wiadczeniem to siê > >> czêsto zdarza, nie przejmuj siê. > > > > Parafrazuj±c, "Skoñczy³ siê czas argumentów. Teraz jest czas inwektyw". > Trafi³em widzê na wra¿liwca. A ja, jak widzê, trafi³em na kogo¶ zakompleksionego, kto musi siê dowarto¶ciowaæ przez pomiatanie innymi. > > A mo¿e tak co¶ do tematu? Czyli, jak rozumiem, nie masz nic do powiedzenia "do tematu"? > >> >> Mo¿emy nie wi±zaæ obiektów transakcji do > >> >> konta, a zrobiæ wi±zanie odwrotne: ka¿da transakcja ma referencjê do > >> >> konta. > >> > > >> > Ale co to ma do rzeczy? > > > >> To, ¿e obiekt konto nie musi przechowywaæ historii, je¶li tylko zechcê > >> tak to zamodelowaæ. > > > > No mo¿e, i nadal, co z tego? > Guzik. Polecam lecytynkê, bo nie pamiêtasz ju¿ co napisa³e¶ kilka postów > temu i dlaczego staram siê uwaliæ pomys³, ¿e konto _musi_ przechowywaæ to > tamto i sramto. No ok. I nadal, co z tego? Czy chcesz mo¿e doj¶æ do tego, ¿eby konto nie przechowywa³o niczego, co nie jest niezbêdne, ¿eby mog³o byæ typem warto¶ciowym? Ju¿ ci powiedzia³em: konto nie bêdzie nigdy typem warto¶ciowym, ¿eby¶ siê nawet zesra³. > >> >> > Czy ty w ogóle wiesz, co to jest "warto¶æ"? > >> > > >> >> Element ze zbioru (tu: typ, klasa). > >> > > >> > To znaczy? > > > >> Odsy³am do ksi±¿ki "Matematyka dla klas drugich". > > > > Có¿, osobliwy masz wybór literatury do nauki programowania, ale to ju¿ nie > > moja sprawa. > Widzê, ¿e pozycja, o której wspomnia³em jest Ci obca. W przeciwnym razie > wiedzia³by¶, ¿e nie ma tam s³owa o programowaniu. Jest mi, owszem, obca. Kiedy ja chodzi³em do "klasy drugiej", ta pozycja nazywa³a siê inaczej. Móg³bym siê jeszcze trochê na tobie powy¿ywaæ, bo póki co rozmowa z tob± nadal mnie bawi, ale spróbujmy wróciæ do tematu - im bli¿ej tematu tym zawsze siê bardziej kompromitujesz. No wiêc, co to takiego jest "warto¶æ"? -- // _ ___ 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"
Page 1 of 2 • 79 total messages
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads