Sie sind auf Seite 1von 71

UNIVERSIDADE DE ITANA

FACULDADE DE ENGENHARIA
CINCIA DA COMPUTAO

MICHAEL DOUGRAS DA SILVA

ORM4Qt: Biblioteca de Mapeamento Objeto


Relacional em C++ para o Framework Qt

Itana
2014

UNIVERSIDADE DE ITANA
FACULDADE DE ENGENHARIA
CINCIA DA COMPUTAO

MICHAEL DOUGRAS DA SILVA

ORM4Qt: Biblioteca de Mapeamento Objeto


Relacional em C++ para o Framework Qt
Trabalho de Concluso de Curso apresentado
como requisito parcial para obteno do ttulo de Bacharel em Cincia da Computao
da Faculdade de Engenharia da Universidade
de Itana.

Orientador:

Anglica Aparecida Moreira

Itana
2014

ORM4Qt: Biblioteca de Mapeamento Objeto Relacional em C++ para o


Framework Qt
Michael Dougras da Silva

Este trabalho foi julgado adequado para obteno da aprovao na disciplina Trabalho
de Concluso do Curso de Cincia da Computao da Faculdade de Engenharia da Universidade de Itana.

Aprovado por:

Anglica Aparecida Moreira

Paulo de Tarso Gomide Castro Silva

Itana, 05 de Junho de 2014.

Dedico este trabalho primeiramente minha famlia e amigos, por estarem sempre presentes
nos momentos em que preciso e por me apoiarem durante todo este tempo. Dedico tambm aos
meus amigos de classe e professores, que contriburam para tornar estes ltimos 4 anos em uma
das pocas inesquecveis da minha vida.

Agradecimentos

Agradeo primeiramente a Deus, pela oportunidade de estar aqui hoje concluindo


este trabalho. Agradeo aos meus pais por terem me apoiado incondicionalmente durante
toda minha vida. Agradeo aos meus irmos pelo incentivo e compreenso apresentados
durante os momentos difceis. Agradeo aos meus amigos por me tirarem de vez em
quando do ambiente de estudos (todo mundo precisa de uma folga de vez em quando) e
por me entenderem nos momentos em que eu tive que me ausentar.
No poderia deixar de agradecer aos meus professores e amigos de classe. Graas
a vocs, hoje estou preparado para seguir em frente e encarar novos desafios. E tenho
certeza de que fiz aqui, amigos para a vida toda. Muito obrigado, por tudo.

Resumo
As Linguagens Orientadas a Objetos em conjunto com os Sistemas Gerenciadores de
Bancos de Dados Relacionais (SGBDs) so considerados padres no desenvolvimento de
Sistemas de Informao Empresarial. Embora o uso destas duas tecnologias em conjunto mostre resultados satisfatrios, encontra-se dificuldade em efetuar a transio de
informaes entre os seus contextos de representao de dados.
Para efetuar a transio de informaes necessrio desenvolver componentes de
software especficos para cada classe que represente dados que necessitam ser persistidos
no banco de dados, o que se mostra uma tarefa repetitiva e propensa a erros. Com o
objetivo de amenizar este problema, foram criadas as Bibliotecas de Mapeamento Objeto
Relacional (ORMs), que so componentes de software capazes de automatizar o processo
de transio de dados entre os dois contextos.
Devido a limitaes nos recursos de reflexo e insero de metadados oferecidos pela
linguagem C++, o desenvolvimento de solues ORM para esta linguagem se mostra uma
tarefa bastante complexa. A maioria das solues implementadas apresenta interfaces de
configurao complexas, alm de utilizar recursos da linguagem que promovem o aumento
do nvel de acoplamento do cdigo.
Este trabalho prope o desenvolvimento de uma biblioteca ORM para a linguagem
C++, onde so implementados mecanismos prprios de reflexo e insero de metadados a
partir da utilizao dos novos recursos propostos pela especificao C++11. A biblioteca
utiliza vrios componentes oferecidos pelo framework Qt para auxiliar em tarefas como
comunicao com banco de dados e extenso de tipos nativos.
Palavras-chave: Orientao a Objetos, SGBD, C++, ORM

Abstract
The Object Oriented Languages combined with the Relational Database Management
Systems (RDBMs) are considered a pattern in Enterprise Information Systems (EIS)
development. Although their use show good results, is difficult to perform the information
transition between their contexts of data representation.
To perform the information transition it is necessary to develop specific software
components for each class that represents data persisted in the database, task that shows
itself repetitive and error prone. With the goal of ease this problem, we created the Object
Relational Mapping (ORM) libraries, software components that automates the process of
data transition between the two contexts.
Due to limitations in the C++ reflection and metadata insertion features, the development of ORM solutions for this language is a very complex task. The existent solutions
present complex configuration interfaces, besides using language resources that increase
the coupling level of code.
This paper proposes the development of a ORM library for the C++ language, using
own mechanisms of reflection and insertion of metadata based on the features of the
C++11 specification. The library uses many components offered by the Qt framework to
help in tasks like communication with the database and extension of native types.
Keywords: Object Oriented, RDBMS, C++, ORM

Glossrio
API

: Application Programming Interface;

ORM

: Object Relational Mapping;

SGBD

SQL

: Structured Query Language;

EIS

: Enterprise Information Systems;

Sistema Gerenciador de Banco de Dados;

Sumrio

1 Introduo

2 Fundamentao Terica

2.1

Orientao a Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.2

A Linguagem de Programao C++ . . . . . . . . . . . . . . . . . . . . . .

2.2.1

Reflexo ou Introspeco . . . . . . . . . . . . . . . . . . . . . . . .

2.2.2

Processo Evolutivo da Linguagem . . . . . . . . . . . . . . . . . . .

2.2.2.1

Listas de Inicializao . . . . . . . . . . . . . . . . . . . .

2.2.2.2

Navegao em Grupos de Elementos . . . . . . . . . . . . 10

2.2.2.3

Novo Identificador para Ponteiros Nulos . . . . . . . . . . 12

2.2.2.4

Inferncia de Tipos . . . . . . . . . . . . . . . . . . . . . . 14

2.2.2.5

Programao Funcional . . . . . . . . . . . . . . . . . . . 16

2.2.2.6

Ponteiros Inteligentes (Smart Pointers) . . . . . . . . . . . 20

2.3

O Framework Qt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

2.4

Sistemas Gerenciadores de Bancos de Dados Relacionais . . . . . . . . . . 25

2.5

O PostgreSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

2.6

A combinao de SGBDs com Linguagens Orientadas a Objetos . . . . . . 26

2.7

Bibliotecas de Mapeamento Objeto Relacional . . . . . . . . . . . . . . . . 28

3 Trabalhos Relacionados
3.1

31

Um Framework de Mapeamento Objeto Relacional com um Exemplo em


C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Sumrio

viii

3.2

QxORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

3.3

ODB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

3.4

Hibernate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

4 A Biblioteca ORM4Qt

35

4.1

Arquitetura em Camadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.2

Camada Objeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.3

4.2.1

Quebrando o Encapsulamento das Classes . . . . . . . . . . . . . . 38

4.2.2

Inserindo Metadados Atravs de Anotaes . . . . . . . . . . . . . . 40

Camada de Armazenamento . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5 Testes
5.1

5.2

44

Ambiente de Testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
5.1.1

Ambiente de Testes Ubuntu 14.04 . . . . . . . . . . . . . . . . . . . 45

5.1.2

Ambiente de Testes Microsoft Windows 8.1 . . . . . . . . . . . . . . 46

O Projeto Minhas Apostilas . . . . . . . . . . . . . . . . . . . . . . . . . 47


5.2.1

A Classe Documento . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.2.1.1

Mapeamento com a Biblioteca ORM4Qt . . . . . . . . . . 49

5.2.1.2

Mapeamento com a Biblioteca ODB . . . . . . . . . . . . 50

5.2.1.3

Mapeamento com a Biblioteca QxOrm . . . . . . . . . . . 52

5.2.2

A Classe IRepository . . . . . . . . . . . . . . . . . . . . . . . . . . 54

6 Concluso

56

Referncias Bibliogrficas

58

Lista de Figuras

2.1

Linha do tempo: evoluo da especificao da linguagem C++ . . . . . . .

2.2

Sintaxe bsica das expresses lambda . . . . . . . . . . . . . . . . . . . . . 18

2.3

Janela no GNU/Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

2.4

Janela no Microsoft Windows XP . . . . . . . . . . . . . . . . . . . . . . . 23

2.5

Janela no Mac Os . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

2.6

Exemplo de definio de tabelas e relaes . . . . . . . . . . . . . . . . . . 26

4.1

Interao entre componentes do software e desenvolvedor . . . . . . . . . . 37

4.2

Diagrama simplificado das classes de reflexo . . . . . . . . . . . . . . . . . 41

4.3

Diagrama de classes simplificado da camada de armazenamento . . . . . . 43

5.1

Tela inicial do programa Minhas Apostilas . . . . . . . . . . . . . . . . . . 47

Lista de Algoritmos

Definio de uma classe simples em C++ . . . . . . . . . . . . . . . . . . .

Inicializao de vetores e estruturas container . . . . . . . . . . . . . . . . . 10

Acesso sequencial via ndice . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Acesso sequencial via iteradores . . . . . . . . . . . . . . . . . . . . . . . . . 11

Acesso sequencial com nova sintaxe (C++11) . . . . . . . . . . . . . . . . . 12

Novo identificador para ponteiros nulos . . . . . . . . . . . . . . . . . . . . . 13

Trecho de declarao longo . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

Trecho de declarao curto usando auto . . . . . . . . . . . . . . . . . . . 14

Particularidade do uso da palavra-chave auto . . . . . . . . . . . . . . . . 15

10

Deduo de tipo com o uso da palavra-chave decltype . . . . . . . . . . . 15

11

Sintaxe para utilizao de ponteiros para funes e mtodos . . . . . . . . . 17

12

Unificao da representao de ponteiros para mtodos e funes . . . . . . 18

13

Exemplo de definio de uma expresso lambda . . . . . . . . . . . . . . . . 20

14

Utilizando smart pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

15

Exemplo de comunicao com SGBD utilizando o mdulo QtSql . . . . . . . 27

16

Obtendo o nome da classe de um objeto em tempo de execuo . . . . . . . 38

17

Exemplo de variaes na declarao de mtodos acessadores para atributos


tipo inteiro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

18

Retornando uma expresso lambda para acesso de atributo privado . . . . . 40

19

Esboo da utilizao de macros para registro de metainformao . . . . . . 42

20

Definio da classe Documento . . . . . . . . . . . . . . . . . . . . . . . . . 48

21

Mapeamento da classe Documento com a biblioteca ORM4Qt . . . . . . . . 50

LISTA DE ALGORITMOS

11

22

Mapeamento da classe Documento com a biblioteca ODB . . . . . . . . . . 51

23

Mapeamento da classe Documento com a biblioteca QxOrm . . . . . . . . . 53

24

Definio da classe IRepository<T> . . . . . . . . . . . . . . . . . . . . . 54

Captulo 1
Introduo

Vivemos em uma era onde os sistemas informatizados deixaram de ser vistos como meras
ferramentas de automatizao de tarefas. Onde o software desempenha papel fundamental
no planejamento estratgico e desempenho de atividades nas grandes empresas. A proliferao de Sistemas de Informao Empresarial (Enterprise Information Systems
- EIS) se mostra cada vez mais notria. Estes sistemas so caracterizados por sua alta
complexidade e por trabalharem com gerenciamento constante de dados [Lhotka, 2009].
As Linguagens Orientadas a Objetos se tornaram um padro consolidado no
desenvolvimento destes sistemas. Devido sua capacidade de abstrair representaes de
entidades do mundo real como componentes de software, estas linguagens permitem aos
arquitetos e engenheiros de software terem uma viso de alto nvel durante o planejamento
e especificao do sistema [Nierstrasz, 1989].
Os Sistemas Gerenciadores de Bancos de Dados Relacionais (SGBDs) so o
meio consolidado para armazenamento de dados estruturados. Eles permitem o armazenamento de informaes de tal forma que estas podem ser manipuladas atravs de comandos
em linguagem SQL ou Structured Query Language. Esta linguagem permite executar
operaes de insero, remoo, edio e gerao de consultas de alta complexidade nos
dados armazenados [Barnes, 2007].
Apesar de as linguagens orientadas a objetos serem utilizadas em conjunto com os
SGBDs no desenvolvimento de sistemas, a forma de representao dos dados nos dois
contextos diferente. No contexto orientado a objetos, as informaes so vistas sobre
uma perspectiva comportamental, onde os componentes do software so importantes no
somente pelos dados que eles contm, mas pela habilidade de se comunicar com outros
componentes para compartilhar estas informaes e executar aes sobre elas. J no

1 Introduo

contexto dos SGBDs, as informaes so vistas sobre uma perspectiva estrutural, onde o
objetivo principal das entidades armazenar os dados e representar suas relaes da forma
mais otimizada possvel. No existe a preocupao em se definir o comportamento das
informaes. Devido a essa diferena de representao de dados entre os dois contextos,
existe a necessidade de converso ou mapeamento durante a transio entre eles. A
gerao de cdigo para mapeamento se mostra uma tarefa repetitiva e propensa a erros.
Com o objetivo de otimizar a utilizao das linguagens orientadas a objetos em conjunto com os SGBDs surgiu o conceito de Biblioteca de Mapeamento Objeto Relacional ou ORM (Object Relational Mapping). Este tipo de biblioteca tem como objetivo
automatizar as tarefas de mapeamento dos dados entre os dois contextos. Sua utilizao promove maior produtividade e reduo da complexidade envolvida em tarefas de
manuteno e modificao do cdigo [Barnes, 2007]. Neste trabalho proposto o desenvolvimento de uma biblioteca ORM para a linguagem C++. O framework Qt
utilizado como auxlio para comunicao com os SGBDs, e extenso dos tipos nativos da
linguagem C++.
Os demais captulos deste trabalho encontram-se organizados da seguinte maneira:
O Captulo 2 apresenta os conceitos bsicos para a correta compreenso do trabalho. O
Captulo 3 apresenta os trabalhos correlatos. O Captulo 4 apresenta as caractersticas
da biblioteca desenvolvida no trabalho, bem como a metodologia e as tcnicas utilizadas
no seu desenvolvimento. O Captulo 5 apresenta a metodologia de testes utilizada para
validao e comparao da biblioteca desenvolvida com duas bibliotecas existentes no
mercado. E, por fim, o Captulo 6 apresenta a concluso do trabalho, onde so descritos
os resultados encontrados e sugestes de trabalhos futuros.

Captulo 2
Fundamentao Terica

Neste captulo so apresentados os conceitos bsicos utilizados ao longo do trabalho,


situando-os dentro do problema a ser resolvido.

2.1

Orientao a Objetos

Um conceito bastante difundido tanto no meio acadmico quanto no mercado so as


Linguagens Orientadas a Objetos, que so linguagens de programao que utilizam
um paradigma ou padro de estruturao de cdigo que permite que o desenvolvedor crie
abstraes no contexto do software para modelar objetos ou entidades do mundo real
[Nierstrasz, 1989].
No existe uma definio universal que diga quais so as caractersticas ou funcionalidades que uma linguagem de programao deve apresentar para ser considerada orientada
a objetos [Nierstrasz, 1989]. Porm, de maneira geral, elas possuem mecanismos que permitem agrupar dentro de uma unidade de software, estruturas para prover informaes de
estado, comportamento e identidade [Barnes, 2007]. Este agrupamento de estruturas
dentro de uma unidade conhecido como encapsulamento.
Esta unidade de software que representa o estado, comportamento e identidade de
uma entidade conhecida como objeto. Um objeto criado a partir de um modelo
preestabelecido que define todas as estruturas internas que o compe. Este modelo
conhecido como classe [Nierstrasz, 1989]. Algumas linguagens no oferecem mecanismos
explcitos para criao de classes, porm oferecem suporte instanciao de objetos. Um
exemplo de linguagem que apresenta esta caracterstica a linguagem Javascript 1 .
1

