Chiamando lo stesso metodo su oggetti diversi - Ricorsione?

3

Ho un oggetto che contiene un riferimento a un altro oggetto dello stesso tipo. Esempio in PHP:

class A {
    protected $child;
    public function __construct(A $child = null) {
        $this->child = $child;
    }

    public function go() {
        if($this->child) {
            $this->child->go();
        }
    }
}

$a = new A(new A());
$a->go();

Il metodo go è considerato un metodo ricorsivo? Posso vederlo in entrambe le direzioni, e non sono sicuro che ci sia una risposta 'corretta' o meno, ma presumo che ci sia.

    
posta Jeff Lambert 17.07.2014 - 17:05
fonte

2 risposte

2

È ricorsivo , poiché lo stack di chiamate deve crescere. È necessario inserire un nuovo frame di chiamata (alla funzione same ).

Se il metodo go chiama un altro metodo foo (anche su una classe non correlata) che richiama di nuovo go sulla stessa classe, avresti un ricorsione reciproca ...

Un altro modo di vedere che sta rilevando che la chiamata al metodo è solo una fase dispatch (calcolando quale funzione dovrebbe essere veramente chiamato a seconda del ricevitore), seguito da una chiamata di funzione (il cui primo argomento è il ricevitore).

Tuttavia, leggi le chiamate a coda (o ricorsione a coda ). Permette di sostituire il frame di chiamata corrente con quello appena chiamato (senza far crescere lo stack di chiamate).

I buoni compilatori implementano una coda chiamata come un "salto con argomenti"; leggi anche stile di passaggio continuo

    
risposta data 17.07.2014 - 17:08
fonte
3

L'istanza su cui viene invocato il metodo (il ricevitore del messaggio , in termini Smalltalk) viene in genere trattato come un parametro implicito, zeroth, per il metodo.

Quindi un metodo come

public function go()

che non accetta argomenti può essere pensato come effettivamente prendendo un argomento, chiamato $this , di tipo A :

public function go(A $this)

E una chiamata a quel metodo, inviata su qualche particolare istanza di A , potrebbe quindi essere pensata, non come scritta

$this->child->go()

ma scritto in questo modo:

go($this->child)

Se guardato in questi termini, diventa chiaramente una chiamata ricorsiva. (Il compilatore Cfront C ++, agli albori del C ++, tradusse C ++ in codice C come questo, che fu poi compilato con un compilatore C.)

    
risposta data 17.07.2014 - 18:54
fonte

Leggi altre domande sui tag