next up previous contents index
Next: Invocação com Herança Up: Exemplos de Código Previous: Smart Pointers --

Exemplo Utilizando Open C++

 

No exemplo, por cada vez que um método é invocado, é impressa uma mensagem no écran. A classe do objecto chama-se Person. O objecto é controlado por um metaobjecto, que altera o código da chamada ao objecto.

//---- person.c ----
#include <stdio.h>
#include "prnmetaobj.h"   // Contém a declaração do metaobjecto.

class Person {
    Person(char *name, int age);
    int Age();
//MOP reflect :
    int IncAge();         // Incrementa a idade e retorna-a.

private:
    char *name;
    int   age;
};

A linha que começa com //MOP indica que a execução dos métodos que se seguem é controlada por um metaobjecto. Estes métodos são chamados reflect. Neste caso, apenas o método IncAge é afectado.

//---- person.c (cont.) ----

//MOP reflect class Person : PrintMetaObj;

Person::Person(char *n, int a) { name = n; age = a; }

int Person::Age()              { return   age; }

int Person::IncAge()           { return ++age; }

A segunda linha começada por //MOP, determina que um objecto da classe Person pode ser reflexivo e que o seu metaobjecto é da classe PrintMetaObj. Isto não é rigorosamente verdade, mas é bastante aproximado. Na realidade, o compilador, ao encontrar a linha, vai produzir uma subclasse de Person, refl_Person. Objectos criados a partir de refl_Person são reflexivos, enquanto que os que são criados a partir de Person não são.

O código da classe do metaobjecto é apresentado de seguida.

//---- prnmetaobj.h ----

#include "metaobj.h"    // Classe mãe...

class PrintMetaObj : public MetaObj {
public:
    void Meta_MethodCall(Id method_id, Id category,
                         ArgPac &args, ArgPac &reply);
};

//---- prnmetaobj.c ----

#include <stdio.h>
#include "prnmetaobj.h"

void PrintMetaObj::Meta_MethodCall(Id method_id, Id category,
                                   ArgPac &args, ArgPac &reply)
{
    printf("*** %s was called.\n", Meta_GetMethodName(m_id));
    Meta_HandleMethodCall(m_id, args, reply);
}

A classe PrintMetaObj redefine o método Meta_MethodCall para escrever uma mensagem por cada chamada a um dos métodos reflect. Os quatros argumentos do método representam o identificador, method_id, a categoria, category, uma referência para os dados de entrada do método, args, e uma referência para os dados de retorno, reply. O método original, neste caso IncAge, é executado por Meta_HandleMethodCall, que recebe o seu identificador. No fim da execução do método Meta_MethodCall, o valor referenciado por reply é passado ao chamador como valor de retorno do método chamado, IncAge (ver figura 2.4).



David M. M. de Matos
Thu Jun 29 14:58:09 MET DST 1995