Linguagem interpretada com tipagem dinmica baseada em scripts muito utilizada em programao

2.1 Orientao a Objetos

O estado de um objeto definido a partir da adio de variveis em sua estrutura


interna para armazenamento de valores. Estes valores podem ser unitrios (onde so
armazenados dados do tipo texto ou numrico, por exemplo), ou podem ser compostos
(onde so utilizados outros objetos para compor a estrutura interna). As variveis internas
de um objeto so conhecidas como atributos ou propriedades e a utilizao de valores
compostos na definio da estrutura de uma classe um mecanismo conhecido como
composio [Nierstrasz, 1989].
O comportamento de um objeto definido a partir da adio de funes em sua estrutura interna. Elas so utilizadas para efetuar operaes sobre os atributos que o objeto
contm, ou para efetuar processamento de dados baseados no estado ou objetivo do objeto
ao qual ela pertence. Estas funes so conhecidas como mtodos [Nierstrasz, 1989].
O conjunto de atributos e mtodos de uma classe define o que chamamos de interface.
Algumas linguagens permitem reduzir a interface de um objeto de forma que nem todas as
estruturas internas sejam acessveis externamente. Um exemplo a linguagem C++, que
nos permite utilizar os modificadores "private" (estruturas no acessveis externamente)
e "public" (estruturas acessveis externamente).
A identidade de um objeto se refere capacidade de se referenciar instncias de objetos
de maneira unvoca, ou seja, se refere capacidade de se distinguir diversas instncias
de objetos entre si atravs de algum mecanismo de comparao [Nierstrasz, 1989]. Em
algumas linguagens este mecanismo se baseia no endereamento de memria ocupado
pela instncia do objeto, como o caso da linguagem C++. J em outras linguagens
existem mecanismos que permitem a criao de funes de comparao, como acontece
por exemplo na linguagem JAVA onde podemos definir o mtodo "equals" das classes
criadas.
Um exemplo de definio de uma classe utilizando a linguagem C++ apresentado
no trecho de cdigo 1, para demonstrar os conceitos explicados anteriormente. No cdigo
definida a estrutura de uma classe que representa uma pessoa. A classe foi definida com
o identificador Pessoa (linha 1), possui dois atributos internos para armazenar o nome
e sobrenome (linhas 3 e 4) e um mtodo que retorna o nome completo de uma pessoa
atravs da combinao do seu nome e sobrenome (linha 6). Os atributos no so acessveis
externamente devido ao modificador de acesso "private" utilizado na linha 2. J o mtodo
acessvel devido ao modificador de acesso "public" utilizado na linha 5.
Mecanismos de encapsulamento (mtodos, atributos e restrio de interface), definipara a WEB e como complemento para interfaces com linguagens e/ou programas complexos.

2.1 Orientao a Objetos

1
2
3
4
5
6
7

c l a s s Pessoa {
private :
s t r i n g m_nome ;
s t r i n g m_sobrenome ;
public :
s t r i n g nomeCompleto ( ) { r e t u r n m_nome + m_sobrenome ; }
}

Algoritmo 1: Definio de uma classe simples em C++


o de classes e instanciao de objetos so as caractersticas mais comumente encontradas nas linguagens consideradas como orientadas a objetos. Porm, existem mecanismos
mais avanados que permitem uma melhoria na definio do comportamento das classes e promovem reaproveitamento de cdigo. Entre os principais esto a herana e o
polimorfismo [Nierstrasz, 1989].
A herana consiste na capacidade de uma classe estender a estrutura de uma classe j
definida. Isso significa que a nova classe mantm a interface da anterior e tem a capacidade
de adicionar novos atributos e mtodos a ela [Nierstrasz, 1989]. Algumas linguagens
oferecem somente suporte para herana simples, onde uma classe pode herdar de somente
uma outra classe, porm geralmente definem mecanismos alternativos de extenso. Um
exemplo a linguagem JAVA. Outras linguagens oferecem suporte para herana mltipla,
onde uma classe pode estender as funcionalidades de uma ou mais classes j definidas.
Um exemplo de linguagem com esta caracterstica a linguagem C++.
Algumas notaes so utilizadas para demonstrar a utilizao do mecanismo de herana. Por exemplo, quando criamos uma classe B que herda de uma classe A, dizemos
que A a classe base ou pai, enquanto a B uma classe especializada ou filha.
Uma caracterstica importante a observar que ao declararmos um objeto da classe B,
este objeto poder ser utilizado em contextos onde esperado um objeto da classe A
[Nierstrasz, 1989].
Ao utilizar o mecanismo de herana, algumas linguagens permitem a modificao
de um mtodo existente na classe base. Este mecanismo utilizado para especializar
o comportamento herdado na nova classe, mantendo um mesmo padro de interface.
Quando isto acontece temos um impasse a ser resolvido. Quando um objeto de uma classe
filha com mtodos especializados for utilizado em um contexto como um objeto da classe
pai, ao chamar este mtodo, dever ser executada a implementao da classe pai ou da
classe filha? Quando desejamos que a implementao da classe filha seja utilizada, surge o
conceito de polimorfismo, onde o comportamento de um objeto mantido consistente em

2.2 A Linguagem de Programao C++

relao sua definio no importa em qual contexto ele seja utilizado [Nierstrasz, 1989].
Em algumas linguagens como JAVA o polimorfismo implcito, ou seja, na pergunta
anterior se desejssemos que a implementao da classe pai fosse executada, isso no seria
possvel. J em outras linguagens como C++, o polimorfismo definido explicitamente
atravs do uso de palavras-chave da linguagem.
Ao analisar todas estas caractersticas citadas, percebemos que as linguagens orientadas a objetos promovem a criao de entidades de software bem descritivas. Isto facilita
sua utilizao por arquitetos e engenheiros de software, que podem visualizar os elementos
envolvidos no desenvolvimento com uma viso de mais alto nvel. Talvez esta seja a razo
da vasta aceitao e utilizao destas linguagens. Neste trabalho utilizada a linguagem
orientada a objetos C++, a qual detalhada na seo 2.2.

2.2

A Linguagem de Programao C++

A linguagem C++ uma linguagem orientada a objetos criada em 1980 por Bjarne
Stroustrup. uma linguagem compilada, ou seja, o cdigo criado pelo desenvolvedor
convertido atravs de um programa denominado compilador para uma linguagem nativa
de uma plataforma alvo, gerando um ou mais arquivos executveis. Estes arquivos so
passveis de execuo direta na plataforma sem a interveno de ferramentas externas
[Bueno, 2002].
A linguagem C++ foi construda com base na linguagem C. Inicialmente o cdigo
escrito em C++ era traduzido para C e compilado com compiladores desta linguagem.
Com o aumento da complexidade de implementao das caractersticas e funcionalidades que foram surgindo na linguagem ao longo de sua existncia, surgiram compiladores
especficos para C++ [Brokken and Kubat, 2014].
Dentre as caractersticas da linguagem esto a capacidade de definio de classes,
utilizao de herana mltipla, utilizao de polimorfismo, gerenciamento de memria
controlado pelo desenvolvedor e compatibilidade com cdigos escritos em C. Outra importante caracterstica da linguagem a sua no portabilidade, ou seja, o cdigo gerado
para uma plataforma (sistema operacional e/ou hardware especfico) geralmente no
compatvel com outras plataformas. Devido a isso, a linguagem possui uma biblioteca
padro bem reduzida, no oferecendo por exemplo bibliotecas de comunicao em rede e
utilizao de banco de dados [Bueno, 2002].

2.2 A Linguagem de Programao C++

Existe uma grande dificuldade em se desenvolver programas voltados para diversas


plataformas utilizando a linguagem, pois quando comeamos a utilizar funcionalidades
um pouco mais avanadas temos que utilizar implementaes especficas para cada plataforma. Como tentativa de diminuir esta dificuldade foram criadas bibliotecas e frameworks 2 multiplataformas para a linguagem [Thelin, 2007]. Neste trabalho utilizado
o Framework Qt que ser descrito na seo 2.3.
A seguir so descritas caractersticas da linguagem presentes em contextos bem especficos e que interferiram bastante no desenvolvimento da biblioteca ORM proposta neste
trabalho. Tambm descrito o modelo de projeo do processo evolutivo da linguagem,
onde so ressaltados mecanismos introduzidos na especificao C++11 e C++14 que
contriburam para eliminar ou amenizar algumas limitaes da linguagem.

2.2.1

Reflexo ou Introspeco

Algumas vezes nos deparamos com a tarefa de desenvolver rotinas que dependem do
conhecimento da estrutura de um objeto qualquer. Problemas como escreva uma funo
que mostre o nome dos atributos de um objeto ou escreva uma funo que armazene em
um arquivo o valor de todos os atributos de um objeto so alguns exemplos de rotinas
deste tipo. nestes momentos que a utilizao de mecanismos de introspeco ou
reflexo se torna til.
Estes mecanismos consistem na disponibilizao por parte da linguagem de programao de estruturas que permitem analisar a especificao de um objeto e acessar seus
recursos, tudo em tempo de execuo. Desta forma podemos escrever rotinas genricas
que podem trabalhar com qualquer tipo de objeto para executar diversos tipos de tarefas,
como listar os atributos de um objeto, acessar e alterar o valor destes atributos, listar os
mtodos de um objeto e at mesmo execut-los [Lhotka, 2009].
Geralmente as linguagens hbridas e as interpretadas oferecem mtodos de reflexo
completos, pois as informaes da estrutura dos objetos so utilizadas pelas prprias
mquinas virtuais e pelos interpretadores em tempo de execuo. Neste caso, j que a
informao j est presente e formatada durante a execuo, basta a linguagem criar
mecanismos de disponibilizao dos mesmos [Lhotka, 2009].
J no cenrio das linguagens compiladas a situao bem diferente. No h a necessidade de gerao de informaes sobre estruturas de objetos para o cdigo ser executado,
2

Um conjunto de bibliotecas que implementam funcionalidades frequentemente utilizadas no desenvolvimento de software, como por exemplo, acesso a banco de dados e comunicao em redes.

2.2 A Linguagem de Programao C++

visto que o programa gerado em cdigo nativo [Gregoire, 2014]. A linguagem C++ do
tipo compilada, portanto, tambm sofre com a falta de mecanismos de reflexo nativos.

2.2.2

Processo Evolutivo da Linguagem

A linguagem C++ foi criada para ser uma linguagem de propsito geral, com o objetivo
principal de apresentar mecanismos para programao com alto nvel de abstrao, porm,
ao mesmo tempo sem privar o desenvolvedor da capacidade de acessar rotinas e recursos
de baixo nvel. Sendo assim possvel obter programas de alto desempenho em diversas
plataformas diferentes [Brokken and Kubat, 2014].
Para a linguagem ser utilizada em mltiplas plataformas necessrio que exista um
compilador que suporte a criao de programas a partir da anlise de cdigo fonte em
C++ para cada plataforma. Para evitar variaes na implementao destes compiladores
existe uma especificao oficial de todo o conjunto de recursos oferecidos pela linguagem
bem como sua sintaxe [Brokken and Kubat, 2014]. Esta especificao mantida pela ISO
(International Organization for Standardization).
As linguagens de programao evoluem com a passar do tempo. Em alguns momentos
preciso acrescentar novos recursos para alinhar a linguagem com os padres atuais,
outras vezes necessrio melhorar recursos existentes ou at mesmo corrigir erros na
especificao [Brokken and Kubat, 2014].
A especificao da linguagem C++ passou por uma grande atualizao em 1998 (conhecida como C++98), seguida de algumas correes em 2003 (especificao conhecida
como C++03). Desde ento a especificao no sofria alteraes significativas, o que
levou a linguagem a ficar um pouco desatualizada de acordo com os conceitos que foram
surgindo ao longo dos anos. At que em meados de 2011 um comit de especialistas
comeou a agir com o intuito de trazer novos recursos para a linguagem. Isso levou
publicao da especificao C++11 no final do ano de 2011 e projeo de atualizaes
da linguagem para os anos de 2014 e 2017, especificaes conhecidas como C++14 e
C++17 [Brokken and Kubat, 2014].
A figura 2.1 mostra a linha do tempo da evoluo da especificao da linguagem C++.
Nela possvel perceber a grande concentrao de tarefas previstas para os anos entre
2014 e 2017. Durante a finalizao deste trabalho (novembro de 2014) a especificao
C++14 est prevista para ser publicada em breve3 .
3

Para mais informaes acesse o site https://isocpp.org/std/status.

2.2 A Linguagem de Programao C++

Figura 2.1: Linha do tempo: evoluo da especificao da linguagem C++


Muitos recursos adicionados na linguagem pelas especificaes C++11 e C++14 foram utilizados no desenvolvimento deste trabalho. Nas sees seguintes sero descritos
alguns destes recursos, e como eles contribuem para melhorar algumas limitaes que
eram impostas pela linguagem.
2.2.2.1

Listas de Inicializao

Um recurso simples e ao mesmo tempo bastante til, as listas de inicializao foram


criadas com o objetivo de facilitar a instanciao de estruturas do tipo container (lista,
pilha, fila, tabelas hash, etc) com um conjunto de elementos adicionados. importante
ressaltar que a linguagem na especificao C++98 j permitia a inicializao de vetores
com uma lista de elementos [Gregoire, 2014].
Este recurso se baseia na utilizao de uma nova classe chamada initializer_list
definida dentro do namespace 4 std . Esta classe implementa um container de dados
simples, que suporta o acesso aos seus elementos atravs do uso de iteradores. Quando
o compilador encontra algum trecho de cdigo com o padro {x, y, z} onde x, y e
z so valores literais ou variveis que podem ser convertidas para um tipo de dado T
comum de forma implcita, ele constri um objeto do tipo initializer_list<T>. Sendo
assim, para que um objeto possa ser construdo com uma lista de inicializao, basta
que sua classe contenha um construtor que recebe como parmetro um objeto do tipo
initializer_list<T> [Brokken and Kubat, 2014].
No trecho de cdigo 2 demonstrado a utilizao das listas de inicializao. Primeiramente temos a inicializao de um vetor de nmeros inteiros (linha 2) utilizando a sintaxe
4

Mecanismo presente na linguagem C++ que permite agrupar estruturas dentro de um espao de
resoluo de nomes comum. utilizado para evitar conflitos de nomes entre estruturas.

2.2 A Linguagem de Programao C++

10

j suportada pela linguagem na especificao C++98. Em seguida temos a inicializao


de um objeto do tipo vector5 (linha 4) utilizando o novo recurso adicionado na especificao C++11. Por ltimo, temos a definio de uma classe projetada para suportar o
recurso de listas de inicializao (linhas 7 a 9) e em seguida a inicializao de um objeto
desta classe (linha 13).
1
2
3
4

// I n i c i a l i z a o de v e t o r e s
i n t v e t o r [ ] = { 1 , 2 , 3 , 4 } ; // V l i d o em C++98
// I n i c i a l i z a o de c o n t a i n e r s
v e c t o r <i n t > l i s t a 1 = { 1 , 2 , 3 , 4 } ; // V l i d o em C++11

5
6
7
8
9

// D e c l a r a o da c l a s s e Container <T>
template <typename T> c l a s s C o n t a i n e r {
C o n t a i n e r ( c o n s t i n i t i a l i z e r _ l i s t <T> & l i s t ) ;
};

10
11
12
13

// V l i d o em C++11 j que a c l a s s e Container <T> tem um c o n s t r u t o r


// que r e c e b e como parmetro um o b j e t o do t i p o i n i t i a l i z e r _ l i s t <T>
Container <i n t > l i s t a 2 = { 1 , 2 , 3 , 4 } ;

Algoritmo 2: Inicializao de vetores e estruturas container

2.2.2.2

Navegao em Grupos de Elementos

Quando precisamos acessar sequencialmente os elementos de um vetor ou de alguma


estrutura do tipo container utilizando a linguagem C++, temos basicamente duas opes:
1)Acesso sequencial via ndice: Utilizamos um lao de repetio para gerar valores
numricos sequenciais dentro do intervalo de posies ou ndices dos elementos que
desejamos acessar na estrutura. De posse dos ndices, podemos acessar os elementos
utilizando a sintaxe estrutura[ndice]. Esta tcnica pode ser utilizada em vetores
e em estruturas container que implementam o operador [] [Gregoire, 2014]. Um
exemplo da utilizao desta tcnica apresentado no trecho de cdigo 3.
2)Acesso sequencial via iteradores: As estruturas container presentes na linguagem
C++ disponibilizam o acesso a um ponteiro especial que permite navegar entre os
elementos que ele contm. Estes ponteiros so chamados de iteradores e podem
ser de dois tipos: constantes e no constantes. Os iteradores constantes permitem
acessar os elementos em modo somente leitura. Enquanto os no constantes permitem a modificao dos valores destes elementos [Gregoire, 2014]. Um exemplo da
utilizao desta tcnica apresentado no trecho de cdigo 4.
5

Classe presente na biblioteca padro de C++, e que implementa uma estrutura de lista de elementos
utilizando reas de memria contguas.

2.2 A Linguagem de Programao C++

1
2
3
4
5
6

// D e c l a r a o de um v e t o r
i n t vetor [ ] = {1 , 2 , 3 , 4 , 5};
// Acesso s e q u e n c i a l v i a n d i c e
f o r ( i n t i = 0 ; i < 5 ; ++i ) {
c o u t << v e t o r [ i ] << e n d l ;
}

7
8
9
10
11
12
13

// D e c l a r a o de um c o n t a i n e r
v e c t o r <i n t > c o n t a i n e r = { 1 , 2 , 3 , 4 , 5 } ;
// Acesso s e q u e n c i a l v i a n d i c e
f o r ( i n t i = 0 ; i < c o n t a i n e r . s i z e ( ) ; ++i ) {
c o u t << c o n t a i n e r [ i ] << e n d l ;
}

Algoritmo 3: Acesso sequencial via ndice

1
2
3
4
5
6
7
8
9
10
11
12

// D e c l a r a o de um c o n t a i n e r
v e c t o r <i n t > c o n t a i n e r = { 1 , 2 , 3 , 4 , 5 } ;
// Acesso s e q u e n c i a l v i a i t e r a d o r e s do t i p o c o n s t a n t e s
f o r ( v e c t o r <i n t > : : c o n s t _ i t e r a t o r i = c o n t a i n e r . c b e g i n ( ) ;
i != c o n t a i n e r . cend ( ) ; ++i ) {
c o u t << i << e n d l ;
}
// Acesso s e q u e n c i a l v i a i t e r a d o r e s do t i p o no c o n s t a n t e s
f o r ( v e c t o r <i n t > : : i t e r a t o r i = c o n t a i n e r . b e g i n ( ) ;
i != c o n t a i n e r . end ( ) ; ++i ) {
c o u t << i << e n d l ;
}

Algoritmo 4: Acesso sequencial via iteradores

11

2.2 A Linguagem de Programao C++

12

Na especificao C++11 foi adicionada uma variao do lao de repetio for que
basicamente uma simplificao das tcnicas 1 e 2 descritas anteriormente. Considerando
que temos um grupo de elementos do tipo T armazenados em uma estrutura (vetor ou
container ) com uma instncia chamada elementos, podemos navegar sobre os elementos
desta instncia utilizando um trecho de cdigo no formato for (T e : elementos) {...}.
Neste caso, o cdigo contido entre as chaves ser executado uma vez para cada elemento
contido em elementos, onde a varivel e assume o valor de cada um destes elementos
[Gregoire, 2014].
Esta nova variao pode ser utilizada tanto com vetores quanto com estruturas do
tipo container, e tambm possvel navegar sobre os elementos em modo somente leitura.
No trecho de cdigo 5 demonstrada a utilizao desta nova sintaxe de diferentes formas.
1
2
3
4
5
6
7
8
9
10

// D e c l a r a o de um v e t o r
i n t vetor [ ] = {1 , 2 , 3 , 4 , 5};
// Acesso s e q u e n c i a l nova s i n t a x e , com c p i a
f o r ( i n t i : v e t o r ) { // i c o p i a o v a l o r de cada e l e m e n t o
c o u t << i << e n d l ;
}
// Acesso s e q u e n c i a l nova s i n t a x e , com r e f e r n c i a
f o r ( i n t &i : v e t o r ) { //No h c p i a de v a l o r e s
c o u t << i << e n d l ;
}

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// D e c l a r a o de um c o n t a i n e r
v e c t o r <i n t > c o n t a i n e r = { 1 , 2 , 3 , 4 , 5 } ;
// Acesso s e q u e n c i a l nova s i n t a x e , com c p i a
f o r ( i n t i : c o n t a i n e r ) { // i c o p i a o v a l o r de cada e l e m e n t o
c o u t << i << e n d l ;
}
// Acesso s e q u e n c i a l nova s i n t a x e , com r e f e r n c i a
f o r ( i n t &i : c o n t a i n e r ) { //No h c p i a de v a l o r e s
c o u t << i << e n d l ;
}
// Acesso s e q u e n c i a l nova s i n t a x e , somentel e i t u r a com r e f e r n c i a
f o r ( c o n s t i n t &i : c o n t a i n e r ) {
c o u t << i << e n d l ;
}

Algoritmo 5: Acesso sequencial com nova sintaxe (C++11)

2.2.2.3

Novo Identificador para Ponteiros Nulos

A linguagem C++ permite a manipulao direta de memria a partir da utilizao de


ponteiros, variveis estas que armazenam o endereo inicial da poro de memria em
que uma estrutura de dados est sendo armazenada durante a execuo de um programa
[Gregoire, 2014].

2.2 A Linguagem de Programao C++

13

A manipulao de ponteiros uma tarefa complexa, que deve ser feita com muito
cuidado. Uma tentativa de acesso a uma regio de memria invlida pode gerar problemas
graves durante a execuo do programa. Para evitar este tipo de problema, uma boa
prtica consiste em invalidar ou anular ponteiros durante a sua inicializao e quando
o seu uso chegou ao fim (o que acontece por exemplo quando desalocamos a regio de
memria apontada por ele) [Gregoire, 2014].
Para anular um ponteiro simplesmente atribumos a ele o valor 0. Porm, na maioria
dos ambientes de desenvolvimento, temos a presena de uma macro chamada NULL que
utilizada no local do valor 0 durante a anulao de um ponteiro para fins de legibilidade.
Esta metodologia pode levar a comportamentos inesperados do cdigo durante a execuo, visto que a macro expandida para o valor inteiro 0 durante a compilao. Se
temos duas funes com o mesmo nome, onde uma recebe um ponteiro como parmetro
e a outra recebe um nmero inteiro, ao executar esta funo passando a macro NULL,
a verso que recebe o nmero inteiro ser executada, gerando assim um comportamento
inesperado.
Com o objetivo de resolver este problema a especificao C++11 prev a existncia
do identificador nullptr para ser utilizado com o significado de ponteiro nulo. Ento se
no mesmo problema citado executssemos a funo passando nullptr como parmetro,
a verso que recebe o ponteiro ser executada [Gregoire, 2014]. O exemplo citado pode
ser observado no trecho de cdigo 6.

1
2
3
4

void funcao ( char v a l o r )


{
c o u t << " c h a r " << e n d l ;
}

5
6
7
8
9

void funcao ( i n t valor )


{
c o u t << " i n t " << e n d l ;
}

10
11
12
13
14
15

v o i d main ( )
{
f u n c a o (NULL) ; // Executa f u n c a o ( i n t v a l o r )
f u n c a o ( n u l l p t r ) ; // Executa f u n c a o ( c h a r v a l o r )
}

Algoritmo 6: Novo identificador para ponteiros nulos

2.2 A Linguagem de Programao C++

2.2.2.4

14

Inferncia de Tipos

A linguagem C++ uma linguagem de tipagem esttica, ou seja, todas as variveis


declaradas no cdigo devem ter seu tipo de dado especificado em momento de compilao
[Brokken and Kubat, 2014]. Esta caracterstica acaba em certas situaes deixando o
cdigo de declarao de variveis muito grande. Veja por exemplo o trecho de cdigo 7,
onde so declarados um container para uma lista de inteiros e um iterador para esta lista.

1
2
3
4

// D e c l a r a uma l i s t a de i n t e i r o s
v e c t o r <i n t > v e t o r = new v e c t o r <i n t >() ;
//Obtm um i t e r a d o r para a l i s t a d e c l a r a d a
v e c t o r <i n t > : : i t e r a t o r i t e r = v e t o r >b e g i n ( ) ;

Algoritmo 7: Trecho de declarao longo


Com a finalidade de reduzir estes trechos de cdigo, a especificao C++11 introduziu
um mecanismo de inferncia ou deteco automtica de tipos de variveis atravs do uso
das palavras-chave auto e decltype [Gregoire, 2014].
A primeira utilizada durante a atribuio de valores que j tem um tipo de dado
definido por outro mecanismo, como por exemplo, pelo retorno de uma funo ou pelo
uso do operador de instanciao new. O trecho de cdigo 7 poderia ser simplificado
para o cdigo em 8.

1
2
3
4

// D e c l a r a uma l i s t a de i n t e i r o s
auto v e t o r = new v e c t o r <i n t >() ;
//Obtm um i t e r a d o r para a l i s t a d e c l a r a d a
auto i t e r = v e t o r >b e g i n ( ) ;

Algoritmo 8: Trecho de declarao curto usando auto


O uso da palavra-chave auto tem uma particularidade importante que deve ser
levada em considerao durante o seu uso. O tipo deduzido o resultado do tipo do
valor atribudo varivel aps a remoo do modificador const 6 e do modificador
& 7 [Gregoire, 2014]. Esta particularidade pode levar a resultados inesperados, como o
que pode ser observado no trecho de cdigo 9 na linha 10, onde a deduo de tipo ir
levar a criao de uma varivel do tipo inteiro com o valor copiado do retorno da funo
constRef, enquanto que o valor atribudo originalmente de uma referncia para um
valor inteiro constante.
6

Utilizado para declarar variveis constantes, ou seja, que no podem ser usadas para modificar valores.
Neste contexto se refere ao modificador para declarao de variveis do tipo referncia na linguagem
C++.
7

2.2 A Linguagem de Programao C++

1
2
3
4

15

c o n s t i n t& c o n s t R e f ( i n t& v a l o r )
{
return valor ;
}

5
6
7
8
9
10
11

i n t main ( )
{
int valor = 10;
//O t i p o d e d u z i d o ( i n t ) e no ( c o n s t i n t &)
auto numero = c o n s t R e f ( v a l o r ) ;
}

Algoritmo 9: Particularidade do uso da palavra-chave auto


Nestas situaes podemos utilizar a palavra-chave decltype para alcanar o comportamento requerido. A funo desta palavra-chave avaliar o tipo de dado do resultado
de uma expresso qualquer [Gregoire, 2014]. Ela pode ser utilizada em qualquer lugar do
cdigo onde se espera a especificao de um tipo de dado, como por exemplo em declaraes de variveis e como parmetros para estruturas genricas (que utilizam o mecanismo
de templates 8 ).
No trecho de cdigo 10 podemos ver a utilizao desta palavra-chave. Neste caso a
varivel numero (linha 10) ir ser deduzida como uma referncia para um valor inteiro
constante, que exatamente o tipo retornado pela funo constRef. Porm o cdigo
gerado para a deduo no to simplificado, o que levou a proposta da adio da
construo decltype(auto) (linha 12) pela especificao C++14, que tem o mesmo
resultado neste caso [Gregoire, 2014].

1
2
3
4

c o n s t i n t& c o n s t R e f ( i n t& v a l o r )
{
return valor ;
}

5
6
7
8
9
10
11
12
13

i n t main ( )
{
int valor = 10;
//O t i p o d e d u z i d o ( c o n s t i n t &)
d e c l t y p e ( c o n s t R e f ( v a l o r ) ) numero = c o n s t R e f ( v a l o r ) ;
// S i m p l i f i c a o p r o p o s t a na C++14
d e c l t y p e ( auto ) num = c o n s t R e f ( v a l o r ) ;
}

Algoritmo 10: Deduo de tipo com o uso da palavra-chave decltype


8

Mecanismo presente na linguagem C++ que permite o desenvolvimento de cdigo que pode trabalhar
com diferentes tipos de dados. muito utilizado na construo de estruturas do tipo container.

2.2 A Linguagem de Programao C++

2.2.2.5

16

Programao Funcional

O conceito de programao funcional prope que funes e mtodos sejam tratados de


forma igualitria com variveis e objetos, no aspecto de poderem ser transportados entre
contextos de execuo, ser armazenados em estruturas especficas, ser criados sob demanda
e ser utilizados como parmetros para outras funes e/ou mtodos [Clugston, 2004].
A maneira tradicional utilizada para manipular funes e mtodos na linguagem C++
consiste do uso de ponteiros. Porm esta metodologia utiliza uma sintaxe bem difcil e
existem vrios problemas ou limitadores em relao converso destes ponteiros. Um
grande problema encontrado que ponteiros para funes (declaradas no contexto global)
e mtodos (declarados dentro de classes, exceto os estticos neste caso) possuem sintaxe
de declarao diferentes e no so convertveis entre si [Clugston, 2004].
No trecho de cdigo 11 demonstrada a sintaxe do uso de ponteiros para funes e
mtodos. Na linha 16 declarado um ponteiro para a funo getTexto, e na linha 18
declarado um para o mtodo de mesmo nome presente na classe Exemplo. Note que
apesar da funo e do mtodo possurem o mesmo prottipo (tipo de retorno e parmetro)
a sintaxe para declarao de seus ponteiros diferente e eles no podem ser convertidos
entre si.
A especificao C++11 prope a unificao da representao destes ponteiros como
instncias da classe function que definida dentro do namespace std. Esta classe
consegue representar ponteiros para funes, mtodos e referncias para function objects 9
[Gregoire, 2014].
O trecho de cdigo 11 pode ser reescrito com o uso desta classe conforme o exemplo
12. Note que para atribuir um ponteiro para mtodo preciso utilizar a funo bind
para associar um objeto com o mtodo a ser apontado (linha 22). Com esta nova sintaxe
apontadores para mtodos e funes com o mesmo prottipo podem ser convertidos entre
si.
Outra funcionalidade adicionada pela especificao C++11 foi o suporte a definio de
mtodos annimos, tambm conhecidos como expresses lambda. Esta funcionalidade
consiste na capacidade de criar funes sob demanda durante blocos de execuo do
programa. Expresses lambda tambm podem ser armazenadas em instncias da classe
function [Gregoire, 2014].
9

Instncias de classes que reimplementam a funo do operador parnteses.

2.2 A Linguagem de Programao C++

1
2
3
4
5
6
7
8

c l a s s Exemplo {
public :
c o n s t s t r i n g getTexto ( )
{ r e t u r n m_texto ; }
// . . .
private :
s t r i n g m_texto ;
};

9
10
11

c o n s t s t r i n g getTexto ( )
{ r e t u r n s t r i n g ( "Exemplo de f u n o . " ) ; }

12
13
14
15
16
17
18

