Programação Orientada aos Objectos Paulo Marques Departamento de Eng. Informática Universidade de Coimbra Out/2005 Core C++: Uma abordagem.

Slides:



Advertisements
Apresentações semelhantes
Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 10 Criado por Frederick H. Colclough, Colorado Technical University Ponteiros e Vetores.
Advertisements

Curso de aprofundamento na linguagem C
Programação Orientada a Objetos*
Paulo Marques Hernâni Pedroso
Introdução aos Sistemas Distribuídos
PHPOO Erick Souza. Conceitos de Orientação a Objetos Objeto é um conceito ou item(concreto ou abstrato). Software orientado a objetos Uma classe é uma.
Programação II Estruturas de Dados
Vamos abordar o exemplo
TC – DEI, 2005/2006.
Uma Introdução.
Programação Orientada aos Objectos Paulo Marques Departamento de Eng. Informática Universidade de Coimbra Set/2005 Uma Introdução Usando.
The new way! The old way... TC – DEI, 2005/2006.
Iniciação ao Java – Márcio F. Campos
Introdução a Programação
Wagner Santos C. de Jesus
Construção de Compiladores
Curso de Programação em C++
Ponteiros em Linguagem C
Introdução a Linguagem de Programação C
1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática.
Matrizes clássicas e vectores em C++
Programação Orientada para Objectos
1 Aula 7 Herança. 2003/2004 Programação Orientada para Objectos 2 Conceitos fundamentais: Herança Polimorfismo Ligação dinâmica.
2002/2003 Programação Orientada para Objectos 1 Aula 5 Memória livre e instâncias dinâmicas Criação de instâncias dinâmicas Destruição de instâncias dinâmicas.
2002/2003 Programação Orientada para Objectos 1 Aula 14 Tratamento de erros Origens dos erros Instruções usuais Papeis do humano Protecção contra: erros.
A linguagem C#.
Tipos Agregados Homogêneos e Listas
Revisão /*======================================================*/
Conceitos básicos de orientação a objetos
Objectos: Introdução O objecto ou classe é o conceito base de uma linguagem de programação por objectos como o C++. Tal como acontecia com as estruturas,
Informática e Computação Estrutura de Repetição aula 13
Exercício 1 Faça um programa que receba como entrada o nome e o salário de um funcionário de uma empresa e que calcule o novo valor do salário do.
Aula 07.
Aula 09.
Como escrever um Documento de Projecto para Redes Informáticas
TIC 10º ano Construir Bases de Dados
Construção de Algoritmos AULA 03
Linguagem de Programação II
Aula 3 CoL, atividade Polimorfismo (late binding) Modificador final Modificador abstract Interfaces Herança múltipla Atribuição, Construtores, Destrutores,
Introdução à Programação Orientada a Objetos com Java
Curso de C/C++ Aula 9 Instrutor: Luiz Felipe Sotero
Linguagem de Programação JAVA
Programação em C++ Compiladores
Procedural vs. OO (Figuras Geométricas: Área do triângulo)
Programação orientada a objectos em C++
Prof. Silvestri – todos os direitos reservados SISTEMAS DISTRIBUIDOS Aula 5 Eduardo Silvestri
2002/2003 Programação Orientada para Objectos 1 Aula 6 Classes que reservam recursos externos Problemas comuns Construtores e destrutores Construção por.
Wagner Santos C. de Jesus
3. Introdução à Linguagem C
Aula prática 14 Orientação a Objetos – C++ Parte 2
Informática e Computação Estrutura de Repetição aula 12
Linguagem de Programação C#
Regras de escopo Escopo: trecho de codificação no qual o identificador possui significado Escopo de função: identificador válido dentro do trecho de uma.
Linguagens de Programação
Linguagem de Programação II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
William Ivanski Curso de Programação C#. Sumário  Exercícios para Fixação  Utilizando uma IDE  Elementos da Linguagem C#  Valores  Variáveis  Tipos.
Tipos de dados inteiro caracter real logico
Linguagem C.
Copyright 1998, Departamento de Informática da UFPE. Todos os direitos reservados sob a legislação em vigor. Variáveis e métodos estáticos, Passagem de.
Sistemas Operativos Paulo Marques Departamento de Eng. Informática Universidade de Coimbra 2006/2007 Breve Introdução à Linguagem C.
Algoritmos e Programação MC102 Prof. Paulo Miranda IC-UNICAMP Aula 15 Ponteiros.
Introdução ao C++ para programadores OO Instrutores: Francisco Carvalho, João Paulo do Monte, Renato Viana Ferreira {fcfl, jpsml,
BCC221 Programação Orientada a Objetos Prof. Marco Antonio M. Carvalho 2014/2.
Paradigmas de Linguagens de Programação BNF e Interpretador da Linguagem Orientada a Objetos Augusto Sampaio e Paulo Borba Gustavo Pinto Marcelo Queiroz.
Tipos de dados básicos em C++ –Formato geral para declaração de variáveis: ; = ;,,... ; =, = ; –O elemento da declaração indica o tipo de dado usado para.
Array e ArrayList LPOO – 01/09/14.
Programação Orientada a Objetos para Redes de Computadores Prof. Miguel Elias Mitre Campista POO para Redes de Computadores.
Tipos Compostos Heterogêneos e Tipos Abstratos de Dados
PROGRAMAÇÃO ORIENTADA A OBJETOS EM C++ PAE: Pedro Shiguihara Professor: Dilvan Moreira.
Polimorfismo e suas aplicações em C++.
Transcrição da apresentação:

Programação Orientada aos Objectos Paulo Marques Departamento de Eng. Informática Universidade de Coimbra Out/2005 Core C++: Uma abordagem tutorial

2 Sobre o que é que vamos falar? Estruturas básicas em C++ Criação Dinâmica de Objectos Construção e Destruição de Objectos Herança, Polimorfismo e Destrutores Virtuais Redefinição de Métodos Redefinição de Operadores Construtor Cópia e Operador Atribuição Gestão de Erros: Excepções Esta sessão continua o trabalho desenvolvido na primeira formação POO: Uma Introdução Usando C++

3 Tipos de Dados Básicos O tamanho de cada tipo de dados varia de plataforma para plataforma. Alguns tipos não estão especificados como sendo com ou sem sinal

4 Controlo de Fluxo (1)

5 Controlo de Fluxo (2)

6 Aspecto de um programa completo // Importa biblioteca e passa a usar o espaço de nomes standard #include using namespace std; // Programa principal int main() { // Declara uma tabela de inteiros de tamanho variável vector myTable; // Adiciona-lhe 10 números for (unsigned i=0; i<10; i++) myTable.push_back(i); // Imprime o seu conteúdo for (unsigned i=0; i<myTable.size(); i++) cout << myTable[i] << endl; return 0; } Inclusão de bibliotecas Uso da biblioteca standard STL: Biblioteca de estruturas de dados e algoritmos! Envio para o ecrã

7 A classe Pessoa da última sessão class Pessoa { private: string _nome; int _idade; public: Pessoa(string nome, int idade); void imprime(); }; Pessoa::Pessoa(string nome, int idade) { _nome = nome; _idade = idade; } void Pessoa::imprime() { cout << "[" << _nome << "/" << _idade << "]" << endl; } Pessoa.cpp Pessoa.h

8 Construtores, Destrutores e Alcance Ao criar-se um objecto directamente, este é criado no stack da aplicação. Trata-se de uma variável automática. O alcance da variável está limitado à função onde foi definido. O destrutor de uma classe é um método especial que é invocado sempre que um objecto deixa de existir. É responsável por limpar todos os recursos associados a esse objecto (e.g. memória, handlers gráficos). void f() { Pessoa cliente("Carlos Manuel", 30); //... cliente.imprime(); } Criação do objecto no stack (construtor chamado) Destruição automática do objecto (destrutor chamado)

9 Declaração do Destrutor É semelhante ao Construtor, mas colocando um ~ antes do nome da classe. Não leva parâmetros e não retorna nada Nunca é chamado explicitamente class Pessoa {... public: ~Pessoa(); }; Pessoa::~Pessoa() { // Limpa eventuais recursos associados à pessoa //... } Pessoa.cpp Pessoa.h

10 Alocação Dinâmica de Memória Muitas vezes é necessário ter variáveis com um alcance (scope) superior a um método Usa-se alocação dinâmica de memória. Para alocar dinamicamente um objecto, utiliza-se o operador new Retorna um ponteiro para um novo objecto do tipo pedido. O construtor do objecto é sempre invocado Não existe garbage collection, a memória tem de ser explicitamente libertada usando o operador delete! Caso tenha sido criado um array de objectos, é necessário usar o operador delete[]. O destrutor é invocado automaticamente ao usar este operador. Pessoa* cliente = new Pessoa("Carlos Manuel", 30); delete cliente;

11 Classe Conjunto (Multi-conjunto) Consideremos uma classe que representa um multi-conjunto de números inteiros. Pode-se adicionar números e verificar a sua presença no conjunto

12 A sua implementação Inicialmente tem tamanho para um elemento (os elementos são guardados no heap!) No final garante que todos os elementos são apagados!

13 A sua implementação (2) O conjunto cresce automaticamente sempre que não existe mais espaço!

14 A sua implementação (3)

15 Pequeno programa de teste

16 Executando...

17 Qual é a grande limitação desta classe? (Bem, uma das grandes limitações...) Apenas permite lidar com inteiros. Mas, porque não armazenar qualquer tipo de objectos??

18 Programação utilizando genéricos (templates) Permite criar uma família de funções, parametrizadas por um tipo de dados abstracto. Meta-programação Existe há anos em C++: a STL é baseada neles Adição recente em Java (J2SE 5.0) e.NET (2.0) Conjunto c; c.adiciona(10); c.adiciona(20); Conjunto clientes; Pessoa p(João Carlos, 20); clientes.adiciona(p);

19 Qual o aspecto da implementação dos métodos? Têm de incluir a definição do template... (Incluído o construtor e destrutor!)

20 MonoConjunto Imaginemos que queremos criar uma nova classe, derivada de Conjunto, que permite apenas ocorrências únicas dos seus elementos. Tem de ser modificado para garantir que o elemento ainda não existe.

21 MonoConjunto::adiciona() Mas, qual é o problema com o seguinte código? Nota: Conjunto ::adiciona(valor) chama explicitamente o método adiciona da classe Conjunto. I.e. da classe acima!

22 MonoConjunto::adiciona() Mas, qual é o problema com o seguinte código? Elementos privados de Conjunto!

23 Níveis de acesso em C++ private: Todos os elementos declarados como private apenas são acessíveis à classe em questão. Nota: também são acessíveis a elementos friend, falaremos disto mais tarde. protected: Todos os elementos declarados como protected são acessíveis à classe em questão e às classes derivadas desta. Usar com muito cuidado pois viola parcialmente o encapsulamento. Em classes pensadas para serem herdadas, considerar quais são os elementos que eventualmente serão necessários serem acedidos por outras classes/funções. public: Elementos declarados como public são acessíveis a todas as classes e funções do programa.

24 Nova versão de Conjunto Admitindo que o programador pensou explicitamente Conjunto para criar outras classes, é provável que definisse essa classe da seguinte forma:

25 virtual? Garante que case se usem ponteiros para aceder aos membros desta classe (ou derivadas) ou caso os mesmos sejam passados como parâmetros, são chamados os métodos correctos! Porquê?

26 virtual (2) Garante que case se usem ponteiros para aceder aos membros desta classe (ou derivadas) ou caso os mesmos sejam passados como parâmetros, são chamados os métodos correctos! Usando o exemplo de Pessoa, Empregado e Patrao da última sessão... Chama Empregado::imprime() ou Patrao::imprime() consoante o tipo real do objecto na tabela.

27 Porquê o destrutor virtual? Qual o resultado da execução??

28 Porquê o destrutor virtual? (2) O destrutor de Empregado nunca é chamado. MEMORY LEAK!!! O sistema não sabe qual o verdadeiro tipo associado ao objecto apontado por p

29 Com um destrutor virtual... Garante que os destrutores são sempre chamados correctamente OK!

30 REGRAS A SEGUIR – Classes Para Herança Devem sempre definir um destrutor virtual Mesmo nos casos em que não é necessário realizar nenhuma limpeza específica no objecto. Normalmente, a limpeza refere-se a objectos alocados dinâmicamente ou a recursos não automáticos (e.g. handlers gráficos, semáforos, etc.) Todos os métodos pensados para serem herdados, sendo modificados em classes derivadas, têm de ser virtual Todos os campos ou métodos a que eventualmente seja necessário aceder em classes derivadas devem ser protected Utilizar com cuidado! É preferível ter métodos protected do que variáveis protected: mantêm um maior encapsulamento

31 Conjunto Revisitado

32 MonoConjunto Revisitado Nota: uma vez declarados como virtual na classe base não deixam de ser virtual nas classes derivadas. No entanto, é mais elegante torná-lo explícito.

33 Implementação de MonoConjunto Não é necessária nenhuma inicialização nem limpeza explícita Afinal não é preciso aceder explicitamente às estruturas de dados (Óptimo!)

34 Nota sobre construtores e destrutores Os construtores e destrutores são sempre invocados, quer tal seja feito explicitamente na lista de inicialização, quer não. Um Empregado tem de ter todos os campos de Pessoa. Logo, antes de criar Pessoa, é necessário criar completamente Empregado. A lista de inicialização permite algum controlo sobre a construção dos objectos acima. Os objectos acima são sempre completamente construídos antes de se entrar no corpo do construtor (i.e. {... } ) A destruição é feita pela ordem inversa da construção { Empregado p; }

35 Nota sobre construtores e destrutores (2) À partida, todas as classes possuem um construtor por omissão, mesmo que o programador não o declare. Isto é, um construtor sem parâmetros. Por vezes é útil não deixar os objectos serem construídos dessa forma (E.g. Pattern Factory ou classes internas) É possível desligar explicitamente o construtor por omissão Caso se declare um construtor com parâmetros, o construtor por omissão é automaticamente desligado. Caso seja necessário, o programador tem de o definir explicitamente.

36 Redefinição de Operadores O C++ permite a redefinição de operadores Redefinir um operador é semelhante a implementar um método Seria interessante poder escrever este código!

37 Conjunto Revisitado

38 Operadores como métodos conversão

39 Implementação

40 Execução

41 Operadores Redefiniveis em C++ Atenção: a redefinição de operadores é algo que implica conhecer bastantes regras e é potencialmente perigoso Certos operadores são utilizados automaticamente em certas circunstâncias. Ao serem redefinidos, pode levar a problemas subtis. Por outro lado, muitas vezes é essencial redefini-los. A sintaxe é relativamente uniforme mas alguns operadores são especiais. Existem operadores que devem ser redefinidos conjuntamente (e.g. == e !=,, >=) +-*/%^&|~ !,=<><=>=++-- <<>>==!=&&||+=-=/= %=^=&=|=*=<<=>>=[]() ->->*newnew[]deletedelete[]

42 ostream Como enviar um conjunto para o ecrã? Basta uma redefinição global... Notas:

43 friends No caso anterior, Conjunto fornecia todos os métodos necessários para implementar o operador <<. Mas, o que é que acontece com Pessoa? class Pessoa { protected: string _nome; int _idade; public: Pessoa(string nome, int idade); virtual ~Pessoa(); }; Se tentarmos escrever a função que implementa o operador <<(ostream&, Pessoa& p), este não tem acesso nem a _nome nem a _idade!

44 friends Ao declarar uma outra classe ou função como friend, dá-se acesso a todos os campos privados da mesma! Para declarar uma outra classe com friend: friend class X; class Pessoa { protected: string _nome; int _idade; public: Pessoa(string nome, int idade); virtual ~Pessoa(); friend ostream& operator<<(ostream& os, Pessoa& p); };

45 friends em acção class Pessoa { protected: string _nome; int _idade; public: Pessoa(string nome, int idade); virtual ~Pessoa(); friend ostream& operator<<(ostream& os, Pessoa& p); };

46 Qual o resultado da execução deste código?

47

48 O problema das cópias Sempre que é necessário copiar um objecto, por omissão, a cópia é realizada elemento a elemento da classe. Isto é problemático no caso de classes que utilizem ponteiros e usem criação dinâmica de objectos! 3 4 _nElementos _capacidade _conjunto conjA 3 4 _nElementos _capacidade _conjunto conjB

49 Problema das cópias Quando se acrescenta um elemento ao segundo conjunto, na verdade, também se está a manipular a informação do primeiro. Quando ambos os objectos são destruídos, ambos vão tentar libertar a memória. Daí o Segmentation Fault!!! 3 4 _nElementos _capacidade _conjunto conjA 3 4 _nElementos _capacidade _conjunto conjB Não se pode apagar a mesma memória duas vezes!

50 Construtor de Cópia As seguintes operações correspondem à invocação do Construtor de Cópia da classe: O construtor de cópia tem como parâmetros uma referência constante para um objecto do mesmo tipo da classe. E.g. Conjunto(const Conjunto & outro) Também é chamado sempre que um objecto é passado por valor para dentro de uma função e, em certas circunstâncias, quando é retornado de uma função.

51 Operador de Atribuição O operador de atribuição (=) é chamado sempre que é necessário substituir um objecto já existente por um novo O destrutor do existente não é invocado!

52 Definição do Construtor de Cópia

53 Definição do operador de atribuição

54 Cópia de Objectos, Pontos Importantes Por omissão, todas as classes possuem um construtor de cópia e um operador de atribuição Tal como no caso do construtor por omissão, também é possível desligá-los, tornando-os privados. Sempre que é necessário criar um novo objecto a partir de outro, é chamado o construtor de cópia. Sempre que é necessário copiar um objecto para outro já existente, é invocado o operador atribuição. Em ambos os casos, o compilador gera código para que, recursivamente, copia as variáveis membro existentes usando construtores-cópia/operadores atribuição. Em geral, quando os objectos são criados dinamicamente dentro de uma classe, é necessário redefinir o construtor cópia e o operador de atribuição. SEMPRE QUE SE REDEFINE O OPERADOR CÓPIA DEVE REDEFINIR-SE O OPERADOR ATRIBUIÇÃO E VICE-VERSA Não o fazer provavelmente indica que se passa algo de muito errado!

55 O resultado da execução...

56 Excepções Tal como na maioria das linguagens modernas, o C++ encoraja a utilização de excepções para gestão de erros Ao contrário da maioria das outras linguagens, uma excepção pode ser qualquer coisa (um inteiro, um objecto, uma referência, um ponteiro, etc.) Embora seja possível declarar as excepções que um método pode lançar, não há obrigatoriedade de as apanhar. Da mesma forma, um método pode lançar excepções que não declara.

57 MonoConjunto revisitado Classe base recomendada para erros nas aplicações, devido ao programador! Aqui acontece a excepção e o programa é abortado!

58 O resultado (espectável ou não...)

59 Salto para o handler correspondente

60 Qual o aspecto do código?

61 Definir uma nova excepção (parametrizada )

62 As novas definições

63 Ainda resultando em... As excepções são um tópico complexo e abrangente em C++. É importante consultar uma referência antes das começar a utilizar! Isto constitui apenas uma brevíssima introdução ao tópico!

64 Antes de terminarmos Objecto criado no stack 2. É criada uma nova cópia no stack (passagem por cópia) 3. O objecto é copiado para o seu destino final 4 4. A cópia do stack local do stack é destruída Se os objectos forem grandes, isto é terrivelmente ineficiente!

65 A solução Passar os objectos sempre por const&, caso os mesmos não sejam modificados e seja necessário algo que valha pelo objecto inicial!

66 » C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg. « Bjarne Stroustrup » If you think C++ is not overly complicated, just what is a protected abstract virtual base pure virtual private destructor and when was the last time you needed one? « Tom Cargill Próxima Sessão: STL = Standard Template Library

67 Para saber mais... C++ How to Program, 4th Edition by Harvey M. Deitel, Paul J. Deitel Prentice Hall, Aug Uma introdução leve ao C++ C++ Primer, 4th Edition by Stanley B. Lippman et. al. Addison-Wesley Professional, Feb Para aprender ao pormenor tudo o que há a saber sobre C++

68 YOU ARE FREE TO USE THIS MATERIAL FOR YOUR PERSONAL LERNING OR REFERENCE, DISTRIBUTE IT AMONG COLLEGUES OR EVEN USE IT FOR TEACHING CLASSES. YOU MAY EVEN MODIFY IT, INCLUDING MORE INFORMATION OR CORRECTING STANDING ERRORS. THIS RIGHT IS GIVEN TO YOU AS LONG AS YOU KEEP THIS NOTICE AND GIVE PROPER CREDIT TO THE AUTHOR. YOU CANNOT REMOVE THE REFERENCES TO THE AUTHOR OR TO THE INFORMATICS ENGINEERING DEPARTMENT OF THE UNIVERSITY OF COIMBRA. (c) 2005 – Paulo Marques,