Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> References, Не могу разобраться... 
:(
    Опции темы
SwordOfDeath
Дата 5.6.2011, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



Привет, 
Помогите разобраться как работает механизм by reference в PHP... Знаком с указателями в C...
Прочитав документацию, коментарии и объяснения все равно не могу понять как этот механизм работает в PHP.

Пишу Double Linked List... Ну и нужен "byreference" и работа с объектами по указателю(ссылке). А также динамическое создание объектов в списке... и соответственно динамическое освобождение...

Где-то проскакивает информация что reference в PHP это ссылки на данные... а где-то что reference это переменные указывающие на ссылки на данные. 

Вот мой класс:
Код
<?php
class ListNode{
    public $data;
    public $prev;
    public $next;
    
    function __construct(&$data){
        $this->data = &$data;
        $this->next = NULL;
        $this->prev = NULL;
    }
}
 
class LinkedList{
    public $firstNode;
    public $lastNode;
    public $count;
    public $nullref;
    
    function __construct(){
        $this->firstNode = NULL;
        $this->lastNode = NULL;
        $this->nullref = NULL;
        $this->count = 0;
    }
    
    public function prepend(&$data){
        $link = new ListNode(&$data);
        if($this->firstNode == NULL){
            $this->lastNode = &$link;
        } else {
            $link->next = &$this->firstNode;
            $this->firstNode->prev = &$link;
        }
        $this->firstNode = &$link;
        $this->count++;
    }
    
    public function append(&$data){
        $link = new ListNode(&$data);
        if($this->lastNode == NULL)
        {
            $this->firstNode = &$link;
        } else {
            $this->lastNode->next = &$link;
            $link->prev = &$this->lastNode;
        }
        $this->lastNode = &$link;
        $this->count++;
    }
    
    public function &deleteFirstNode(){
        if(!$this->count) return $this->nullref;
        $node = &$this->firstNode;
        if($node->next == NULL){
            $this->firstNode = NULL;
            $this->lastNode = NULL;
        } else {
            $this->firstNode = &$node->next;
            $this->firstNode->prev = NULL;
        }
        $this->count--;
        return $node;
    }
    
    public function &deleteLastNode(){
        if(!$this->count) return $this->nullref;
        $node = &$this->lastNode;
        if($node->prev == NULL){
            $this->firstNode = NULL;
            $this->lastNode = NULL;            
        } else {
            $this->lastNode = &$node->prev;
            $this->lastNode->next = NULL;
        }
        $this->count--;
        return $node;
    }
    
    public function &deleteNode(&$node){
        if(!$this->count) return $this->nullref;
        
        if($node->prev == NULL && $node->next == NULL && $this->firstNode == $node){
            $this->firstNode = NULL;
            $this->lastNode = NULL;
        } else if($node->prev != NULL && $node->next != NULL){
            $node->prev->next = &$node->next;
            $node->next->prev = &$node->prev;    
        } else if($node->prev == NULL && $this->firstNode == $node){
            $this->firstNode = &$node->next;
            $this->firstNode->prev = NULL;
        } else if($node->next == NULL && $this->lastNode == $node){
            $this->lastNode = &$node->prev;
            $this->lastNode->next = NULL;
        } else {
            return NULL;
        }
        $this->count--;
        return $node;
    }    
}
?>


В общем я пришел в выводу что везде где мне не требуется копирование нужно ставить амперсанд. Но потом просто ужаснулся от количества амперсандов в коде...
Код кажется работает но я буду очень благодарен если мне кто-то поможет разобраться и сделать все по уму, а не в слепую лепить byref!

PS: Я так понимаю сборщик мусора автоматом почистит данные которые остались без ссылок?

Это сообщение отредактировал(а) SwordOfDeath - 5.6.2011, 23:34
PM MAIL   Вверх
Absinthe
Дата 8.6.2011, 23:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 4.5.2011

Репутация: 1
Всего: 11



Цитата

Помогите разобраться как работает механизм by reference в PHP... 


Привет. Мой совет - купи хорошую книжку по основам и прочитай.
Кратко:
1) по значению копируются простые типы и массивы. По ссылке - объекты.
2) Т.е. если ты передаешь объект - то & не нужно
3) При передачи массива не происходит выделение лишних ресурсов - они выделяются при изменении массива. Так что не беспокойся.
4) Если ты передаешь по ссылке переменну типа строка или число, то у тебя наверняка ошибка проектирования.