i n t main ( )
{
// P o n t e i r o para f u n o
c o n s t s t r i n g ( f u n c a o ) ( ) = &getTexto ;
// P o n t e i r o para mtodo
c o n s t s t r i n g ( Exemplo : : metodo ) ( ) = &Exemplo : : getTexto ;

19

// U t i l i z a n d o o p o n t e i r o de f u n a o
c o u t << f u n c a o ( ) << e n d l ;
// U t i l i z a n d o o p o n t e i r o de mtodo
Exemplo ex ;
c o u t << ( ex . metodo ) ( ) << e n d l ;

20
21
22
23
24
25

f u n c a o = metodo ; // I n v l i d o
metodo = f u n c a o ; // I n v l i d o

26
27
28

Algoritmo 11: Sintaxe para utilizao de ponteiros para funes e mtodos

17

2.2 A Linguagem de Programao C++

1
2
3
4
5
6
7
8

18

c l a s s Exemplo {
public :
c o n s t s t r i n g getTexto ( )
{ r e t u r n m_texto ; }
// . . .
private :
s t r i n g m_texto ;
};

9
10
11

c o n s t s t r i n g getTexto ( )
{ r e t u r n s t r i n g ( "Exemplo de f u n o . " ) ; }

12
13
14
15
16
17
18
19
20
21
22
23
24

i n t main ( )
{
// Declarando c o n t a i n e r u n i f i c a d o
f u n c t i o n <c o n s t s t r i n g ( )> f u n c a o = n u l l p t r ;
// A t r i b u i n d o e u t i l i z a n d o uma f u n o
f u n c a o = getTexto ;
c o u t << f u n c a o ( ) << e n d l ;
// A t r i b u i n d o e u t i l i z a n d o um mtodo
Exemplo e ;
f u n c a o = bind (&Exemplo : : getTexto , &e ) ; // r e l a c i o n a i n s t n c i a
c o u t << f u n c a o ( ) << e n d l ;
}

Algoritmo 12: Unificao da representao de ponteiros para mtodos e funes

Figura 2.2: Sintaxe bsica das expresses lambda


A sintaxe bsica para utilizao de expresses lambda demonstrada na imagem 2.2.
Os blocos presentes nesta construo so explicados em seguida:
1) rea de captura (Capture specification): As expresses lambda podem capturar
as variveis presentes no contexto atual de execuo para utilizar seus valores no
seu bloco de execuo. Esta captura pode feita por valor, onde efetuado uma
cpia dos valores das variveis do contexto alvo, ou pode ser feita por referncia,
onde as variveis sero referenciadas no bloco de execuo da expresso, ou seja,
podemos trabalhar com modificao de valores das variveis originais. Neste ltimo
caso importante garantir que as variveis capturadas existem no momento de
execuo da expresso, caso contrrio teremos uma exceo de acesso a posio

2.2 A Linguagem de Programao C++

19

invlida de memria. A captura pode ser feita especificando cada varivel que
queremos capturar, como por exemplo no trecho [a, &b] capturamos a varivel a
por valor e b por referncia. Ou podemos capturar todas as variveis do contexto
utilizando [=] para capturar todas as variveis por valor ou [&] para capturar
por referncia. Caso no seja necessrio capturar variveis, utilizamos colchetes sem
contedo, assim [] [Brokken and Kubat, 2014].
2) Lista de parmetros (Parameter specification): onde especificada a lista de
parmetros que a expresso lambda recebe. A sintaxe a mesma utilizada na
definio de prottipos de funes e mtodos. Por exemplo no trecho (int a, char
b) dizemos que a expresso recebe um nmero inteiro que ser referenciado no
corpo da expresso como a e tambm recebe um caractere que ser referenciado
como b [Brokken and Kubat, 2014].
3) Mutable specification: Por padro, variveis capturadas por valor so tratadas dentro do bloco de execuo da expresso como do tipo constante, ou seja, no podemos modificar seus valores. Caso utilizemos o modificador mutable elas no
sero mais tratadas como do tipo constante, ento poderemos manipular os valores
copiados no bloco de execuo da expresso [Brokken and Kubat, 2014].
4) Especificao do tipo de retorno (Return type specification): Neste ponto devemos especificar o tipo de dado que ser retornado pela expresso lambda. Caso a
expresso no retorne valores ou o tipo do valor retornado pode ser deduzido pelo
compilador, podemos omitir esta parte [Brokken and Kubat, 2014].
5) Bloco de execuo (Lambda body ): Consiste do bloco de cdigo que ser executado quando a expresso for utilizada. Assim como a lista de parmetros, este trecho de definio segue a mesma sintaxe da definio de funes e mtodos comuns.
Podem ser utilizadas quaisquer construes vlidas para blocos de execuo na linguagem C++. importante ressaltar tambm que no h um limite de tamanho
para o bloco, porm expresses lambda geralmente so bem concisas e simplificadas,
ocupando poucas linhas. Caso a expresso comece a ficar muito grande e complexa,
talvez seja melhor definir uma funo comum para que possa ser reutilizada por
outros componentes do programa [Brokken and Kubat, 2014].
No trecho de cdigo 13 temos um exemplo de definio de uma expresso lambda
com o mesmo prottipo utilizado nos exemplos anteriores. Note que a expresso pode ser

2.2 A Linguagem de Programao C++

20

armazenada em uma instncia da classe function e a sua execuo feita da mesma


maneira que os ponteiros para funes e mtodos, armazenados nestas instncias.

1
2
3
4

// Exemplo de e x p r e s s o lamda
f u n c t i o n <c o n s t s t r i n g ( )> lambda = [ ] ( ) { r e t u r n s t r i n g ( "Exemplo . " ) ; } ;
// Executando a e x p r e s s o
c o u t << lambda ( ) << e n d l ;

Algoritmo 13: Exemplo de definio de uma expresso lambda

2.2.2.6

Ponteiros Inteligentes (Smart Pointers)

Um dos maiores desafios enfrentados por desenvolvedores que utilizam a linguagem C++
consiste na garantia da liberao de blocos de memria alocados dinamicamente a partir
do uso de ponteiros. Sempre que alocamos uma regio de memria a partir do uso do
operador new, temos que garantir que em algum ponto do cdigo aquela regio ser
liberada, tarefa que deve ser realizada explicitamente com o uso do operador delete
[Brokken and Kubat, 2014].
Regies de memria alocada que no so liberadas, iro persistir marcadas como utilizadas durante todo o fluxo de execuo do programa, causando assim um efeito de utilizao extra de memria indevida tambm conhecido como memory leak [Gregoire, 2014].
Com o objetivo de evitar este tipo de problema, a especificao C++11 prev a
criao de ponteiros inteligentes ou smart pointers, que so basicamente estruturas que
simulam o funcionamento de um ponteiro comum, porm adicionando mecanismos de
gerenciamento de memria. Do ponto de vista de padres de projeto, um smart pointer
seria um proxy para a interface de ponteiros comuns [Brokken and Kubat, 2014].
A especificao C++11 define a presena de trs smart pointers, sendo eles:
1) unique_ptr: Este ponteiro tm basicamente as mesmas caractersticas de um ponteiro comum. A nica diferena que ele automaticamente libera a regio de memria apontada por ele quando ele deletado ou quando o escopo de sua utilizao
chega ao fim [Gregoire, 2014].
2) shared_ptr: Este ponteiro possui uma funcionalidade um pouco mais avanada.
Ele mantm um contador interno que armazena a quantidade de referncias que
existem para a regio de memria apontada por ele, ou seja, ele armazena quantas instncias do tipo shared_ptr se encontram ativas no momento para aquela

2.2 A Linguagem de Programao C++

21

regio de memria. O contador incrementado quando o ponteiro copiado e decrementado quando instncias de ponteiros so deletadas ou perdem escopo. Somente
quando o contador chegar a zero, ou seja, quando no existir mais nenhuma cpia do ponteiro original ativa, a regio de memria ser automaticamente liberada
[Gregoire, 2014].
3) weak_ptr: Este ponteiro utilizado para testar se uma instncia de shared_ptr
ainda vlida (ainda no foi desalocada), e caso o for, permite efetuar uma cpia
desta instncia para acessar a regio de memria apontada [Gregoire, 2014].
O trecho de cdigo 14 demonstra a utilizao dos trs tipos de smart pointers descritos anteriormente. Nele so alocados dois espaos de memria para armazenar dados
do tipo inteiro dentro de um escopo de execuo delimitado por chaves. Assim que o
escopo finalizado, ambos os ponteiros desalocam a regio de memria apontada por
eles automaticamente. No cdigo tambm mostrado como utilizar um weak_ptr para
verificar se um shared_ptr ainda vlido a partir da utilizao do mtodo lock que
retorna uma cpia deste segundo ponteiro no caso de validao ou retorna nullptr caso
contrrio.
1
2

// D e c l a r a um weak_ptr sem i n i c i l i z a o
weak_ptr<i n t > wptr ;

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// Abertura de e s c o p o
{
// D e c l a r a um shared_ptr
shared_ptr<i n t > s p t r = shared_ptr<i n t >(new i n t ( 1 0 ) ) ;
// D e c l a r a um unique_ptr
unique_ptr<i n t > u p t r = unique_ptr<i n t >(new i n t ( 1 0 ) ) ;
// I n i c i a l i z a o weak_ptr
wptr = s p t r ;
// Testa s e memria a i n d a no f o i d e s a l o c a d a
i f ( auto p t r = wptr . l o c k ( ) )
{
// Cdigo s e r executado , p o i s s p t r a i n d a no perdeu e s c o p o
c o u t << p t r << e n d l ;
}
} //Fim do escopo , s p t r e u p t r s o d e s a l o c a d o s

19
20
21
22
23
24
25

// Testa s e memria a i n d a no f o i d e s a l o c a d a
i f ( auto p t r = wptr . l o c k ( ) )
{
//No s e r executado , p o i s s p t r perdeu e s c o p o
c o u t << p t r << e n d l ;
}

Algoritmo 14: Utilizando smart pointers

2.3 O Framework Qt

2.3

22

O Framework Qt

Qt um framework multiplataforma voltado para a criao de aplicativos com interface


grfica utilizando a linguagem C++. Sua primeira verso foi lanada em 1995 pelos
seus criadores Haavard Nord e Eirik Chambe-Eng em sua empresa chamada Trolltech
[Blanchette and Summerfield, 2006].
O objetivo do framework basicamente prover uma interface de programao padro
para executar tarefas como criao de interface grfica, programao paralela e acesso
a banco de dados, para todas as plataformas suportadas. Esse comportamento alcanado atravs do direcionamento da execuo das tarefas para implementaes especficas
existentes na plataforma alvo [Blanchette and Summerfield, 2006]. Uma caracterstica
interessante do framework a adaptao da interface grfica criada ao seu ambiente de
execuo. Uma janela executada em um sistema operacional suportado assume a aparncia nativa do mesmo, como possvel verificar nas figuras 2.3, 2.4 e 2.5, onde temos uma
janela de um programa sendo exibida nos trs sistemas suportados da plataforma desktop.

Figura 2.3: Janela no GNU/Linux


Inicialmente o framework era totalmente focado na padronizao do processo de criao de interface grfica entre diferentes plataformas, porm ao longo de sua existncia

2.3 O Framework Qt

23

Figura 2.4: Janela no Microsoft Windows XP


foram sendo adicionadas novas funes voltadas para tarefas rotineiras no desenvolvimento de software, como por exemplo acesso a banco de dados, programao paralela
e manipulao de arquivos multimdia (vdeos e imagens). Com a adio destes novos
componentes, o framework acabou crescendo muito, o que levou aos desenvolvedores o
reestruturarem em forma de mdulos de forma que o desenvolvedor possa adicionar em
seu projeto somente os mdulos que pretende utilizar, diminuindo o tamanho final do executvel gerado para distribuio de seu aplicativo [Blanchette and Summerfield, 2006].
Neste trabalho so utilizados basicamente trs dos mdulos existentes no framework,
sendo eles o QtSql, o QtTest e o QtCore. O QtSql um mdulo voltado para utilizao
de Sistemas Gerenciadores de Bancos de Dados Relacionais (ver seo 2.4) como
forma de persistncia dos dados gerados pelo aplicativo. Ele prov suporte para utilizao dos sistemas mais populares, como MySQL, Oracle, PostgreSQL, Sybase, DB2,
SQLite, Interbase e ODBC [Thelin, 2007]. Esse mdulo ser utilizado como apoio
para utilizao de bancos de dados relacionais nas plataformas Microsoft Windows e
GNU/Linux.

2.3 O Framework Qt

24

Figura 2.5: Janela no Mac Os


O QtTest um mdulo voltado para a criao de testes unitrios. Os testes so utilizados para validar o funcionamento do software desenvolvido ao longo de sua existncia.
Geralmente so executados quando feita alguma modificao no cdigo, como por exemplo adio de novos componentes. E, por fim, QtCore o mdulo principal do framework.
Ele responsvel por prover rotinas para programao paralela, converso de tipos, alm
de adicionar tipos de dados muito importantes na utilizao de bancos de dados, como o
QDateTime 10 [Thelin, 2007].
No momento da criao deste documento, o framework est em sua verso 5.3 (verso
que utilizada no trabalho), e compatvel com os sistemas operacionais GNU/Linux,
Microsoft Windows e Mac OS na plataforma desktop. Ele oferece tambm suporte a
dispositivos embarcados com sistema operacional GNU/Linux e para dispositivos mveis
com os sistemas Android, IOS e Windows Phone.
10
Tipo de dado que armazena um valor de data e hora. No existe um tipo de dado nativo em C++
para esta finalidade.

2.4 Sistemas Gerenciadores de Bancos de Dados Relacionais

2.4

25

Sistemas Gerenciadores de Bancos de Dados Relacionais

Assim como as linguagens orientadas a objetos so consideradas um padro para desenvolvimento de software, os Sistemas Gerenciadores de Bancos de Dados Relacionais ou
SGBDs so considerados um padro para armazenamento estruturado de informaes
[Barnes, 2007].
Os SGBDs utilizam um modelo de persistncia denominado modelo relacional,
que se baseia no uso de tabelas e colunas. As tabelas representam entidades, ou um
grupo de informao a ser armazenado, e podem se relacionar com outras tabelas para
promover regras de armazenamento. As colunas representam as caractersticas da entidade
armazenada. Neste modelo, quando armazenamos um registro, ele acrescentado como
uma linha em uma ou mais tabelas relacionadas. Nas tabelas, pode ser aplicado o conceito
de unicidade dos registros armazenados, atravs da definio de um conjunto de colunas
que deve representar uma combinao de valores nica dentre os registros armazenados.
Este conjunto de colunas define o que chamamos de chave primria da tabela ou, em
ingls, primary key [Barnes, 2007].
A definio de chaves primrias nas tabelas criadas permite a criao de relaes entre
elas atravs do uso de referncias entre suas chaves. A referncia em uma tabela para uma
chave primria de outra tabela conhecida como chave estrangeira ou, em ingls, foreign key [Barnes, 2007]. Na figura 2.6 temos um exemplo de definio de duas tabelas,
uma representando registros de pessoas e outra de telefones. Elas esto relacionadas, de
modo que um registro de telefone pertence a uma pessoa. Este comportamento obtido
atravs da definio da chave estrangeira TelefoneId na tabela Pessoa, que se refere
chave Id na tabela Telefone.
Uma das funcionalidades mais importantes apresentada pelos SGBDs a capacidade
de aplicao de rotinas complexas de pesquisa usando a linguagem SQL. Esta linguagem
define um conjunto de operaes que permite executar inseres, modificaes, remoo e
busca de registros armazenados em um SGBD [Barnes, 2007]. Talvez esta funcionalidade
seja a causa de sua grande utilizao e aceitao. Neste trabalho utilizado o SGBD
PostgreSQL (ver seo 2.5).

2.5 O PostgreSQL

26

Figura 2.6: Exemplo de definio de tabelas e relaes

2.5

O PostgreSQL

