Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Ссылки и стандартный алгоритм клонирования  (Прочитано 39531 раз)
0 Пользователей и 1 Гость смотрят эту тему.
MasterMan342
Участник

ru
Offline Offline
Пол: Мужской

« : 04-03-2017 20:05 » 

Доброе время суток формучане!
Разбирался тут со ссылками и объектами в пэхе, и вот столкнулся со следующей странностью:

Код: (PHP)
<?php
class test{
    public $a = 3;
    public $b = NULL;
    function __construct(){
        $this->b =& $this->a;
    }
}

$vvv = new test();
$v = clone $vvv;

$vvv->a = 434;
echo $vvv->a, PHP_EOL;
echo $v ->a, PHP_EOL;

Так вот, этот код выводит "434" и "434"... как так?
т.е. я создаю клон объекта стандартной логикой, которая копирует значение каждого свойства одного экземпляра в одноименное свойство другого экземпляра... верно?

Таким образом:

vvv = {
  a = 434,
  b - ссылается на "vvv.a"
};

v = {
  a = 434,
  b - в начальный момент времени ссылалась на "v.a", но после клонирования стала ссылаться на "vvv.a" (по крайней мере должна)
};

но почему изменение "v.a" влияет на "vvv.a"? ведь они не связаны ссылкой!
аналогично, если я даже изменю по ссылке "vvv.b = 111", то и "v.b" и "v.a" будут выдавать это-же изменение...



Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 04-03-2017 20:53 » 

Никто ничего никому не должен. Не надо гадать, а лучше взять и прочитать мануал.
http://php.net/manual/ru/language.oop5.cloning.php

Т.ч. vvv.b по прежнему ссылается на v.a.

И да: PHP не подвержен логическому осмыслению. Только чтение мануала и тесты.
« Последнее редактирование: 04-03-2017 20:55 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
MasterMan342
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 05-03-2017 06:53 » 

Никто ничего никому не должен. Не надо гадать, а лучше взять и прочитать мануал.
http://php.net/manual/ru/language.oop5.cloning.php

Т.ч. vvv.b по прежнему ссылается на v.a.

И да: PHP не подвержен логическому осмыслению. Только чтение мануала и тесты.

Я читал манулал, товарищ администратор... вы невнимательно прочитали и не поняли суть вопроса...
Мне интересно, с какого перепуга изменяется значение "$vvv.a" при изменении "$v.a" (если $v копия), т.к. переменная $a хранит обычное значение, и не является ссылкой...

Вот пример: http://sandbox.onlinephpfunctions.com/code/b9300726e716ee507647f8eeb7f4cd2ed5ca291d
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 05-03-2017 10:30 » 

Цитата
Разбирался тут со ссылками и объектами в пэхе,
В первую очередь - что такое пэха?
Во вторую - это неуважение к языку.
Третье - какое отношение, такое и понимание

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 05-03-2017 10:43 » 

ну и внимательно!!! читаем документацию

Я за вас ее прочту

function __clone()
Цитата
    {
        // Принудительно копируем this->object, иначе
        // он будет указывать на один и тот же объект.
        $this->object1 = clone $this->object1;

Т.е. при clon создается ссылка, и если не описан метод __clon , то и останется ссылкой
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 05-03-2017 15:01 » new

MasterMan342, используй var_dump для распечатки объектов. И $a и $b являются ссылками.

# php -a
Interactive shell

php > class B { public $a = 3; public $b = NULL; function __construct() { echo "CONSTRUCTOR"; $this->b = $this->a; }}
php > $a = new B;
CONSTRUCTOR
php > var_dump($a);
object(B)#1 (2) {
  ["a"]=>
  int(3)
  ["b"]=>
  int(3)
}

php > class C { public $a = 3; public $b = NULL; function __construct() { echo "CONSTRUCTOR"; $this->b = &$this->a; } }
php > $a = new C;
CONSTRUCTOR
php > var_dump($a);
object(C)#1 (2) {
  ["a"]=>
  &int(3)
  ["b"]=>
  &int(3)
}

Умом PHP не понять. Видимо по этому он такой популярный.
В итоге, читаем ман о ссылках.
http://php.net/manual/ru/language.references.php

Занимательная штука, эти ссылки в PHP...
$ php -a
Interactive shell

php > $a = array(1, 2);
php > $x = &$a[0];
php > var_dump($a);
array(2) {
 
  • =>
  &int(1)
  [1]=>
  int(2)
}
php > var_dump($x);
int(1)
php > unset($x);
php > var_dump($x);
PHP Notice:  Undefined variable: x in php shell code on line 1
NULL
php > var_dump($a);
array(2) {
 
  • =>
  int(1)
  [1]=>
  int(2)
}
« Последнее редактирование: 05-03-2017 15:06 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines