C orientado a objeto?

Vocês se lembram daqueles tópicos sobre ponteiros para funções? Eles me inspiraram a fazer um pequeno teste. Vocês já devem ter ouvido falar que a principal diferença entre structs e classes é que a primeira não pode ter funções dentro de si e que a segunda pode. Acabei de descobrir que é possível burlar essa limitação e com uma pequena gambiarra deixar o C uma linguagem mais voltada a objetos.

Se você ainda não leu os artigos sobre ponteiros para funções, dê uma lida pelo menos no primeiro, apenas para saber do que se trata. Depois de feita a leitura, vamos para um passo-a-passo do que foi feito. Primeiro, a definição de uma nova struct:

typedef struct {
void (*function)();
int i;
} class;

Você pode confirmar que estamos usando C e não C++, já que se fosse usado o segundo, ele daria um erro devido o mau uso da palavra class. O que foi feito aqui é bem simples: definimos uma estrutura com um ponteiro para uma função e um inteiro. Agora o segundo passo:

void fnc( class *this )
{
this->i++;
printf( "Function called %d time(s).\n", this->i );
}

Agora definimos a função que será usada pela estrutura a cima. Infelizmente, não temos um jeito de ter acesso ao this que teríamos no C++. Isso pode ser contornado colocando como argumento um ponteiro. Essa parte ainda será objeto de estudos.

A terceira parte é a criação de um constructor. Já que não estamos trabalhando de fato com uma classe, o ponteiro para a função começa vazio; temos então que ajustar tudo manualmente e para facilitar criamos uma função com esse propósito:

class Class()
{
class a;

a.i = 0;
a.function = &function;
printf( "Constructor called.\n" );
return a;
}

Agora quando estivermos dentro do main, criamos uma nova instância dessa estrutura/classe usando esse construtor. O único problema é a falta de um
this
. Sem ele, não temos como acessar informações de dentro da struct sem passá
-la por referência, o que torna o esse método pouco prático. Talvez haja um jeito de
fazer o que eu quero usando macros.

O código todo:

#include <stdio.h>

typedef struct {
        void (*function)();
        int i;
} class;

void function( class *this )
{
        this->i++;
        printf( "Function called %d time(s).\n", this->i );
}

class Class()
{
        class a;

        a.i = 0;
        a.function = &function;
        printf( "Constructor called\n" );
        return a;
}

int main( int argc, char* argv[] )
{
        int count;

        class test = Class();

        for( count = 0; count < 10; count++ )
                test.function( &test );

        return 0;
}
Publicado em C. Tags: , . 2 Comentários »

2 Respostas para “C orientado a objeto?”

  1. Diogo diz:

    Parabéns pelo post.
    Muito útil.
    Já vou aplicar isso ae.
    Um abraço.

  2. Tiago Natel de Moura diz:

    Cara, gostei do seu blog. Você leva o raciocínio a fundo mesmo, a galera do C costuma falar muito e codar pouco. hehe

    Sobre o C orientado eu também já me aventurei a brincar com os ponteiros de funções para simular uma pequena orientação. Só que o meu raciocínio tava bem diferente do seu, eu parti do pressuposto de que tudo era “tipo”, ao invés do conhecido tudo é “objeto”. Aí defini um tipo “Object”, um tipo “Class” e um tipo “method”. O problema é que uma biblioteca em C para tentar simular OO não poderia (eu acredito) dar a possibilidade de utilizar o paradigma da orientação mesmo, como Herança, Polimorfismo, encapsulamento, etc, porque isso seria implementado pelo usuário (o desenvolvedor) da biblioteca.
    Por isso a necessidade de um outro compilador, como é no caso do C++. Na verdade, outra linguagem.

    Voce já viu como é a Orientação à objetos em javascript?
    function Person()
    {
    this.andar = function()
    {
    /** andando */
    }

    this.parar = function()
    {
    /** parar */
    }
    }

    var aleteia = new Person();
    aleteia.andar();
    aleteia.parar();

    Era dessa maneira que eu estava querendo fazer, passando o ponteiro das funções para as variaveis locais da classe (no caso a estrutura).

    Olha esse link http://www.planetpdf.com/codecuts/pdfs/ooc.pdf
    Aí o cara cria uma orientação completa em C ANSI, mas nada funcional ¬¬

    falow.


Deixe uma resposta