O PostgreSQL um SGBD de cdigo aberto, e com licena de uso gratuita para qualquer
pessoa sobre qualquer propsito. Ele pode ser utilizado, modificado e redistribudo livremente. Este SGBD derivado do projeto POSTGRES desenvolvido na Universidade de
Berkeley na Califrnia no ano de 1986. Por ser um software de cdigo aberto desenvolvido
em comunidade, ele conhecido por ser pioneiro na adio de novas funcionalidades, e se
mantm sempre atualizado em relao aos conceitos e especificaes da linguagem SQL
[PostgreSQL, 2014].

2.6

A combinao de SGBDs com Linguagens Orientadas a Objetos

A princpio, os programas trabalham com dados em memria principal, que voltil. Isto
, ao desligarmos o equipamento todos os dados so perdidos. Devido a isso, necessitamos
de algum mecanismo de persistncia, ou seja, que permita a gravao de dados importantes
em memria secundria, no voltil [Barnes, 2007].
A combinao mais comumente utilizada para alcanar este cenrio o uso de linguagens orientadas a objetos para desenvolver o software e o uso de SGBDs para armazenar
os dados gerados pelo software [Bauer and King, 2005]. Porm, os dados no contexto
orientado a objetos e no contexto relacional so estruturados de maneiras diferentes, portanto precisamos realizar uma converso ou mapeamento dos dados durante a transio
de contextos.

2.6 A combinao de SGBDs com Linguagens Orientadas a Objetos

27

Quando estamos trabalhando com classes simples (no compostas por membros de
outras classes), o mapeamento segue uma lgica simples. Podemos criar uma correspondncia entre a classe e sua respectiva tabela, onde os atributos da classe so mapeados para
colunas de uma tabela. Porm quando comeamos a utilizar mecanismos mais avanados
da orientao a objetos como herana e composio, o mapeamento entre os contextos se
torna mais complexo [Barnes, 2007].
Mesmo quando temos um cenrio onde o mapeamento simples, precisamos gerar
cdigo de converso. As linguagens de programao fornecem bibliotecas ou APIs 11 que
permitem a comunicao com SGBDs atravs do envio de comandos em linguagem SQL
[Barnes, 2007]. O cdigo gerado para executar a transio de dados entre os dois contextos
geralmente segue a seguinte sequncia de passos:
1. Carregar um driver de comunicao com o SGBD utilizado e abrir a conexo;
2. Criar um objeto que permita a montagem de cdigo SQL;
3. Enviar o comando para o SGBD para que seja executado;
4. Recuperar e processar os dados ou resposta gerados pelo SGBD;
5. Liberar os recursos alocados para execuo da tarefa, como por exemplo fechar a
conexo com SGDB.
No trecho de cdigo 15 temos um esboo de como estas etapas so realizadas utilizando
a linguagem C++ em conjunto com o mdulo QtSql do framework Qt (ver seo 2.3) e
comunicando com o SGBD PostgreSQL (ver seo 2.5).

1
2
3
4
5
6

QSqlDatabase d a t a b a s e = QSqlDatabase : : addDatabase ( "QPSQL" ) ; // Etapa ( 1 )


d a t a b a s e . open ( ) ; // Etapa ( 1 )
QSqlQuery query ( "comando s q l " ) ; // Etapa ( 2 )
query . e x e c ( ) ; // Etapa ( 3 )
// P r o c e s s a o r e s u l t a d o r e t o r n a d o , e t a p a ( 4 ) //
d a t a b a s e . c l o s e ( ) ; // Etapa ( 5 )

Algoritmo 15: Exemplo de comunicao com SGBD utilizando o mdulo QtSql

A utilizao deste tipo de cdigo se torna repetitiva, visto que temos que executar
estes passos para todas as classes que armazenam dados utilizando SGBDs. Este tipo
de comportamento indesejado, pois diminui a produtividade do desenvolvimento, alm
11

Application Programming Interface. Define uma interface de um conjunto de bibliotecas de software.

2.7 Bibliotecas de Mapeamento Objeto Relacional

28

do fato de que tarefas repetitivas tem grande potencial de gerarem erros. Outro grande
problema que encontramos que os comandos em linguagem SQL variam entre os SGBDs,
portanto ao mudar o SGBD utilizado pelo programa, temos de reescrever os comandos
SQL utilizados. Este outro fator com grande potencial de gerao de erros, alm de
diminuir a flexibilidade do software, tornando, em alguns casos, invivel a mudana de
SGBD [Barnes, 2007].
Para otimizar a combinao do uso de linguagens de programao orientadas a objetos
em conjunto com SGBDs, surgiu o conceito de Biblioteca de Mapeamento Objeto
Relacional ou ORM (Object Relational Mapping ), assunto abordado na seo 2.7.

2.7

Bibliotecas de Mapeamento Objeto Relacional

As bibliotecas ORM tm como objetivo principal automatizar as tarefas relacionadas com


a transio de informaes entre os contextos orientado a objetos e relacional. No existe
um conceito universal que defina quais so as funcionalidades que uma biblioteca ORM
deve oferecer [Barnes, 2007], porm as trs funcionalidades mais comumente encontradas
so:
1) Definio de mapeamento: As bibliotecas ORM permitem a definio explcita da
correspondncia entre entidades no contexto orientado a objetos (classes) e entidades
no contexto relacional (tabelas). Os mecanismos de definio deste mapeamento
variam entre as implementaes;
2) Gerao de banco de dados: As bibliotecas ORM geralmente permitem a gerao
automtica do banco de dados equivalente s estruturas do contexto orientado a
objetos;
3) Definio de uma API: Geralmente as bibliotecas ORM disponibilizam interfaces
padronizadas para realizao de tarefas que envolvam a transio de dados entre os
dois contextos. Operaes como salvar, deletar ou pesquisar registros so encapsuladas em classes de propsito geral que conseguem trabalhar sobre qualquer entidade
mapeada.
Nem todas as bibliotecas existentes oferecem as trs funcionalidades descritas, mas
o mais comum encontrar uma combinao das trs. Existem ainda bibliotecas que

2.7 Bibliotecas de Mapeamento Objeto Relacional

29

permitem gerar o cdigo de mapeamento e at mesmo gerar o cdigo das classes a partir da anlise de um banco de dados existente. Esta funcionalidade conhecida como
Mapeamento Reverso ou Engenharia Reversa [Barnes, 2007].
As bibliotecas ORM divergem bastante na forma de implementao e funcionalidades
disponibilizadas. Isso se deve principalmente ao fato da divergncia de recursos entre
as prprias linguagens de programao em que so implementadas. Porm uma deciso
comum a ser tomada no desenvolvimento de uma biblioteca ORM em qualquer linguagem, a definio do ponto de partida para obteno das informaes de mapeamento
[Barnes, 2007]. Os paradigmas mais utilizados so:
1) Orientado a metadados: Neste paradigma, o desenvolvedor informa a estrutura das
entidades envolvidas no software que devem ser mapeadas atravs de alguma fonte
externa, como um arquivo XML. Neste arquivo so informados metadados12 sobre
as entidades nos dois contextos, o que permite a biblioteca ORM criar o cdigo de
definio das classes e do cdigo de mapeamento. Neste modelo podemos utilizar
um banco de dados j existente, ou a biblioteca ORM pode constru-lo a partir
da anlise dos metadados. A vantagem deste paradigma a abstrao total da
gerao de cdigo de manipulao do banco de dados. E sua grande desvantagem
a limitao de edio do cdigo gerado pela biblioteca. Os cdigos das classes
mapeadas sero gerados automaticamente pela biblioteca e no podero ser editados
pelo desenvolvedor [Barnes, 2007].
2) Orientado aplicao: Neste paradigma o desenvolvedor deve escrever o cdigo das
classes de todo o programa normalmente, porm sem se preocupar com as operaes
de persistncia. Aps a definio das classes, a biblioteca ORM, atravs da anlise
do cdigo e opcionalmente metadados, consegue criar o cdigo de persistncia.
possvel utilizar um banco de dados existente ou a biblioteca pode constru-lo. A
vantagem deste paradigma a total abstrao da gerao de cdigo de manipulao
do banco de dados, e sua grande desvantagem a alta complexidade de desenvolver
o mecanismo de anlise do cdigo escrito pelo desenvolvedor para inferir informaes de mapeamento. A definio deste mecanismo pode influenciar bastante no
desempenho final da aplicao que utiliza a biblioteca ORM [Barnes, 2007].
3) Orientado ao banco de dados: Neste paradigma o desenvolvedor deve primeiramente criar o banco de dados. Ento a biblioteca ORM auxiliada por metadados
12

Informaes complementares sobre outro conjunto de dados. Podem ser utilizados, por exemplo, para
descrever a estrutura destes.

2.7 Bibliotecas de Mapeamento Objeto Relacional

30

consegue gerar o cdigo das classes a serem mapeadas e das operaes de persistncia. A grande desvantagem deste paradigma a no abstrao do conhecimento de
banco de dados, visto que o desenvolvedor deve primeiramente definir a estrutura
da base de dados a ser utilizada. Outra desvantagem o desenvolvedor no ter a
permisso de modificar o cdigo das classes mapeadas pela biblioteca ORM. Sua
vantagem consiste no melhor controle da definio da estrutura da base de dados
sendo utilizada [Barnes, 2007].
As bibliotecas de mapeamento mais robustas possuem a possibilidade de operar nos
trs paradigmas citados. Em alguns casos, elas ainda permitem que o desenvolvedor tenha
controle dos trs componentes principais citados pelos paradigmas, ou seja, o desenvolvedor pode definir o cdigo das classes a serem mapeadas, os metadados e construir o banco
de dados a ser utilizado, deixando para a biblioteca ORM somente a tarefa de adicionar
o cdigo de persitncia [Barnes, 2007].
Existe ainda o conceito de transparncia, que aplicado a bibliotecas que utilizam o
paradigma orientado aplicao. Uma biblioteca ORM transparente quando no requer
que classes implementem interfaces, ou sigam um modelo especfico de cdigo para serem
mapeadas [Barnes, 2007]. Estas bibliotecas seguem a filosofia de que as classes envolvidas
no software no precisam saber como, porque ou quando elas sero persistidas, ou seja,
elas devem se comportar como classes ordinrias ou comuns.
Analisando as principais funcionalidades que as bibliotecas ORM possuem, podemos
perceber que elas promovem uma melhoria considervel de produtividade (economia de
tempo de desenvolvimento) alm de diminuir a complexidade do desenvolvimento de sistemas que lidam com gerenciamento constante de dados persistidos em bancos de dados
relacionais [Barnes, 2007].

Captulo 3
Trabalhos Relacionados

Neste captulo so apresentadas algumas bibliotecas ORM presentes no mercado e um


trabalho que props o desenvolvimento de uma biblioteca ORM para a linguagem C++.
O modelo de uso e desenvolvimento destas bibliotecas serviram como inspirao para a
construo deste trabalho. E duas das bibliotecas citadas so utilizadas em testes de
comparao de usabilidade no captulo 5.

3.1

Um Framework de Mapeamento Objeto Relacional com um Exemplo em C++

Em seu trabalho intitulado Um Framework de Mapeamento Objeto Relacional com um


Exemplo em C++, originalmente em ingls, A Framework for Object-Relational Mapping
With An Example in C++, Zhang Xiaobing apresenta um modelo para desenvolvimento
de uma biblioteca ORM que pode ser utilizado na maioria das linguagens orientadas a
objetos. Em seu modelo, ele define padres a serem utilizados para resolver problemas
como mapeamento de classes simples, herana, composio, associao, e ainda define
mecanismos de otimizao como criao de um cache de objetos resgatados do banco de
dados [Zhang, 2004].
Seu modelo define uma biblioteca ORM que segue o paradigma orientado a aplicao,
onde o desenvolvedor ficar responsvel por definir toda a parte do cdigo relacionado
a criao dos objetos a serem mapeados. Todo objeto a ser mapeado deve herdar de
uma classe especfica, e o desenvolvedor deve reimplementar determinados mtodos de
modo a informar para a biblioteca metadados que definem o mapeamento. Devido a esse
comportamento dizemos que a biblioteca no transparente. O modelo ainda define uma
arquitetura de desenvolvimento em duas camadas:

3.2 QxORM

32

1) Camada de objetos (Object Layer ): Camada responsvel por prover uma interface simples para definio de classes a serem mapeadas e seus metadados, alm de
trafegar dados entre os objetos mapeados e a camada de persistncia. Esta camada
a nica acessvel diretamente pelo desenvolvedor.
2) Camada de persistncia (Storage Layer ): Camada responsvel por abstrair a comunicao com o SGBD, provendo rotinas de persistncia, concorrncia, recuperao de erros e execues de pesquisas no banco de dados. Esta camada no
diretamente acessvel pelo desenvolvedor.
O modelo definido pode ser aplicado em diversas linguagens pelo fato de no se aproveitar de recursos especficos de determinadas linguagens, porm devido a isso ele exige
um trabalho adicional do desenvolvedor ao reimplementar mtodos de diversas interfaces
definidas. Em alguns momentos, o desenvolvedor deve explicitamente executar funes
de consulta e ajuste de valores de atributos em suas classes trocando informaes com
o framework para permitir a execuo de tarefas no banco de dados [Zhang, 2004]. Isso
ocorre devido a biblioteca no definir um mecanismo de listagem e acesso s estruturas
internas dos objetos mapeados.
Neste trabalho o modelo de Zhang utilizado como base para a implementao de
uma biblioteca ORM para C++, porm com alguns ajustes como a definio de uma
interface de anotaes para definies de mapeamento, e a capacidade de mapeamento
de classes arbitrrias, sem a necessidade de herana de uma classe especfica (biblioteca
transparente).

3.2

QxORM

QxORM uma biblioteca ORM de cdigo aberto desenvolvida para ser utilizada em
conjunto com o framework Qt. Ela utiliza vrios mdulos deste framework como auxlio
na execuo das tarefas de mapeamento, como por exemplo, o mdulo QtSql para realizar
interaes com os SGBDs. Foi criada em 2003 e mantida pelo Engenheiro de software
Lionel Marty [Marty, 2014].
Esta biblioteca segue o paradigma orientado a aplicao, e transparente, ou seja,
permite o mapeamento de classes arbitrrias. Para mapear uma classe, o desenvolvedor deve inserir algumas marcaes na definio da classe, e implementar um mtodo
utilizando funes especficas para registros de informaes das classes e atributos a se-

3.3 ODB

33

rem mapeados. Portanto, nesta biblioteca tambm no existe um sistema de anotaes


[Marty, 2014].
Esta biblioteca utilizada durante testes de usabilidade, onde comparada a sua
abordagem de especificao de mapeamento com a interface de anotaes criada neste
trabalho. Alm de testes de usabilidade, tambm ser feita a comparao do processo
de configurao do ambiente de desenvolvimento para utilizao desta biblioteca com a
desenvolvida neste trabalho.

3.3

ODB

ODB uma biblioteca ORM desenvolvida para ser utilizada com a linguagem C++.
uma biblioteca de cdigo aberto e mantida pela empresa Code Synthesis. Ao contrrio
da biblioteca QxOrm, a ODB no foi desenvolvida para ser utilizada especificamente em
conjunto com um framework ou outra biblioteca, mas sim com a linguagem C++ pura.
Para ser utilizada em conjunto com o framework Qt, por exemplo, a biblioteca disponibiliza um recurso chamado profile, que atua como uma espcie de plugin adicional que
pode ser acoplado a biblioteca para habilitar seu uso em conjunto [Synthesis, 2013].
Mesmo quando utilizada com profiles, a biblioteca utiliza mecanismos prprios para
acesso a banco de dados e construo de sentenas em linguagem SQL. As informaes de mapeamento so especificadas atravs do uso de diretivas de pr-processamento
pragma 1 . Estas informaes so analisadas por um compilador disponibilizado em
conjunto com a biblioteca, que gera ento cdigo em C++ com os comandos para realizar
tarefas de persistncia [Synthesis, 2013].
A biblioteca utiliza o paradigma orientado a aplicao com uma abordagem transparente, pois no obriga o desenvolvedor a implementar interfaces ou aplicar herana nas
classes a serem mapeadas para o banco de dados. Seu sistema de insero de metadados
bem parecido com o sistema de anotaes, porm estes metadados somente so acessveis
pelo seu compilador externo [Synthesis, 2013].
Esta biblioteca tambm utilizada durante testes de usabilidade e de configurao do
ambiente de desenvolvimento no Captulo 5.
1