Так что количество & в хорошем коде стремитс к нулю.
PM MAIL   Вверх
SwordOfDeath
Дата 9.6.2011, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



Цитата(Absinthe @  8.6.2011,  23:38 Найти цитируемый пост)
4) Если ты передаешь по ссылке переменну типа строка или число, то у тебя наверняка ошибка проектирования.

Эм... А в чем проблема? Так ведь и должно быть.... Мой клас не должен ничего копировать будь то строки или числа...

Цитата(Absinthe @  8.6.2011,  23:38 Найти цитируемый пост)
2) Т.е. если ты передаешь объект - то & не нужно

А при присваивании или возврате?

В моем конкретном случае работаю со списком объектов... Таким образом убрав & в описании параметров функции копирования не будет происходить и переменная будет указывать на изначальные данные?
PM MAIL   Вверх
Absinthe
Дата 10.6.2011, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 4.5.2011

Репутация: 1
Всего: 11



Цитата

Эм... А в чем проблема? Так ведь и должно быть.... Мой клас не должен ничего копировать будь то строки или числа...
 Копирование происходит при изменении, так что если не изменялось - не копируется.
А если тебе надо как-то внутри изменить число, которое передали - то мне твой код не нравится.
Хочешь менять что-то - то возвращай такое значение, или внеси его как переменную класса.

Цитата

А при присваивании или возврате?
 По ссылке всегда в случае объекта.
PM MAIL   Вверх
SwordOfDeath
Дата 10.6.2011, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



Спасибо огромное за пояснения...
В итоге получается что нужно все оставлять как есть... Потому что все мои byref дублируют стандартное поведение php и убирают "copy on write" что мне и нужно так как в объектах мне нужно менять ссылку на предыдущий и следующий...
Конечно можно было бы убрать byref от хранимых в списке данных так как я их не меняю... но по моему лучше оставить потому что это дает читающему человеку понимание что происходит byref и не нужно сильно задумываться о внутренностях php с её "copy on write" и различным поведением для разных типов данных.

Это сообщение отредактировал(а) SwordOfDeath - 10.6.2011, 12:40
PM MAIL   Вверх
Absinthe
Дата 10.6.2011, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 4.5.2011

Репутация: 1
Всего: 11



Цитата

но по моему лучше оставить потому что это дает читающему человеку понимание что происходит byref и не нужно
 Подразумевается, что читающий человек знает основы языка.
И такие вещи затрудняют чтение, акцентируя на себе внимание и читающий будет ожидать какой-то финт.
PM MAIL   Вверх
SwordOfDeath
Дата 10.6.2011, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 130
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



Ну вот мне пришлось прибегнуть к помощи форума даже после прочтения мануала и активного гугления... А на форуме в ветке для профи тему прочитало больше 70 человек перед тем как что-то откомментировать... Это наталкивает на мысль что читающий должен быть чуть более обознан в тонкостях php...
Да и программистов на php больше волнует простота и красота кода чем его эффективность... В данном случае этот класс написан для оптимизации... Что само по себе странно ведь данный функционал должен быть в самом языке... с красивым итератором для foreach итд...

Согласен что человека который имеет солидный опыт программирования на php такая запись может немного сбить с толку...
Но ведь byref он и в африке byref... А все эти скрытые копирования и хитрые условия по типам вот это реально сбивает с толку... По крайней мере меня так точно...

Спасибо за помощь! 
PM MAIL   Вверх
Absinthe
Дата 10.6.2011, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 4.5.2011

