Pode observar-se na figura 6.1 que o caminho através do qual o envelope tem que aceder à carta é não tipificado. A necessidade para esta construção impõe-se devido ao significado especial que o compilador de C++ atribui aos ponteiros para instâncias de classes. Em particular, o compilador pode proibir algumas conversões, mesmo que estas não sejam semanticamente incorrectas, e.g. conversão, partindo de um ponteiro para uma classe derivada, para um ponteiro de uma superclasse.
A estrutura SPM_quot
LL_Letter", que representa uma carta genérica e que
se designará por CAGE, existe para garantir o correcto funcionamento
do modelo e coerência nos acessos aos objectos na presença das
conversões de tipos de C++. Não sendo tipificada a referência para a
carta em si, o funcionamento vai depender de conversões feitas em
tempo de execução.
Qualquer envelope contém no seu interior uma CAGE. Note-se que a
noção de carta é algo relaxada neste caso, designando qualquer objecto
que possa ser utilizado de forma semelhante à de uma carta, e.g. um
representante. O objecto real, criado a partir da classe do
programador, segundo o tipo com o qual foi declarado, é guardado como
SPM_quot
void*" no interior de uma CAGE. O tipo real do objecto é
recuperado quando necessário, e.g. para realizar uma invocação.
Existem dois campos numa CAGE: o ponteiro para o objecto, letter, e o campo de identificação do tipo, typeid. A declaração da classe é a que se apresenta de seguida.
struct LL_Letter { void *letter; LL_TypeId typeid; };
A macro SPM_quot
LL_LETTER_INI(type,var,initexpr)" permite inicializar
CAGEs. type é o nome do tipo do objecto no interior, que será
passado à macro SPM_quot
LL_TYPEID_INI", que inicializa o campo
respeitante ao tipo (ver secção 6.2.3). var é uma
CAGE, que será inicializada com o retorno da expressão initexpr.
Esta macro é utilizada de forma automática pelo código dos envelopes
para criação de cartas, nunca sendo visível no código do programador.
A macro SPM_quot
LETENV_CTOR(type,args...)", utilizada para definir
construtores de envelopes a partir dos das cartas faz uso da macro
acima ( size é um campo de SPM_quot
LL_Envelope" que representa a
dimensão real do objecto na CAGE). Nesta macro, seguindo o exemplo
acima, SPM_quot
type" é igual a SPM_quot
Line", e SPM_quot
args", se existirem,
o conjunto de argumentos do construtor original da carta.
#define LETENV_CTOR(type,args...) \ { \ size = sizeof(type##Letter); \ LL_LETTER_INI(type##Letter,letter,new type##Letter(args)); \ }