Diretiva de pr-processamento que permite ao desenvolvedor passar informaes durante a compilao


que so especficas de um compilador utilizado.

3.4 Hibernate

3.4

34

Hibernate

O Hibernate uma das bibliotecas ORM escritas em JAVA, mais conhecidas atualmente.
um projeto de cdigo aberto mantido e desenvolvido pela empresa Red Hat. Esta
biblioteca uma das bibliotecas ORM mais completas, sendo pioneira na implementao
de vrios mecanismos de otimizao. Ela utiliza um paradigma orientado a aplicao e a
insero de metadados de mapeamento pode ser feita a partir da utilizao de arquivos
XML, ou a partir da utilizao do mecanismo de anotaes presente na linguagem JAVA
[Bauer and King, 2005].
A biblioteca capaz de mapear classes que utilizam mecanismos de herana e composio, alm de ter a capacidade de a partir da anlise das classes mapeadas e dos metadados,
criar o banco de dados equivalente. Seu mecanismo de anotaes a inspirao principal
do desenvolvimento deste trabalho, pois tal mecanismo traz um nvel de facilidade enorme
na configurao dos dados de mapeamento, e at ento poucas bibliotecas voltadas para
a linguagem C++ apresentam algo semelhante [Bauer and King, 2005].

Captulo 4
A Biblioteca ORM4Qt

Desenvolver aplicativos multiplataforma utilizando a linguagem C++ uma tarefa muito


difcil, devido reduzida biblioteca padro da linguagem, e aos diversos componentes
especficos desenvolvidos para cada plataforma. Esta complexidade pode ser minimizada
a partir do uso de frameworks multiplataforma, como o Qt, para compor nosso ambiente
de desenvolvimento. Porm, em comparao com ambientes oferecidos por linguagens
mais recentes, este apresenta poucos mecanismos de automatizao de tarefas diversas,
ou os que existem apresentam interfaces complexas para utilizao. o que acontece por
exemplo com as bibliotecas de Mapeamento Objeto Relacional (ORM).
Analisando o ambiente de desenvolvimento oferecido a partir da combinao da linguagem C++ com o framework Qt, encontramos algumas implementaes de bibliotecas
ORM, destacando-se o QxOrm. Estas bibliotecas, devido ao pouco suporte a reflexo
oferecido pela linguagem C++, em sua maioria apresentam interfaces de configurao
complexas. Alm de usarem mecanismos como herana e "classes friend "1 para quebra
de encapsulamento das classes a serem mapeadas, o que indesejvel por aumentar o
nvel de acoplamento do cdigo.
Neste trabalho proposto o desenvolvimento de uma biblioteca ORM intitulada
ORM4Qt para ser utilizada neste ambiente de desenvolvimento. A biblioteca utiliza o
paradigma orientado a aplicao e a abordagem transparente para definio das classes
mapeadas. A interface de configurao do mapeamento feita atravs de um mecanismo
de anotaes desenvolvido especificamente para a biblioteca. Para a quebra de encapsulamento das classes ser utilizada a manipulao de ponteiros de funes atravs do uso de
estruturas de alto nvel oferecidos pela linguagem C++. A biblioteca desenvolvida capaz
1

Este recurso permite que uma classe ou mtodo global externo acesse os componentes privados de
uma classe.

4.1 Arquitetura em Camadas

36

de mapear somente classes simples, ou seja, que contm somente atributos escalares e no
utilize herana. Posteriormente, ela poder ser estendida para suportar o mapeamento de
classes que utilizem mecanismos mais avanados da orientao a objetos.
Das bibliotecas ORM existentes para o cenrio abordado, a QxOrm e a ODB so as
que mais se aproximam das caractersticas citadas, portanto elas so utilizada em testes ao
final do desenvolvimento que comparam a configurao do ambiente de desenvolvimento
para utilizao das bibliotecas, a facilidade em utilizao dos mecanismos de configurao
de mapeamento e a facilidade em migrao de cdigo legado.
Nas prximas sees sero detalhados os mecanismos utilizados para o desenvolvimento, bem como a arquitetura utilizada.

4.1

Arquitetura em Camadas

O desenvolvimento da biblioteca estruturado em duas camadas, a camada objeto (ou


Object Layer) e a camada de armazenamento (ou Storage Layer), seguindo
a nomenclatura utilizada no trabalho desenvolvido por [Zhang, 2004]. As duas camadas
oferecem interfaces acessveis diretamente pelo desenvolvedor e cooperam entre si atravs
de troca de informaes.
A camada objeto tem como objetivo apresentar uma interface transparente para o
desenvolvedor que permita a configurao das classes a serem mapeadas e apresentar uma
interface para a camada de Armazenamento que permita o acesso aos metadados bem
como estrutura interna das classes sendo mapeadas. Esta camada a mais complexa
de ser desenvolvida devido ao uso intenso de estruturas de baixo nvel da linguagem para
quebra de encapsulamento e criao do mecanismo de anotaes.
A camada de armazenamento tem como objetivo apresentar uma interface para o
desenvolvedor que permita executar tarefas relacionadas com a persistncia de objetos no
banco de dados, alm de definir uma interface comum de gerao de cdigo SQL que possa
ser implementada para diferentes SGBDs. Inicialmente esta interface implementada
para o SGBD PostgreSQL, e utiliza os mecanismos oferecidos pelo mdulo QtSql para se
comunicar com ele.
Na imagem 4.1 temos uma representao de alto nvel da interao entre os mdulos,
o desenvolvedor, o banco de dados e as classes a serem mapeadas durante o funcionamento
da biblioteca. Nas sees subsequentes as duas camadas so detalhadas em conjunto com

4.2 Camada Objeto

37

os mecanismos especficos envolvidos no seu desenvolvimento.

Figura 4.1: Interao entre componentes do software e desenvolvedor

4.2

Camada Objeto

Para que seja possvel realizar o mapeamento, a biblioteca ORM deve ser capaz de conhecer e acessar a estrutura interna das classes a serem mapeadas. Existem basicamente dois
limitadores que dificultam alcanar este cenrio na linguagem C++. O primeiro deles
consiste na possibilidade de o desenvolvedor limitar o acesso estrutura interna atravs
das diretivas de proteo oferecidas pela linguagem durante a definio das classes. A
biblioteca ORM precisa ter acesso de leitura e escrita nos atributos das classes sendo mapeadas, porm em geral eles so mantidos com permisso de acesso privado, onde somente
podem ser acessados diretamente de dentro da classe.
O segundo deles o baixo suporte da linguagem a mecanismos de reflexo. Antes de
acessar os atributos das classes a biblioteca deve saber quais so os atributos que a classe
contm, entretanto em seu atual estado, a linguagem oferece somente informaes bsicas

4.2 Camada Objeto

38

sobre os objetos, como por exemplo o nome de sua classe. No trecho de cdigo 16 temos
um exemplo da obteno do nome da classe de um objeto em tempo de execuo. Na
linha 1 criado um objeto da classe Pessoa, e na linha 2 capturado o nome da classe
deste objeto e exibido no console. A sada gerada por este programa quando compilado
no compilador que acompanha o Visual Studio 2013 o texto class Pessoa.
1
2

Pessoa o b j = new Pessoa ( ) ;


s t d : : c o u t << t y p e i d ( o b j ) . name ( ) << s t d : : e n d l ;

Algoritmo 16: Obtendo o nome da classe de um objeto em tempo de execuo


A camada objeto utiliza dois mecanismos para contornar estes limitadores, os quais
so descritos nas sees a seguir.

4.2.1

Quebrando o Encapsulamento das Classes

Quando os atributos das classes so declarados com acesso pblico, a biblioteca ORM
pode acess-los diretamente, porm este cenrio no normalmente utilizado pelos desenvolvedores e a utilizao da biblioteca impor tal cenrio uma caracterstica indesejvel
e que poderia diminuir sua aceitao no mercado. Para resolver este problema foi pressuposto que todos os atributos a serem acessados nas classes a serem mapeadas estaro com
acesso privado, ou seja, s podem ser acessados de dentro das classes. Com isso em mente
podemos tambm definir que somente poderemos acessar os atributos das classes atravs
do uso de um intermediador que componha a estrutura da classe, ou mais precisamente
um mtodo que compe a interface da classe.
A primeira ideia que vem em mente utilizar mtodos acessadores (popularmente
conhecidos como mtodos get e set) criados pelos desenvolvedores, porm temos
alguns limitadores que dificultam a sua utilizao. Um deles que no podemos assumir
que para todo atributo existem mtodos acessadores, pois podem existir atributos somente
leitura ou cujo valor controlado internamente na classe. Outro limitador a ausncia
de padronizao do prottipo dos mtodos acessadores, pois estes mtodos podem ser
definidos com uma quantidade varivel de parmetros. Alm disso, a linguagem C++
permite a criao de variaes destes mtodos atravs da modificao do tipo de parmetro
e/ou retorno (ponteiro, referncia ou por valor), alm do uso do modificador const na
declarao de mtodos de leitura.
Devido a estas caractersticas, o uso de ponteiros genricos para mtodos, por exemplo,
no poderia ser utilizado, pois teramos que variar a definio dos ponteiros de acordo com

4.2 Camada Objeto

39

o prottipo dos mtodos utilizados. No trecho de cdigo 17 apresentado um exemplo


das possveis variaes de declaraes de mtodos acessadores para um atributo do tipo
inteiro.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

// Mtodos g e t
int get () ;
int get () ;
i n t &g e t ( ) ;
int get () const ;
int get () const ;
i n t &g e t ( ) c o n s t ;
// Mtodos s e t
void s e t ( i n t valor ) ;
v o i d s e t ( i n t &v a l o r ) ;
void s e t ( i n t valor ) ;
void s e t ( const i n t valor ) ;
v o i d s e t ( c o n s t i n t &v a l o r ) ;
void s e t ( const i n t valor ) ;

Algoritmo 17: Exemplo de variaes na declarao de mtodos acessadores para


atributos tipo inteiro
Como no possvel utilizar os mtodos acessadores, a soluo proposta a insero
de mtodos intermediadores na definio das classes a serem mapeadas. Dessa maneira
podemos criar os mtodos seguindo prottipos pr-definidos, o que permite manipullos mais facilmente atravs de ponteiros. Porm, esta soluo ainda tem um problema,
se formos criar um mtodo para cada atributo da classe, a quantidade destes pode se
tornar muito grande, o que causaria uma modificao extrema da interface original da
classe mapeada, o que indesejvel. Para diminuir os efeitos deste problema proposto
a utilizao de expresses lambda.
As expresses lambda so estruturas que permitem a criao de mtodos annimos,
ou seja, que no tm um nome ou marcador de referncia, o que implica em eles no
fazerem parte de interfaces de classes ou at mesmo do escopo global. Estas estruturas
so manipuladas de maneira semelhante aos ponteiros de funes, porm possuem um tipo
de dado padro para seu armazenamento, o std::function. Desta maneira podemos
inserir somente um mtodo na classe a ser mapeada e dentro deste criar expresses lambda
para manipular os atributos. As expresses criadas podem ser ento agrupadas em uma
estrutura de lista e retornadas. Como as expresses foram criadas dentro da classe sendo
manipulada, elas tm acesso aos atributos privados normalmente, alm de poderem ser
transportadas como variveis comuns.
No trecho de cdigo 18 temos um exemplo de uma classe com um atributo privado
do tipo inteiro, e uma funo que retorna uma expresso lambda capaz de acessar este

4.2 Camada Objeto

1
2
3
4
5
6
7
8
9
10

40

c l a s s Class
{
public :
s t d : : f u n c t i o n <i n t ( )> getLambda ( )
{
r e t u r n [ & ] ( ) > i n t { r e t u r n t h i s >v a l o r ; } ;
}
private :
int valor ;
};

Algoritmo 18: Retornando uma expresso lambda para acesso de atributo privado
atributo. Na linha 4 temos a definio do mtodo que retorna a expresso lambda e na
linha 6 a sua criao e retorno. A sintaxe de criao de expresses lambda pode parecer
estranha inicialmente, porm com o decorrer do seu uso ela se torna prtica e simples. O
mtodo criado pela biblioteca no retorna uma simples lista de expresses lambda, mas
um objeto que alm de armazenar as expresses, armazena metadados, como veremos no
prximo tpico.

4.2.2

Inserindo Metadados Atravs de Anotaes

Como no temos um mecanismo nativo para obter conhecimento sobre as estruturas das
classes sendo mapeadas em momento de execuo, temos que criar algum mecanismo
que permita a criao destas informaes. Uma maneira de fazer isto seria criar um
analisador de cdigo, que a partir da leitura dos arquivos de definio das classes geraria
estas informaes automaticamente. Esta soluo tem a grande vantagem de gerar as
informaes em momento de compilao e agir de forma transparente. Entretanto, a
implementao de tal soluo uma tarefa bastante complexa, alm de seu uso promover
uma quebra no fluxo padro de compilao de programas, pois o desenvolvedor ter que
inserir a execuo deste analisador no fluxo de compilao antes da execuo do prprio
compilador. Outro problema, que somente a informao das estruturas das classes no
suficiente para realizar o mapeamento, precisamos de informaes a mais, como o nome
das colunas equivalentes aos atributos.
A soluo proposta neste trabalho consiste em inserir um mtodo nas classes mapeadas que retorne uma estrutura com todos os metadados necessrios para o mapeamento,
ampliando a ideia exposta na seo 4.2.1. Para organizar as informaes a serem retornadas foi criada uma hierarquia de classes de armazenamento de metainformaes,
baseada em uma classe chamada Reflect. Esta classe permite o registro de tuplas do

4.2 Camada Objeto

41

tipo chave e valor, chamadas de tags, que podem ser recuperadas atravs de funes
de sua interface. A partir desta classe so definidas as classes Property e Class.
A primeira responsvel por descrever as informaes relativas a um atributo de uma
classe, e prov mtodos para acesso a este atributo em uma instncia de classe utilizando
o mecanismo de expresses lambda citado anteriormente. A segunda classe responsvel
por descrever as informaes relativas a uma classe. Ela contm uma lista de objetos de
descrio de atributos, alm de permitir a definio de informaes adicionais atravs da
insero de tags. Na imagem 4.2 temos um diagrama de classe simplificado que demonstra
a hierarquia criada.

Figura 4.2: Diagrama simplificado das classes de reflexo


Com o uso desta tcnica conseguimos contornar os dois limitadores impostos pela
linguagem C++ para conhecimento e acesso a estrutura de objetos em tempo de execuo,
porm, ainda temos um problema relacionado com a insero do mtodo que retorna o
objeto de reflexo. Ao impormos ao desenvolvedor a necessidade de criar tal mtodo,
a biblioteca deixa de ser transparente, pois estamos impondo a implementao de uma
interface nas classes a serem mapeadas. Para contornar este problema proposto a criao
de uma camada de abstrao atravs do uso de macros de registro, simulando o recurso de
anotaes existentes na linguagem JAVA. Estas macros em tempo de pr-processamento
do cdigo sero expandidas, construindo o mtodo de retorno do objeto de reflexo. Desta
maneira a criao do mtodo ser feita de forma transparente para o desenvolvedor.
No trecho de cdigo 19 temos um esboo da utilizao deste mecanismo. Nas linhas 7