Репутация: 1
Всего: 11



Цитата

Это наталкивает на мысль что читающий должен быть чуть более обознан в тонкостях php...
 Я еще раз повторю. Это не тонкости. Это самые основы и все их знают.


Цитата

Да и программистов на php больше волнует простота и красота кода чем его эффективность... 
 Не путай программистов и праздных студентов.

Цитата

Что само по себе странно ведь данный функционал должен быть в самом языке... с красивым итератором для foreach итд...
 SPL.

Цитата

Но ведь byref он и в африке byref... А все эти скрытые копирования и хитрые условия по типам вот это реально сбивает с толку... По крайней мере меня так точно...
 После 1-2 месяцев PHP основы как-то сами собой постигнутся в достаточном объеме.
PM MAIL   Вверх
dark_religion
Дата 18.6.2011, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 198
Регистрация: 8.9.2006

Репутация: нет
Всего: -3



я вопроса не понял?)))  что именно не получается? 

Только в пхп списки так не работают в пхп не существует указателей на объекты)) Вот вычитал:

As of PHP 5.3, PHP's SPL extension contains the 'SplDoublyLinkedList' class that can be used to implement Deque datastructures. Previously to make a Deque structure the array functions array_shift/unshift/pop/push had to be used instead.

По руски говоря, поддержка  списков в php только в виде масивов, начиная с версии 5.3 есть класс SplDoublyLinkedList

http://php.net/manual/en/class.spldoublylinkedlist.php

А типо создание своего списка по моему теряет смысл) так как пхп не поддерживает той функциональности, что к примеру C++ ) то есть если вы и сделаете список) он смысла иметь не будет) 

Может я не прав, но немогу найти, что бы делали списки в php )) мы же не самые умные) раз не делают значит есть на то причина)

Еще вот есть класс http://php.net/manual/en/class.splqueue.php

Это сообщение отредактировал(а) dark_religion - 18.6.2011, 21:49
PM MAIL   Вверх
dark_religion
Дата 18.6.2011, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 198
Регистрация: 8.9.2006

Репутация: нет
Всего: -3



Цитата(Absinthe @  10.6.2011,  22:02 Найти цитируемый пост)
Не путай программистов и праздных студентов.


Хотел бы я посмотреть на вашу реализацию списка на Php продимонстрируйте всем ваши нестуденческие навыки самый простой пример:

Односвязный список. реализовать функцию push и добавить с помощью нее 5 елементов. И вывести содержимое объекта на экран, осилите?) 
Ато вы нас тут всех студентами обозвали. Продемонстируйте нам ваши супер навыки! Хоть одного балабола с ответами изучайте основы php удастся поймать за язык)) Встроеные классы в php можете нам не демонстрировать. Функция push должна быть полностью реализованна вами. 


Это сообщение отредактировал(а) dark_religion - 18.6.2011, 22:35
PM MAIL   Вверх
Absinthe
Дата 21.6.2011, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 4.5.2011

Репутация: 1
Всего: 11



Цитата

Хотел бы я посмотреть на вашу реализацию списка на Php продимонстрируйте всем ваши нестуденческие навыки самый простой пример:

Односвязный список. реализовать функцию push и добавить с помощью нее 5 елементов. И вывести содержимое объекта на экран, осилите?) 
Ато вы нас тут всех студентами обозвали. Продемонстируйте нам ваши супер навыки! Хоть одного балабола с ответами изучайте основы php удастся поймать за язык)) Встроеные классы в php можете нам не демонстрировать. Функция push должна быть полностью реализованна вами. 
 Я думаю, что данный вопрос неуместен в теме, его было бы правильнее задать в разделе о работе.
Ну и в таких случаях принято указывать вознаграждение.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса

Внимание: данный раздел предназначен для решения сложных, нестандартных задач.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Для профи | Следующая тема »


 




[ Время генерации скрипта: 0.0788 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.