O problema das duplas indirecções manifesta-se para os smart pointers por causa da semântica associada aos objectos que representam ponteiros. O primeiro segmento de código, que não utiliza smart pointers, ilustra um problema de tipos que é proibido pelo compilador, pois permitiria o manuseamento de entidades não relacionáveis pelo facto de terem uma superclasse comum.
class BASE { ... }; class DER1 : public BASE { ... }; class DER2 : public BASE { ... }; void f(BASE **p1, BASE **p2) { *p1 = *p2; } int main(void) { DER1 *d1 = new DER1; DER2 *d2 = new DER2; f(&d1, &d2); // Ilegal em C++, com ponteiros normais. return 0; }
A utilização de smart pointers torna este problema invisível para o compilador, pelo que ele apenas é detectado em tempo de execução. A razão é o facto de, no programa, se ter associado semântica de ponteiro a uma entidade que o compilador não considera como tal. Assim, a conversão entre os ponteiros para os smart pointers tem o aspecto de uma conversão normal de ponteiros para objectos. O segundo segmento de código ilustra precisamente esse caso. Considerem-se definidas, além das classes acima, as respectivas classes de smart pointers: PtrBASE, PtrDER1 e PtrDER2.
//---- Nova declaração da função 'f' void f(PtrBASE *p1, PtrBASE *p2) { *p1 = *p2; } int main(void) { PtrDER1 d1 = new DER1; PtrDER2 d2 = new DER2; // Legal e errado! Quando se utiliza uma hierarquia de // ``smart pointers''. O problema pode ser resolvido // recorrendo a conversões manuais. f(&d1, &d2); return 0; }
O esquema que utiliza envelopes e cartas não evidencia este problema, pois não é associada nenhuma semântica especial aos objectos que o programa vê, os envelopes. No que ao programa diz respeito, os envelopes são os objectos. As cartas nunca são vistas pelo programa.