nov 172007
 

Blz!

Estava estes dias revisando alguns conceitos no framework GBF[1], quando lembrei que no SpaceShooter[2] tive a necessidade de determinar em runtime de que tipo de classe pertencia um dado objeto, na época resolvi com algo muito simples, criei um método chamado “getType()” que retornava um valor de uma enum (enumeração). Porém esta solução não é genérica o bastante para poder ser reutilizada, e com alguns recursos que estou planejando implementar no framework GBF, começo a ter a necessidade de poder fazer questionamentos em runtime.
Para isso o c++ tem o que chamamos de RTTI (Run-Time Type Identification) que fornece algumas poucas opções – não se compara as capacidades reflexivas que o Java possui, nessa hora que sinto falta do java – uma delas eh por meio do dynamic_cast onde ele funciona da seguinte forma:

TipoClasse * tc = dynamic_cast(objeto)

Onde em caso de erro, ou seja do objeto não pertencer a hierarquia da classe “TipoClasse” ele retorna NULL, caso contrario um ponteiro válido para o objeto do “TipoClasse”.
Resolvi então encapsular o dynamic_cast em um recurso como o “instanceOf” do Java, para isso tive que utilizar templates(generics).

Antes de vermos o código, observemos o diagrama de classes abaixo:

Observemos a classe “ObjetoBase” ela implementa as possibilidades de uso do método “isInstance”, ou seja, funcionará assim, tendo uma instância de uma classe perguntaremos a ela se pertence a um certo tipo de classe ou se é do mesmo tipo de um outro objeto.

Abaixo podemos ver a utilização do código:

Podemos destacar alguns pontos interessantes:

Se você possui um objeto e quer saber se ele pertence a uma dada classe e não possui nenhuma instância da mesma você pode fazer como na linha 30 do código.

Exemplo 1:
sprite.isInstance <Sprite> ();

Essa construção pode parecer estranha mas é comum devido o uso de templates, outras opções são caso você possua uma instância qualquer da classe ou queira cria-la, como nas linhas 42 e 46 respectivamente.

Exemplo 2:
spritePersonagem2->isInstance(new SpritePersonagem());

spriteManager->isInstance(ObjetoManager());

Porém lembramos que estes casos necessitam de um construtor público e que uma nova instância da classe será criada, o que nem sempre é possível ou de bom agrado, por isso quando não for possível instanciar ou ter um objeto da classe utilize o primeiro exemplo.

Agora poderemos ver como de fato é feita esta implementação, observemos a figura/código abaixo:


Podemos observar que a solução é bastante simples e que o código apresentado atende a:

  1. Questionar se um objeto pertence a uma determinada classe;
  2. Questionar se um objeto pertence a mesma classe de um outro objeto;
  3. Questionar se um objeto pertence a mesma classe de um outro objeto por meio de referências;

Espero que quem tenha essas necessidades possa fazer bom uso dessas informações, e lembro que ainda é possível outras implementações, dentre as quais uma que me agradou bastante foi implementar template de funções, aparentemente ficou mais legível, porém não estaria encapsulada em uma hierarquia de classes.

Não esqueça de baixar o souce[3].

T+!
Vida Longa e Próspera!

———————————————-

Referência
[1]http://pjmoo.wiki.sourceforge.net/GBF
[2]http://pjmoo.wiki.sourceforge.net/SpaceShooter
[3]http://downloads.sourceforge.net/pjmoo/ObjetoBase.zip
[4]http://www.codeblocks.org
[5]http://bouml.free.fr

  2 Responses to “InstanceOf em Cpp”

Comments (2)
  1. hum.. não é isso que o RTTI faz? exemplo!class CBase { virtual void f(){} };class CDerived : public CBase {};int main () { try { CBase* a = new CBase; CBase* b = new CDerived; cout << "a is: " << typeid(a).name() << '\n'; cout << "b is: " << typeid(b).name() << '\n'; cout << "*a is: " << typeid(*a).name() << '\n'; cout << "*b is: " << typeid(*b).name() << '\n'; } catch (exception& e) { cout << "Exception: " << e.what() << endl; } return 0;}e a saída éa is: class CBase *b is: class CBase **a is: class CBase*b is: class CDerived

  2. Blz!Tb é um recurso disponível na RTTI, mas só retorna o nome da classe, e no caso eu preciso saber se pertence a uma hierarquia de classes.Veja: http://pt.wikipedia.org/wiki/RTTIhttp://www.cplusplus.com/doc/tutorial/typecasting.html

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(requerido)

(requerido)