language oop newref


Referencje wewnątrz konstruktoraPodręcznik PHPPoprzedniRozdział 9. Klasy i ObiektyNastępnyReferencje wewnątrz konstruktora Tworzenie referencji wewnątrz konstruktora może prowadzić do dziwnych efektów. Ten rozdział ma pomóc w unikaniu takich problemów. class Foo { function Foo($nazwa) { // stworz referencje wewnatrz globalnej tablicy $globalref global $globalref; $globalref[] = &$this; // ustaw nazwę na przekazaną wartość $this->ustawNazwe($nazwa); // i wyświetl ją $this->wyswietlNazwe(); } function wyswietlNazwe() { echo "<br>",$this->nazwa; } function ustawNazwe($nazwa) { $this->nazwa = $nazwa; } } Sprawdźmy, czy jest jakaś różnica pomiędzy $bar1, który jest tworzony przy pomocy operatora przypisania =, a $bar2, który został stworzony używając operatora referencji =&... $bar1 = new Foo('ustawione w konstruktorze'); $bar1->wyswietlNazwe(); $globalref[0]->wyswietlNazwe(); /* wyjście: ustawione w konstruktorze ustawione w konstruktorze ustawione w konstruktorze */ $bar2 =& new Foo('ustawione w konstruktorze'); $bar2->wyswietlNazwe(); $globalref[1]->wyswietlNazwe(); /* wyjście: ustawione w konstruktorze ustawione w konstruktorze ustawione w konstruktorze */ Wydaje się, że nie ma żadnej różnicy, ale na prawdę jest jedna, i to bardzo istotna: $bar1 i $globalref[0] NIE są referencjami, NIE są tą samą zmienna. Dzieje się tak, ponieważ "new" nie zwraca domyślnie referencji, ale kopię. Notatka: Zwracanie kopii zamiast referencji nie powoduje utraty wydajności (od PHP 4 używane jest zliczanie referencji). Jednakże zazwyczaj lepiej jest pracować poprostu z kopiami zamiast referencji, poniewać tworzenie referencji zabiera trochę czasu, podczas gdy tworzenie kopii obiektów teoretycznie w ogóle nie zabiera czasu (chyba że któraś z tych zmiennych jest dużą tablicą lub obiektem i jedno z nich ulega zmianie, po czym tej samej zmianie ulegają pozostałe zmienne; wtedy lepiej jest użyć referencji do zmieniania ich równolegle). Aby udowodnić to, co zostało zapisane powyżej, przyjrzyjmy się poniższemu programowi. // teraz zmienimy nazwę. czego się spodziewasz? // możesz się spodziewać, że i $bar1 i $globalref[0] zmienią swoje nazwy... $bar1->ustawNazwe('ustawiona z zewnątrz'); // jak napisano powyżej, nic takiego się nie stanie $bar1->wyswietlNazwe(); $globalref[0]->wyswietlNazwe(); /* wyjście: ustawiona z zewnątrz ustawiona w konstruktorze */ // zobaczmy co się dzieje z $bar2 i $globalref[1] $bar2->ustawNazwe('ustawiona z zewnątrz'); // na szczęście ta zmienna nie zachowuje się jak ta z poprzedniego przypadku // są to te same zmienne, z więc $bar2->nazwa i $globalref[1]->nazwa są także // tymi samymi zmiennymi $bar2->wyswietlNazwe(); $globalref[1]->wyswietlNazwe(); /* wyjście: ustawiona z zewnątrz ustawiona z zewnątrz */ Ustatni przykład. Postaraj się go zrozumieć/ class A { function A($i) { $this->wartosc = $i; // domyśl się dlaczego nie potrzebujemy tutaj referencji $this->b = new B($this); } function stworzRef() { $this->c = new B($this); } function wyswietlWartosc() { echo "<br>","klasa ",get_class($this),': ',$this->value; } } class B { function B(&$a) { $this->a = &$a; } function wyswietlWartosc() { echo "<br>","klasa ",get_class($this),': ',$this->a->value; } } // spróbuj zrozumieć dlaczego użycie tu prostego kopiowania może powodować // nieporządany efekt w linii uznaczonej znaczkiem '*' $a =& new A(10); $a->stworzRef(); $a->wyswietlWartosc(); $a->b->wyswietlWartosc(); $a->c->wyswietlWartosc(); $a->value = 11; $a->wyswietlWartosc(); $a->b->wyswietlWartosc(); // * $a->c->wyswietlWartosc(); /* wyjście: klasa A: 10 klasa B: 10 klasa B: 10 klasa A: 11 klasa B: 11 klasa B: 11 */ PoprzedniSpis treściNastępnyMagiczne funkcje __sleep i __wakeupPoczątek rozdziałuMożliwości

Wyszukiwarka

Podobne podstrony:
language oop newref
language oop newref
language oop
language oop
language oop magic functions
language oop serialization
language oop serialization
language oop magic functions
language oop
language oop serialization
language oop constructor
language oop magic functions
language oop constructor

więcej podobnych podstron