Algumas vezes é possível utilizar alguns paradigmas de orientação à objetos em C. Ao se projetar uma biblioteca, podemos encapsular o conteúdo das structs usando tipos incompletos e provendo funções para manipular o conteúdo destas.
Imagine uma biblioteca que cria um “objeto” para representar uma pessoa. Esta biblioteca provê um cabeçalho person.h com funções para manipular o “objeto”.
typedef struct person person; person *person_new(char *name, int age); void person_free(person *handler); void person_print(person *handler);
Note que não existe uma descrição da struct person no cabeçalho. A única forma então de manipular esta struct é usando as funções, porque os atributos da struct não são conhecidos. Esta struct portanto caracteriza um tipo incompleto, mas apenas do ponto de vista dos usuários da biblioteca. Em sua implementação, a biblioteca conhece o conteúdo de person e consegue manipulá-los, como vemos a seguir.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "person.h"
struct person {
char *name;
int age;
};
person *person_new(char *name, int age)
{
person *new = malloc(sizeof(*new));
new->name = strdup(name);
new->age = age;
return new;
}
void person_free(person *handler)
{
free(handler->name);
free(handler);
}
void person_print(person *handler)
{
printf("%s - %d\n", handler->name, handler->age);
}
A vantagem de se encapsular os dados, forçando esta política através da técnica apresentada, é que a implementação da biblioteca pode ser alterada sem impacto em seus clientes. person_new poderia checar a validade do atributo age, retornando um ponteiro nulo caso seja passado uma idade negativa. O código seguinte ilustra um possível cliente da biblioteca, note que não há referência aos atributos de struct person.
#include <person.h>
int main(void)
{
person *mike = person_new("Mike", 21);
person_print(mike);
person_free(mike);
return 0;
}
A primeira vez que vi uma biblioteca fazendo uso extenso desta técnica foi no projeto OpenSync, que inspirou este post.





Encapsulamento em C!!! Me parece ser uma boa para a validação de campos!
Interessante a técnica :D
Usei ela em uma experiência que fiz. Gostaria de saber o que acha:
http://murilo.wordpress.com/2009/08/05/como-programar-em-c-orientado-a-objetos/
Abraço!
Gostei do post.
Existem outras bibliotecas que implementam essa técnica.
No ano passado eu escrevi sobre isso também:
http://blog.blabos.org/2008/05/membros-privados-em-estruturas-c
Abração
E usado largamente este tipo de técnica em códigos relacionados ao GNOME! (Conceitos envolvendo GObject, dados privados, …)
Muito legal!!!
Nunca vi essa nomenclatura de “tipos incompletos”, conheço essa maneira de prover funções para manipular structs pelo nome de “tipos opacos”.
Com tipos opacos, programas utilizam a biblioteca apenas através de referências as estruturas, e realizam operações sobre estas através de funções.
Dessa maneira, a biblioteca esconde detalhes de sua implementação, os programas não devem setar valores diretamente nos campos da estrutura, deve-se sempre utilizar funções da bibilioteca.
Um exemplo de biblioteca que utiliza isso e que vários não perceberam, é quando se manipula arquivos. fopen() retorna um ponteiro para um handler, depois utiliza-se outras funções como ftell(), fwrite() e ao final fclose(), porém em nenhum momento se mexeu diretamente com o handler :)
sqlite e libevent são também exemplos de bibliotecas em C que utilizam-se de tipos opacos.
Espero ter ajudado :)
Ambos os nomes estão corretos. Já vi ambas nomenclaturas, mas a maioria das vezes, Opaque Pointers era usado quando se falava de C++.
http://tinobox.com/wordpress/c-programming/incomplete-types-in-c-programming/
http://www.ibm.com/developerworks/library/pa-ctypes1/
[]‘s
A tradução de termos técnicos é sempre complicada. Em linguagem Scala temos os “companion Objects” os quais traduzí como sendo “objetos complementares”, porém há incontáveis outras possibilidades para esse termo.
Essa é uma dificuldade para a difusão de conceitos de programação em português. Temos que nos adaptar a uma realidade onde a lingua inglesa é predominante.
Na minha opinião, “tipos opacos” soa correto também.