4.3 Camada de Armazenamento

42

e 13 temos as macros ORM4QT_BEGIN e ORM4QT_END, que delimitam o


incio e final da rea de especificao de mapeamento. A primeira macro ser expandida
gerando a declarao do mtodo de retorno do objeto de reflexo e a segunda expandir
o encerramento do mtodo. Todas as macros compreendidas entre elas iro expandir o
corpo do mtodo. As outras duas macros utilizadas so a CLASS que recebe como
parmetros uma lista varivel de tags, e a macro PROPERTY que recebe o atributo a
ser mapeado, seguido de uma srie de tags. Estas macros servem para registrar metadados
sobre classes e atributos respectivamente.

1
2
3
4
5

c l a s s Classe
{
private :
int inteiro ;
std : : s t r i n g texto ;

6
7

ORM4QT_BEGIN

8
9
10
11

CLASS( name=" C l a s s e " , t a b l e=" t a b e l a " )


PROPERTY( i n t e i r o , column="numero" )
PROPERTY( t e x t o , column=" f r a s e " )

12
13
14

ORM4QT_END
};

Algoritmo 19: Esboo da utilizao de macros para registro de metainformao


Com este mecanismo definido foi possvel implementar as responsabilidades da camada
objeto. Nas prximas sees so detalhados os mecanismos utilizados para implementao
da camada de armazenamento.

4.3

Camada de Armazenamento

O objetivo principal de uma biblioteca ORM abstrair do desenvolvedor a criao dos


comandos SQL para executar as tarefas de persistncia, bem como a comunicao com
o banco de dados. A camada de armazenamento alcana este cenrio a partir da utilizao de duas classes. A primeira a Repository, que disponibiliza em sua interface
mtodos para salvar, atualizar, deletar e carregar registros de objetos no banco de dados.
Esta classe oferece a possibilidade do uso de transaes para garantir que um grupo de
operaes seja executado de forma atmica. Ela tambm tem a responsabilidade de gerenciar a comunicao com o banco de dados, o que feito atravs da utilizao da API
disponibilizada pelo mdulo QtSQL oferecido pelo framework Qt.

4.3 Camada de Armazenamento

43

A segunda classe a SQLProvider que define uma interface para gerao de comandos em linguagem SQL para a execuo das tarefas de persistncia de objetos. Ela
utiliza os objetos de reflexo disponibilizados pela camada objeto para construir sentenas
de acordo com a instncia de objeto a ser persistida. Esta interface deve ser implementada
para cada tipo de SGBD que se deseja utilizar, desta forma a adio de suporte da biblioteca para diversos SGBDs se torna uma tarefa mais simples. A classe Repository utiliza
uma implementao desta interface para gerar os comandos necessrios para execuo de
suas tarefas.

Figura 4.3: Diagrama de classes simplificado da camada de armazenamento


Na figura 4.3 temos um esboo do diagrama de classes da camada de Armazenamento,
onde temos a representao de duas possveis implementaes da interface SQLProvider,
uma que daria suporte ao SGBD PostgreSQL e outra ao MySQL. A camada de armazenamento menos complexa pelo fato de utilizar a prpria camada objeto e o mdulo
QtSql para facilitar sua implementao, porm ela tambm responsvel por tratar os
erros que podem ocorrer durante a comunicao com o banco de dados ou execuo de
comandos SQL, caso em que ela deve retornar mensagens bem formatadas descrevendo
os erros e oferecer mecanismos para gerao de logs.

Captulo 5
Testes

Aps a implementao da biblioteca ORM4Qt foi necessrio definir um modelo de testes que pudesse ser aplicado a ela em conjunto com outras bibliotecas j existentes. O
objetivo deste modelo o de avaliar o nvel de usabilidade da biblioteca sob o ponto de
vista do desenvolvedor, isto , avaliar a facilidade de uso da biblioteca no ambiente de
desenvolvimento utilizado.
O modelo de testes escolhido foi o desenvolvimento de uma aplicao simples chamada Minhas Apostilas, que consiste de um programa que permite o armazenamento de
arquivos no formato PDF em uma base de dados do SGBD PostgreSql. Alm do arquivo,
o aplicativo armazena um pequeno grupo de informaes referentes a ele, como nome,
descrio e data de alterao.
Com o intuito de testar a integrao das bibliotecas utilizadas com o ambiente de
desenvolvimento baseado no framework Qt, o aplicativo utiliza alguns recursos adicionais
do framework para a construo de uma interface grfica (mdulos QtGui e QtWidgets)
e para realizao de tarefas de forma assncrona (mdulo QtConcurrent). Alm disso,
o aplicativo foi desenvolvido de forma totalmente portvel, sendo testado nos sistemas
operacionais Ubuntu 14.04 e Microsoft Windows 8.1, ambos com a arquitetura 64 bits.
Foram escolhidas duas bibliotecas ORM existentes para serem comparadas com a
biblioteca desenvolvida, sendo elas, a ODB e a QxOrm. Ambas bibliotecas foram descritas
no Captulo 4. Nas prximas sees so detalhados os ambientes de desenvolvimento
utilizados para realizao dos testes e descritas as funcionalidades presentes no programa
Minhas Apostilas.

5.1 Ambiente de Testes

5.1

45

Ambiente de Testes

A biblioteca ORM4Qt foi desenvolvida utilizando somente componentes oferecidos pelo


framework Qt verso 5.3 e pela especificao C++11, portanto ela est preparada para
ser utilizada em qualquer ambiente de desenvolvimento que oferea estes componentes.
Porm, neste trabalho somente foram feitos testes nas plataformas Ubuntu verso 14.04
64 bits e Microsoft Windows 8.1 tambm 64 bits.
As outras duas bibliotecas utilizadas nos testes tambm so compatveis com os sistemas citados. Nas duas prximas sees so listados os programas utilizados para compor
o ambiente de desenvolvimento de cada uma destas plataformas.

5.1.1

Ambiente de Testes Ubuntu 14.04

Nesta plataforma foram utilizados os seguintes programas para montagem do ambiente


de desenvolvimento:
Compilador g++ verso 4.8.2: Consiste de um compilador compatvel com a especificao C++11. Ele foi instalado a partir dos repositrios oficiais do sistema;
Bibliotecas do framework Qt verso 5.3: Foram instaladas a partir de um instalador obtido no site oficial do projeto Qt1 ;
QtCreator verso 3.2.2: Ambiente de desenvolvimento integrado instalado em conjunto com as bibliotecas do framework Qt;
Compilador odb: Programa que compe a biblioteca ODB. Ele foi instalado a partir
de um instalador oferecido no site oficial do projeto2 ;
Bibliotecas libodb, libodb-pgsql e libodb-qt: Compem a biblioteca ODB e so necessrias para utiliz-la em conjunto com o framework Qt e com o SGBD PostgreSql.
Estas bibliotecas foram instaladas a partir da compilao de seus cdigos fonte que
tambm so disponibilizados no site oficial do projeto;
Biblioteca boost: Dependncia necessria para utilizao da biblioteca QxOrm. Foi
instalada a partir dos repositrios oficiais do sistema;
Biblioteca QxOrm: Foi acoplada no projeto do programa Minhas Apostilas;
1
2

http://qt-project.org
http://www.codesynthesis.com/products/odb/

5.1 Ambiente de Testes

46

Biblioteca ORM4Qt: Tambm acoplada no projeto do programa Minhas Apostilas;


SGBD PostgreSql: Instalado a partir dos repositrios oficiais do sistema.

5.1.2

Ambiente de Testes Microsoft Windows 8.1

Nesta plataforma foram utilizados os seguintes programas para montagem do ambiente


de desenvolvimento:
Microsoft Visual Studio 2013 Express: Ambiente de desenvolvimento oferecido pela
Microsoft e que acompanha um compilador C++ compatvel com as funcionalidades
da especificao C++11 utilizadas neste trabalho;
Bibliotecas do framework Qt verso 5.3: Foram instaladas a partir de um instalador obtido no site oficial do projeto Qt;
QtCreator verso 3.2.2: Ambiente de desenvolvimento integrado instalado em conjunto com as bibliotecas do framework Qt;
Compilador odb: Programa que compe a biblioteca ODB. Ele foi instalado a partir
de um instalador oferecido no site oficial do projeto;
Bibliotecas libodb, libodb-pgsql e libodb-qt: Compem a biblioteca ODB e so necessrias para utiliz-la em conjunto com o framework Qt e com o SGBD PostgreSql.
Estas bibliotecas foram instaladas a partir da compilao de seus cdigos fonte que
tambm so disponibilizados no site oficial do projeto;
Biblioteca boost: Dependncia necessria para utilizao da biblioteca QxOrm. Foi
compilada a partir do cdigo fonte obtido no site oficial do projeto3 ;
Biblioteca QxOrm: Foi acoplada no projeto do programa Minhas Apostilas;
Biblioteca ORM4Qt: Tambm acoplada no projeto do programa Minhas Apostilas;
SGBD PostgreSql: Instalado a partir de um instalador disponibilizado no site oficial
do projeto4 .
3
4

http://boost.org
http://postgresql.org

5.2 O Projeto Minhas Apostilas

5.2

47

O Projeto Minhas Apostilas

O projeto utilizado para testes foi chamado de Minhas Apostilas e consiste de um


aplicativo simples que permite o cadastro de arquivos PDF com informaes adicionais
de descrio em uma base de dados do SGBD PostgreSql.
As principais funes presentes no programa so a insero, edio, deleo e pesquisa
de registros de documentos. A tela inicial do programa pode ser vista na imagem 5.1.

Figura 5.1: Tela inicial do programa Minhas Apostilas


O mecanismo que permite a utilizao das trs bibliotecas ORM no projeto se baseia
nas classes Documento e IRepository que so expostas nas sees seguintes. Aps
a explicao das classes so expostos os mecanismos utilizados para desenvolvimento de
cada uma das funcionalidades do aplicativo.

5.2.1

A Classe Documento

Para representar os documentos gerenciados pelo programa, foi criada uma classe chamada
Documento, cuja definio pode ser vista no trecho de cdigo 20. A classe definida
contm 6 atributos que armazenam os dados referentes a cada arquivo gerenciado pelo
aplicativo:
Cdigo: Consiste de um identificador numrico nico associado com cada arquivo armazenado. armazenado internamente no atributo privado m_codigo e acessvel
atravs dos mtodos codigo (leitura) e setCodigo (escrita);

5.2 O Projeto Minhas Apostilas

1
2
3
4
5
6

c l a s s Documento
{
public :
// C o n s t r u t o r e d e s t r u t o r
Documento ( ) ;
v i r t u a l ~Documento ( ) ;

7
8
9
10
11
12
13
14
15
16
17
18
19
20

// Mtodos a c e s s a d o r e s
qlonglong codigo () const ;
v o i d s e t C o d i g o ( c o n s t q l o n g l o n g &c o d i g o ) ;
QString nome ( ) c o n s t ;
v o i d setNome ( c o n s t QString &nome ) ;
QString d e s c r i c a o ( ) c o n s t ;
v o i d s e t D e s c r i c a o ( c o n s t QString &d e s c r i c a o ) ;
QDateTime u l t i m a A l t e r a c a o ( ) c o n s t ;
v o i d s e t U l t i m a A l t e r a c a o ( c o n s t QDateTime &u l t i m a A l t e r a c a o ) ;
quint16 versao () const ;
v o i d s e t V e r s a o ( c o n s t q u i n t 1 6 &v e r s a o ) ;
QByteArray a r q u i v o ( ) c o n s t ;
v o i d s e t A r q u i v o ( c o n s t QByteArray &a r q u i v o ) ;

21
22
23
24
25
26
27
28
29
30

private :
// A t r i b u t o s p r i v a d o s
q l o n g l o n g m_codigo ;
QString m_nome ;
QString m_descricao ;
QDateTime m_ultimaAlteracao ;
q u i n t 1 6 m_versao ;
QByteArray m_arquivo ;
};

Algoritmo 20: Definio da classe Documento

48

5.2 O Projeto Minhas Apostilas

49

Nome: Consiste de um nome para identificar o arquivo armazenado. armazenado internamente no atributo privado m_nome e acessvel atravs dos mtodos nome
(leitura) e setNome (escrita);
Descrio: Consiste de um campo de texto com uma descrio do arquivo armazenado.
armazenada internamente no atributo privado m_descricao e acessvel atravs
dos mtodos descricao (leitura) e setDescricao (escrita);
ltima alterao: Armazena a data e hora em que foi efetuada a ltima alterao no arquivo armazenado. armazenado internamente no atributo privado m_ultimaAlteracao
e acessvel atravs dos mtodos ultimaAlteracao (leitura) e setUltimaAlteracao
(escrita);
Verso: Armazena o nmero da verso do arquivo armazenado. armazenado internamente pelo atributo m_versao e acessvel atravs dos mtodos versao (leitura)
e setVersao (escrita);
Arquivo: Armazena a sequncia de bytes em formato puro, que compe o arquivo armazenado. armazenado internamente no atributo privado m_arquivo e acessvel
atravs dos mtodos arquivo (leitura) e setArquivo (escrita).
Esta classe foi mapeada para o banco de dados utilizando os mecanismos presentes
nas trs bibliotecas ORM utilizadas no teste. O mapeamento foi configurado de forma que
a classe mapeada para uma tabela com nome t_documentos, o atributo m_codigo
mapeado para a coluna c_codigo, o atributo m_nome para a coluna c_nome,
o atributo m_descricao para a coluna c_descricao, o atributo m_ultimaAlteracao
para a coluna c_ultimaalteracao, o atributo m_versao para a coluna c_versao e o
atributo m_arquivo para a coluna c_arquivo.
Nas sees seguintes so apresentados os mecanismos utilizados para configurao do
mapeamento com cada uma das bibliotecas testadas.
5.2.1.1

Mapeamento com a Biblioteca ORM4Qt

O mapeamento com a biblioteca ORM4Qt foi configurado atravs da adio de uma srie
de macros no final do bloco de definio da classe. O trecho de cdigo 21 demonstra as
macros utilizadas para configurar o mapeamento.
Nas linhas 2 e 11 temos as macros que definem o incio e final da regio de configurao
do mapeamento, respectivamente. Na linha 3 temos a macro CLASS que utilizada

5.2 O Projeto Minhas Apostilas

1
2
3
4
5
6
7
8
9
10
11

50

//Orm4Qt a n n o t a t i o n s
ORM4QT_BEGIN
CLASS( name="Documento" , autocolumn=" c o d i g o " , t a b l e=" t_documento " )
PROPERTY( m_codigo , name=" c o d i g o " , column=" c_codigo " , key=t r u e )
PROPERTY(m_nome, name="nome" , column="c_nome" )
PROPERTY( m_descricao , name=" d e s c r i c a o " , column=" c _ d e s c r i c a o " )
PROPERTY( m_ultimaAlteracao , name=" u l t i m a A l t e r a c a o " ,
column=" c _ u l t i m a a l t e r a c a o " )
PROPERTY( m_versao , name=" v e r s a o " , column=" c_versao " )
PROPERTY( m_arquivo , name=" a r q u i v o " , column=" c_arquivo " )
ORM4QT_END

Algoritmo 21: Mapeamento da classe Documento com a biblioteca ORM4Qt


