Che Stanley intende per “ricorsiva” è solo che l'operatore è applicato a ogni oggetto restituito fino la il tipo restituito è un puntatore.
Che succede qui al primo tentativo: screen::operator ->
restituisce un puntatore. Quindi questa è l'ultima chiamata a un operator ->
che il compilatore tenta. Risolve quindi il sorso destro dell'operatore (p
) cercando un membro nel tipo di punta restituito (dummy
) con quel nome.
In sostanza, quando il compilatore trova la sintassi aᵢ->b
in codice, vale essenzialmente il seguente algoritmo:
- È
aᵢ
di tipo puntatore? In tal caso, risolvere il membro b
di *aᵢ
e chiamare (*aᵢ).b
.
- Else, cercare di risolvere
aᵢ::operator ->
- In caso di successo, insieme
aᵢ₊₁ = aᵢ::operator ->()
. Goto 1.
- In caso di errore, emettere un errore di compilazione.
Sono difficoltà a venire con una breve, significativo esempio dove un catena di operator ->
invocazioni rende ancora senso. Probabilmente l'unico vero uso è quando scrivi una classe puntatore intelligente.
Tuttavia, il seguente esempio di giocattolo almeno compila e produce un numero. Ma non consiglierei davvero di scrivere questo codice. Rompe l'incapsulamento e fa piangere i gattini.
#include <iostream>
struct size {
int width;
int height;
size() : width(640), height(480) { }
};
struct metrics {
size s;
size const* operator ->() const {
return &s;
}
};
struct screen {
metrics m;
metrics operator ->() const {
return m;
}
};
int main() {
screen s;
std::cout << s->width << "\n";
}
fonte
2012-05-05 09:56:30
Dove si dice che è "applicato in modo ricorsivo"? –
No, non sono d'accordo sul fatto che l'esempio funzioni come previsto, l'operatore -> è semplicemente una chiamata di funzione, in sostanza, perché dovrebbe eseguire il drill down? Se lo fa, come controlleresti a quale livello smettere di dereferenziare e renderebbe ancora più complicato l'ereditarietà e il polimorfismo di quello che è già – EdChum
Primer C++, quarta edizione di Stanley B. Lippman, sezione 14.6 ultimo paragrafo. – user1232138