Baixe o app para aproveitar ainda mais
Prévia do material em texto
Laboratório de Programação II Departamento de Ciência da Computação UFJF Aula de hoje • Tipos Abstratos de Dados (TADs) • Como implementar TADs em C++ – Classes Tipo Abstrato de Dado • Um tipo abstrato de dados (ou TAD) é um tipo de dados definido pelo programador que possui um conjunto de valores e uma coleção de operações bem definidas que podem ser realizadas sobre esses valores. Tipo Abstrato de Dado • A ideia de TAD é desvincular o tipo de dado de sua implementação. • Algumas vantagens desta desvinculação são: – Integridade dos dados – Invisibilidade (representação escondida e inacessível) – Proteção (o cliente manipula os objetos através das operações fornecidas - interface) – Facilidade de manutenção – Reutilização • Um TAD está desvinculado de sua implementação, ou seja, quando definimos um TAD estamos preocupados com o que ele faz e não como ele faz. Tipo Abstrato de Dado Tipo Abstrato de Dado • Em geral, para todos os TADs, temos os seguintes tipos de operações: – Criar e inicializar novas instâncias do TAD. – Acessar os dados contidos em um TAD sem modificar os mesmos. – Modificar os dados de uma instância do TAD. – Processar os dados. TAD TPonto2D • Vamos criar um TAD para representar um ponto no espaço bidimensional. • TPonto2D – Dados • Coordenadas X e Y – Operações • Criar um ponto com coordenadas (X,Y) • Acessar as coordenadas • Alterar as coordenadas • Calcular a distância até outro ponto • ... TAD TPonto2D • Para implementar o TAD em C++ iremos usar um recurso da linguagem chamado de classe. • A classe será responsável por representar os dados do TAD assim como as suas operações (interface). • Para garantir a desvinculação entre o tipo de dados e sua implementação, vamos criar arquivos diferentes para a definição do TAD e para o seu MI (Módulo de Implementação) • Antes, vamos ver como um programa pode fazer uso do TAD TPonto2D sem conhecer sua representação interna, através do que chamamos de PA (Programa Abstrato). Usando o TAD TPonto2D #include “TPonto2d.h” int main(){ TPonto2D *A = new TPonto2D(0.0, 0.0); TPonto2D *B = new TPonto2D(2.5, 3.5); A->altera(-1.0, -1.0); B->altera(2.0, 0.0); float xB = B->acessaX(); cout << “Coordenada X do ponto B: ” << xB << endl; float dist = A->calcDistancia(B); cout << “Distancia de A ate B: ” << dist << endl; delete A; delete B; } TAD TPonto2D • Para codificarmos o TAD, vamos precisar criar um arquivo .h para armazenar o TAD e um .cpp que conterá o MI do TAD: – TPonto2d.h (def. da classe, dados e operações) – TPonto2d.cpp (implementação das operações) • Através da diretiva #include, o conteúdo do arquivo .h é adicionado pelo pré-processador ao arquivo .cpp antes da compilação – O .h vem do inglês header (cabeçalho) – Erros de compilação “estranhos” no .cpp podem significar um erro de sintaxe no .h • Veremos agora como criar projetos com mais de um arquivo fonte • Para criar um projeto com esses arquivos no Code::Blocks, basta seguir os passos já conhecidos para criação de projetos: – Criar um novo projeto: File > New > Project... > Console application... Programas com vários arquivos fontes • No Code::Blocks: Programas com vários arquivos fontes • No Code::Blocks: – Estamos programando na linguagem C++, logo... Programas com vários arquivos fontes • No Code::Blocks: Programas com vários arquivos fontes Nome do projeto Pasta onde será salvo o projeto Não há necessidade de mexer, é automaticamente gerado • No Code::Blocks: – Finish para finalizar a criação do projeto Programas com vários arquivos fontes • No Code::Blocks: – Projeto criado corretamente • Code::Blocks já gera um main.cpp automaticamente Programas com vários arquivos fontes • Vamos agora criar arquivos adicionais! – Criar um novo arquivo (cabeçalho): – File > New > File... Programas com vários arquivos fontes • No Code::Blocks: – Escolha a opção C/C++ header e clique em Go: Programas com vários arquivos fontes • No Code::Blocks: Programas com vários arquivos fontes 19 Clique aqui para escolher o diretório • No Code::Blocks: Programas com vários arquivos fontes 20 Digite o nome do arquivo com a extensão... A janela já abre na própria pasta do projeto. Salve o novo arquivo nessa pasta. ... e clique em Salvar • No Code::Blocks: Programas com vários arquivos fontes 21 O caminho do arquivo e a definição do cabeçalho são gerados automaticamente Clique no All para marcar as duas opções (Debug e Release) e depois clique em Finish Caso esteja desmarcado, marcar “Add file to active project” • No Code::Blocks: – Digite o código contendo o TAD TPonto2D e salve- o: Programas com vários arquivos fontes • No Code::Blocks: – Criar um novo arquivo (fonte): File > New > File... Programas com vários arquivos fontes 23 • No Code::Blocks: – Escolha a opção C/C++ source e clique em Go: Programas com vários arquivos fontes 24 • No Code::Blocks: – Escolha a opção C++ e clique em Next: Programas com vários arquivos fontes • No Code::Blocks: Programas com vários arquivos fontes 26 Clique aqui para escolher a pasta • No Code::Blocks: Programas com vários arquivos fontes Digite o nome do arquivo com a extensão... A janela já abre na própria pasta do projeto. Salve o novo arquivo nessa pasta. ... e clique em Salvar • No Code::Blocks: Programas com vários arquivos fontes 28 O caminho do arquivo é gerado automaticamente Clique no All para marcar as duas opções (Debug e Release) e depois clique em Finish Caso esteja desmarcado, marcar “Add file to active project” – Digite no arquivo .cpp o MI do TAD TPonto2D – Salve o arquivo: Programas com vários arquivos fontes – Coloque o código do PA visto anteriormente no arquivo main.cpp e salve-o : Programas com vários arquivos fontes • Obs: o passo-a-passo anterior é para o caso em que os arquivos estão sendo criados. • Caso os arquivos já existam (arquivos de outro projeto, por exemplo), não é necessário criá-los novamente – Basta adicioná-los ao projeto usando uma das formas alternativas a seguir Programas com vários arquivos fontes • Forma Alternativa 1: – Com o botão direito do mouse, clique sobre o nome do projeto e depois na opção Add files... Programas com vários arquivos fontes • Forma Alternativa 1: – Escolha os arquivos que deseja incluir no projeto e clique em Abrir: • Suponha que queremos incluir dois arquivos chamados funcao.cpp e funcao.h Programas com vários arquivos fontes • Forma Alternativa 1: – Marque a opção Select All e clique em OK: Debug Release Programas com vários arquivos fontes • Forma Alternativa 2: – Com o botão direito do mouse, clique sobre o nome do projeto (no caso “TPonto2d”) e selecione Properties... Programas com vários arquivos fontes • Forma Alternativa 2: – Na aba Build targets, opção Build target files, marcar os arquivos que deseja incluir no projeto Programas com vários arquivos fontes Selecionar Build targets De volta ao TAD TPonto2D... • Vamos criar primeiro a classe que irá representar o TAD TPonto2D • Arquivo TPonto2d.h class TPonto2D { public: // ... private: float coordX; float coordY; }; Dados (ou atributos) do tipo abstrato de dado. Vamos definir as operações (ou métodos) aqui. TAD TPonto2D (TPonto2d.h) #ifndef TPONTO2D_H_INCLUDED #define TPONTO2D_H_INCLUDED class TPonto2D { public: TPonto2D(float x, float y); ~TPonto2D(); voidaltera(float x, float y); float acessaX(); float acessaY(); float calcDistancia(Ponto2D * p); private: float coordX; float coordY; }; #endif // TPONTO2D_H_INCLUDED Operações do TAD. Observe a sintaxe, como é parecida com a de protótipos de funções. TAD TPonto2D (TPonto2d.cpp) #include “TPonto2d.h" TPonto2D::TPonto2D(float x, float y) { cout << "Criando Ponto2D" << endl; coordX = x; coordY = y; } TPonto2D::~TPonto2D() { cout << "Destruindo Ponto2D" << endl; } TAD TPonto2D (TPonto2d.cpp) // continua void TPonto2D::altera(float x, float y) { cout << "Alterando as coordenadas X,Y" << endl; coordX = x; coordY = y; } float TPonto2D::acessaX(){ return coordX; } float TPonto2D::acessaY(){ return coordY; } TAD TPonto2D (TPonto2d.cpp) // continua float TPonto2D::calcDistancia(TPonto2D *p) { float dx, dy, d; dx = coordX - (p->coordX); dy = coordY - (p->coordY); d = sqrt(dx*dx + dy*dy); return d; } // fim Como funciona essa função que calcula a distância de um ponto a outro? TAD TPonto2D (Exemplo) TPonto2D *A = new TPonto2D(0,0); TPonto2D *B = new TPonto2D(2,2); float d = B->calcDistancia(A); delete A; delete B; float TPonto2D::calcDistancia(TPonto2D *p) { float dx, dy, d; dx = coordX - (p->coordX); dy = coordY - (p->coordY); d = sqrt(dx*dx + dy*dy); return d; } TAD TPonto2D (Exemplo) TPonto2D *A = new TPonto2D(0,0); TPonto2D *B = new TPonto2D(2,2); float d = B->calcDistancia(A); delete A; delete B; float TPonto2D::calcDistancia(TPonto2D *A) { float dx, dy, d; dx = coordX - (A->coordX); dy = coordY - (A->coordY); d = sqrt(dx*dx + dy*dy); return d; } Coordenadas do ponto A (0,0) Coordenadas do ponto B (2,2). TAD TPonto2D – Resumo TPonto2d.h TPonto2d.cpp main.cpp Classe que define os atributos e operações do TAD Implementação das operações do TAD. Programa “cliente” que usa o TAD. TAD TPonto2D – Resumo TPonto2d.h TPonto2d.cpp main.cpp Classe que define os atributos e operações do TAD Implementação das operações do TAD. Programa “cliente” que usa o TAD. PATAD MI TADs em C++ • Categorias de permissão: membros (atributos ou métodos) de uma classe podem ser: – public • Podem ser acessados em qualquer lugar. – private • Só podem ser acessados pelos membros da própria classe. • Em geral definimos os atributos (dados internos) de um TAD como private e os seus métodos (operações) como public. TADs em C++ • Se os atributos do TAD são private (ou seja, eles são de certa forma protegidos), como então um programa que usa o TAD pode acessar o seu conteúdo? • Como mudar o seu conteúdo? • Basta definir operações especiais para isso. • No exemplo usamos: – acessaX() – acessaY() – altera(float novo_x, float novo_y); TADs em C++ • Os nomes dos métodos (operações) são definidos pelo programador. • Em geral, os métodos que acessam e alteram o conteúdo de dados privados do TAD são nomeados seguindo o padrão: void setAtributo(TipoDeDado novoValor); TipoDeDado getAtributo(); TADs em C++ • Construtor: todo TAD precisa definir um construtor. Sempre que um objeto do TAD for criado, o código do construtor é chamado. TPonto2D *A = new TPonto2D(0,0); TPonto2D *B = new TPonto2D(2,2); Chamada ao construtor do TAD. Obs: colocamos esse código só para ficar claro quando o construtor está sendo chamado. Na prática não usamos isso. TADs em C++ • Destrutor: um TAD sempre tem um destrutor. Nem sempre precisa ter um código associado. Em geral o destrutor é usado para liberar memória ou realizar alguma tarefa antes de destruir o objeto. delete A; Chamada ao destrutor do TAD. TADs em C++ • Destrutor – Nesse exemplo o destrutor não precisa fazer nada, pois o TAD não alocou nenhuma memória de forma dinâmica. – Veremos adiante um exemplo em que o destrutor precisa desalocar memória alocada dinamicamente pelo TAD. delete A; TADs em C++ • Destrutor – Se o destrutor não faz nada, podemos omitir a sua definição, pois a linguagem C++ cria um automaticamente. – Entretanto se existir memória a ser desalocada, ele precisa ser definido e implementado corretamente. TAD TCirculo • Vamos criar um tipo abstrato de dados para representar um círculo. • TCirculo – Dados • Raio • Centro – Operações • Cria um círculo com raio r e cujo centro C possui as coordenadas (cx,cy) • Get/Set para raio e centro • Verifica se um ponto P está dentro ou fora • Calcula área • Libera (destrói) um círculo TAD TCirculo (TCirculo.h) class TCirculo { public: TCirculo(float r, float cx, float cy); // construtor ~TCirculo(); // destrutor float getRaio(); TPonto2D *getCentro(); void setRaio(float novoRaio); void setCentro(float cx, float cy); bool verifica (TPonto2D *p); float calcArea(); private: float raio; TPonto2D *centro; }; TAD TCirculo (TCirculo.cpp) TCirculo::TCirculo(float r, float cx, float cy) { cout << "Criando Circulo" << endl; raio = r; centro = new TPonto2D(cx,cy); } TCirculo::~TCirculo() { cout << "Destruindo Circulo" << endl; delete centro; } // continua Se o construtor alocou memória de forma dinâmica, o destrutor precisa liberar a mesma. TAD TCirculo (TCirculo.cpp) float TCirculo::getRaio(){ return raio; } TPonto2D* TCirculo::getCentro(){ return centro; } void TCirculo::setRaio(float novoRaio){ raio = novoRaio; } void TCirculo::setCentro(float cx, float cy){ centro->setX(cx); centro->setY(cy); } // continua (exercícios!) Exercícios 1. Implemente as operações calcArea() e verifica() do TAD TCirculo apresentado no exemplo anterior. Dica: use o projeto que já está disponível na página do curso: Projetos Codeblocks Exercícios 2. Implemente o TAD TRetangulo. – Dados • Pontos V1 e V2 (ver figura) – Operações • Cria retângulo dado as coordenadas (X,Y) de V1 e V2 • Libera retângulo • Calcula área • Verifica se o ponto P está dentro V1 V2 Exercícios 3. Implemente o TAD TData. – Dados • Ano, mês e dia. – Operações • Cria/Libera • Get/Set´s para ano, mês e dia. • Verifica se uma data é válida. • Imprime no formato DIA/MES/ANO • Verifica se é ano bissexto Fazer Y=ano Se ano modulo 100 é 0 então Y=ano/100 Se Y modulo 4 é 0 então bissexto Senão não_bissexto
Compartilhar