para definir metadados relativos classe atravs da especificao de tuplas no formato
chave=valor. Para que o mapeamento funcione, temos que informar obrigatoriamente
um valor para as chaves name (nome da classe) e para a chave table (nome da tabela
correspondente classe no banco de dados). Neste caso tambm foi informada a chave
autocolumn que define o nome da propriedade do tipo numrico que incrementada
automaticamente pelo banco de dados durante insero de registros, que corresponde a
propriedade cdigo neste caso.
Nas linhas 4 at a 9 utilizada a macro PROPERTY que tem como objetivo inserir
metadados relativos s propriedades da classe. Esta macro recebe como parmetro o nome
do atributo interno que armazena a propriedade a ser mapeada, seguida por uma lista
de tuplas no formato chave=valor. Para que o mapeamento funcione, temos que informar obrigatoriamente um valor para a chave column (nome da coluna correspondente
propriedade mapeada na tabela no banco de dados).
Neste caso tambm so informados valores para as chaves name (apelido para a
propriedade utilizado na construo de filtros de pesquisa) e key (define se a propriedade
compe a chave primria da tabela correspondente a classe). Como pode ser observado no
trecho de cdigo, a configurao do mapeamento com a biblioteca ORM4Qt bem simples
e apresenta uma sintaxe bem prxima das anotaes utilizadas na linguagem JAVA, por
exemplo.
5.2.1.2

Mapeamento com a Biblioteca ODB

Para realizar o mapeamento com a biblioteca ODB foi necessrio incluir uma srie de
diretivas de pr-processamento no arquivo de definio da classe. Para o desenvolvimento
do aplicativo de testes tambm foi necessria a definio de duas estruturas, que so

5.2 O Projeto Minhas Apostilas

51

utilizadas para limitar o conjunto de propriedades durante a pesquisa de registros e para


calcular o nmero de registros presentes no banco de dados. O cdigo para configurao
do mapeamento com a biblioteca ODB exposto no trecho de cdigo 22.

1
2
3
4
5
6
7
8
9

//Mapeamento com o ODB Orm


#pragma db o b j e c t ( Documento ) t a b l e ( " t_documento " )
#pragma db member ( Documento : : m_codigo ) i d auto column ( " c_codigo " )
#pragma db member ( Documento : : m_nome) column ( "c_nome" )
#pragma db member ( Documento : : m_descricao ) column ( " c _ d e s c r i c a o " )
#pragma db member ( Documento : : m_ultimaAlteracao ) \
column ( " c _ u l t i m a a l t e r a c a o " )
#pragma db member ( Documento : : m_versao ) column ( " c_versao " )
#pragma db member ( Documento : : m_arquivo ) column ( " c_arquivo " )

10
11
12
13
14
15
16
17

// E s t r u t u r a usada para c o n t a r a q u a n t i d a d e de r e g i s t r o s
#pragma db view o b j e c t ( Documento )
s t r u c t DocumentoInfo
{
#pragma db column ( " count ( " + Documento : : m_codigo + " ) " )
std : : size_t quantidade ;
};

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

// E s t r u t u r a u t i l i z a d a para l i m i t a r a s p r o p r i e d a d e s p e s q u i s a d a s
#pragma db view o b j e c t ( Documento )
s t r u c t DocumentoView
{
#pragma db column ( Documento : : m_codigo )
qlonglong codigo ;
#pragma db column ( Documento : : m_nome)
QString nome ;
#pragma db column ( Documento : : m_descricao )
QString d e s c r i c a o ;
#pragma db column ( Documento : : m_ultimaAlteracao )
QDateTime u l t i m a A l t e r a c a o ;
#pragma db column ( Documento : : m_versao )
quint16 versao ;
};

Algoritmo 22: Mapeamento da classe Documento com a biblioteca ODB


Na linha 2 informado o nome da tabela no banco de dados equivalente a esta classe.
Nas linhas 3 at 9 so informados os nomes das colunas equivalentes a cada propriedade da
classe mapeada. Importante observar que na linha 3 so utilizadas as palavras chave auto
e id para informar que a propriedade m_codigo da classe um campo numrico que
ser incrementado automaticamente pelo banco de dados durante inseres de registros,
e, que este atributo define a chave primria da tabela mapeada, respectivamente.
Nas linhas 12 at 17 definida a estrutura DocumentoInfo que utilizada em funes
do aplicativo que precisam recuperar do banco de dados o nmero de registros presentes.
E, por fim, nas linhas 20 at 33 definida a estrutura DocumentoView, que utilizada

5.2 O Projeto Minhas Apostilas

52

no programa para recuperar registros, ignorando o atributo arquivo ao preencher tabelas


de visualizao de dados (feito assim para fins de desempenho).
Aps esta configurao foi necessrio executar o compilador odb passando como parmetro o arquivo de definio da classe. Este compilador gerou os arquivos documentoodb.hxx, documento-odb.ixx e documento-odb.cxx que contm o cdigo para as rotinas de troca de informaes com o banco de dados. Estes arquivos foram acoplados no
projeto do programa, e toda vez que foi necessria a modificao da estrutura da classe
Documento foi necessrio executar novamente o compilador para gerar os arquivos citados.
5.2.1.3

Mapeamento com a Biblioteca QxOrm

Para configurar o mapeamento com a biblioteca QxOrm foi necessrio incluir uma macro
no bloco de definio da classe para ativar o mecanismo de classes friend da linguagem
C++, permitindo biblioteca o acesso aos atributos privados. Foi necessrio tambm
incluir uma srie de macros extras no arquivo de definio da classe e implementar uma
funo de registro de metadados. No trecho de cdigo 23 possvel observar o cdigo
utilizado para o mapeamento.
Na linha 2 mostrada a macro que foi inserida dentro do bloco de declarao da
classe para ativao do mecanismo de classes friend. Na linha 5 utilizada uma macro
para informar para a biblioteca o tipo de dado do campo de chave primria utilizado na
classe. Nas linhas 6 at 12 so utilizadas macros para informar para a biblioteca que a
classe Documento deve ser mapeada para o banco de dados. Note que nestas linhas foi
necessrio utilizar diretivas de pr-processamento para informar macros diferentes para
os sistemas Ubuntu e Windows.
Nas linhas 15 at 28 demonstrada a implementao do mtodo de registro de metadados para classes mapeadas por esta biblioteca. Dentro desta funo, na linha 19
definida a tabela equivalente a classe, e nas linhas 21 at 26 so definidas as equivalncias
entre atributos e colunas.
Das trs bibliotecas utilizadas, esta a que possui o sistema de configurao mais
complexo. Como o aplicativo foi desenvolvido para ser utilizado nas plataformas Ubuntu
e Windows, foi necessrio utilizar, em certos pontos, macros de configurao diferentes
para os dois sistemas, como pode ser observado.

5.2 O Projeto Minhas Apostilas

1
2

53

// Macro que a t i v a mecanismo de c l a s s e s f r i e n d


QX_REGISTER_FRIEND_CLASS( E n t i d a d e s : : Documento )

3
4
5
6
7
8
9
10
11
12

// Macros e x t r a s d e f i n i d a s no a r q u i v o de d e f i n i o da c l a s s e
QX_REGISTER_PRIMARY_KEY( E n t i d a d e s : : Documento , q l o n g l o n g )
#i f
d e f i n e d (Q_OS_WIN32)
QX_REGISTER_COMPLEX_CLASS_NAME_HPP_EXPORT_DLL( E n t i d a d e s : : Documento , \
qx : : t r a i t : : no_base_class_defined , 0 , Documento )
#e l i f
d e f i n e d (Q_OS_LINUX)
QX_REGISTER_COMPLEX_CLASS_NAME_HPP( E n t i d a d e s : : Documento , \
qx : : t r a i t : : no_base_class_defined , 0 , Documento )
#e n d i f

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

// Reimplementao de mtodo de r e g i s t r o de metadados


namespace qx
{
template <> v o i d r e g i s t e r _ c l a s s ( QxClass<E n t i d a d e s : : Documento> &t )
{
t . setName ( " t_documento " ) ;
t . i d (& E n t i d a d e s : : Documento : : m_codigo , " c_codigo " ) ;
t . data (& E n t i d a d e s : : Documento : : m_nome, "c_nome" ) ;
t . data (& E n t i d a d e s : : Documento : : m_descricao , " c _ d e s c r i c a o " ) ;
t . data (& E n t i d a d e s : : Documento : : m_ultimaAlteracao ,
" c_ultimaalteracao ") ;
t . data (& E n t i d a d e s : : Documento : : m_versao , " c_versao " ) ;
t . data (& E n t i d a d e s : : Documento : : m_arquivo , " c_arquivo " ) ;
}
}

Algoritmo 23: Mapeamento da classe Documento com a biblioteca QxOrm

5.2 O Projeto Minhas Apostilas

5.2.2

54

A Classe IRepository

Para possibilitar que as operaes do aplicativo relacionadas com gerenciamento de dados


pudessem ser efetuadas com cada uma das bibliotecas ORM utilizadas, foi criada a classe
abstrata IRepository<T>, que define uma interface unificada de mtodos para gerenciamento de registros de objetos de uma classe qualquer no banco de dados. No trecho de
cdigo 24 demonstrada a declarao desta classe, onde so descritas as funes de cada
mtodo includo.
1
2
3
4
5
6

template <c l a s s T> c l a s s I R e p o s i t o r y


{
public :
// C o n s t r u t o r e d e s t r u t o r
I R e p o s i t o r y ( ) {}
v i r t u a l ~ I R e p o s i t o r y ( ) {}

// Retorna um t e x t o com a d e s c r i o do l t i m o e r r o o c o r r i d o .
QString l a s t E r r o r ( ) c o n s t ;
// C r i a um novo r e g i s t r o de um o b j e t o no banco de dados
v i r t u a l b o o l c r e a t e O b j e c t (T &o b j e c t ) ;
// A t u a l i z a o r e g i s t r o de um o b j e t o no banco de dados
v i r t u a l b o o l updateObject (T &o b j e c t ) ;
// D e l e t a o r e g i s t r o de um o b j e t o no banco de dados
v i r t u a l b o o l d e l e t e O b j e c t (T &o b j e c t ) ;
// S e l e c i o n a uma l i s t a de o b j e t o s do banco de dados
// que obedecem o s f i l t r o s i n f o r m a d o s .
v i r t u a l b o o l s e l e c t O b j e c t s ( QList<T> &l i s t , QMap<QString , QVariant>
filters );
// Retorna a q u a n t i d a d e de r e g i s t r o s de o b j e t o s no banco de dados
// que obedecem o s f i l t r o s i n f o r m a d o s .
v i r t u a l b o o l c o u n t O b j e c t s ( i n t &count , QMap<QString , QVariant> f i l t e r s ) ;
// P e s q u i s a um r e g i s t r o e s p e c f i c o a p a r t i r do i d informado
v i r t u a l b o o l g e t O b j e c t ( c o n s t QVariant &id , T &o b j e c t ) ;

8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24

};

Algoritmo 24: Definio da classe IRepository<T>


Todas as operaes de gerenciamento de objetos da classe Documento so feitas a
partir de implementaes da classe IRepository<Documento>. No programa foram definidas trs implementaes, sendo elas, a DocumentoRepositorioOrm4Qt (implementao
que utiliza a biblioteca ORM4Qt), a DocumentoRepositorioODB (implementao que
utiliza a biblioteca ODB) e DocumentoRepositorioQxOrm (implementao que utiliza a
biblioteca QxOrm).
Quando o programa Minhas Apostilas iniciado, apresentado uma lista com as
opes das trs bibliotecas ORM. De acordo com a opo escolhida, uma instncia da
implementao equivalente criada e utilizada ao longo da execuo do aplicativo. Outra

5.2 O Projeto Minhas Apostilas

55

aspecto importante a observar, que todas as implementaes ficam exibindo no console


os comandos SQL gerados pela biblioteca utilizando recursos especficos de cada uma.
As implementaes dos mtodos da interface de IRepository<Documento> para as
trs bibliotecas so bem parecidas devido a similaridade entre as API apresentadas por
elas para realizao de operaes no banco de dados. Sendo assim, estas implementaes
no sero comparadas.

Captulo 6
Concluso

O objetivo principal deste trabalho foi mostrar que a partir da utilizao dos novos recursos, sobretudo os de programao funcional, propostos pelas novas especificaes da
linguagem C++, possvel construir uma biblioteca de mapeamento objeto relacional
com uma interface de configurao mais amigvel para o desenvolvedor. Para provar
esta teoria foi desenvolvida a biblioteca ORM4Qt, uma biblioteca ORM voltada para
utilizao integrada ao framework Qt.
A biblioteca desenvolvida mostrou-se com um nvel de facilidade de uso mais alto,
sobretudo na parte de configurao do mapeamento, quando comparada com duas existentes no mercado, a ODB e a QxOrm. Um dos motivos para isso acontecer consiste
no mecanismo de reflexo desenvolvido especificamente para a biblioteca, que permite a
configurao do mapeamento e insero de metadados com uma interface bem parecida
com o mecanismo de anotaes presente nas linguagens JAVA e C#.
Apesar de apresentar uma interface de configurao mais simples, a biblioteca desenvolvida no pde ser comparada diretamente com outras em quesitos como o suporte
a mapeamento de mecanismos mais avanados da orientao a objetos (como herana e
polimorfismo, por exemplo). Isso se deve ao fato de o suporte a tais mecanismos no ter
sido desenvolvido por no fazer parte do escopo principal do trabalho.
Tambm no foi comparado o desempenho das bibliotecas em relao ao tempo de
resposta e utilizao de memria, devido tambm ao fato da diferena da quantidade de
mecanismos implementados entre as bibliotecas existentes e a desenvolvida. Porm, ao
utilizar o aplicativo Minhas Apostilas, que foi desenvolvido para fins de testes entre as
trs bibliotecas, a diferena de tempo de resposta imperceptvel ao usurio.
A biblioteca ORM4Qt apresenta potencial para se tornar uma biblioteca ORM to

6 Concluso

57

completa quanto as utilizadas para testes de comparao. Para que isso seja possvel
preciso ampliar o mecanismo de reflexo de forma a detectar a utilizao de herana nas
classes mapeadas e reconstruir toda a camada de armazenamento para suportar operaes
no banco de dados que envolvam mais de uma tabela, ao necessria para suportar o
mapeamento de composio e associao. Estas melhorias podem ser implementadas em
trabalhos futuros.
Outra sugesto de trabalho futuro consiste na utilizao do mecanismo de reflexo
criado, para implementao de mecanismos de serializao de objetos para arquivos XML
e JSON.

Referncias Bibliogrficas

[Barnes, 2007] Barnes, J. M. (2007). Object-relational mapping as a persistence mechanism for object-oriented applications.
[Bauer and King, 2005] Bauer, C. and King, G. (2005). Hibernate in Action, volume 1.
Manning Publications Co.
[Blanchette and Summerfield, 2006] Blanchette, J. and Summerfield, M. (2006). C++
GUI programming with Qt 4. OReilly Japan.
[Brokken and Kubat, 2014] Brokken, F. B. and Kubat, K. (2014). C++ annotations.
Citeseer.
[Bueno, 2002] Bueno, A. (2002). Apostila de programao orientada a objeto em c++.
[Clugston, 2004] Clugston, D. (2004). Member function pointers and the fastest possible
c++ delegates. Online Article.
[Gregoire, 2014] Gregoire, M. (2014). Professional C++, volume 3. WROX.
[Lhotka, 2009] Lhotka, R. (2009). Expert C# 2008 Business Objects, volume 1. Apress.
[Marty, 2014] Marty, L. (2014). Qxorm - c++ object relational mapping library. http:
//www.qxorm.com/doxygen/html/index.html.
[Nierstrasz, 1989] Nierstrasz, O. (1989). A survey of object-oriented concepts.
[PostgreSQL, 2014] PostgreSQL, T. G. D. G. (2014). PostgreSQL 9.3.4 Documentation.
[Synthesis, 2013] Synthesis, C. (2013). C++ Object Persistence with ODB.
[Thelin, 2007] Thelin, J. (2007). Foundations of Qt development, volume 7. Springer.
[Zhang, 2004] Zhang, X. (2004). A framework for object-relational mapping with an example in C++. PhD thesis, Concordia University.

Das könnte Ihnen auch gefallen