A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 15 Criado por Frederick H. Colclough, Colorado Technical University Polimorfismo e Funções.

Apresentações semelhantes


Apresentação em tema: "Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 15 Criado por Frederick H. Colclough, Colorado Technical University Polimorfismo e Funções."— Transcrição da apresentação:

1 Pearson Education Slide 1

2 Pearson Education Slide 2 Cap í tulo 15 Criado por Frederick H. Colclough, Colorado Technical University Polimorfismo e Funções Virtuais

3 Pearson Education Slide 3 Objetivos de Estudo Princípios das Funções Virtuais Ligação Tardia Implementando Funções Virtuais Quando usar uma Função Virtual Classes Abstratas e Funções Virtuais Puras Ponteiros e Funções Virtuais Compatibilidade de Tipo Estendida Downcasting and upcasting Como C++ implementa Funções Virtuais

4 Pearson Education Slide 4 Princípios de Funções Virtuais Polimorfismo Associação de muitos significados à uma função Funções virtuais fornecem essa capacidade Princípio fundamental da Programação Orientada a Objetos! Virtual Existe na essência porém não de fato Função virtual Pode ser usada antes de ser definida

5 Pearson Education Slide 5 Exemplo: Figuras Melhor ilustrado com exemplos: Classes para vários tipos de figuras Retângulos, círculos, ovais, etc. Cada figura é um objeto de uma classe diferente Retângulo: altura, largura, ponto central Círculo: ponto central e raio Todas derivam da classe-pai: Figura Necessita da Função: desenho() Diferentes instruções para cada figura

6 Pearson Education Slide 6 Exemplo 2: Figuras Cada classe necessita de uma função desenho() diferente Pode ser chamada desenho em cada classe, assim: Retêngulo r; Círculo c; r.desenho(); // Chama Retângulo da classe desenho c.desenho(); // Chama Círculo da classe desenho Nada de novo até aqui…

7 Pearson Education Slide 7 Exemplo Figuras : centro( ) Classe-pai Figura contém funções que se aplicam à todas as figuras: centro(): move a figura para o centro da tela Primeiro apaga para então redesenhar Então Figura::centro() usa a função desenho() para redesenhar Complicações! Qual função desenho()? De qual classe?

8 Pearson Education Slide 8 Exemplo Figuras : Nova Figura Considere um novo tipo de figura: Classe Triângulo derivada da classe Figura Função centro() herdada de Figura Funcionará para Triângulos? Ela usa desenho(), a qual é diferente para cada figura! Usará Figura::desenho() Não funciona para triângulos! Queremos que a função herdada centro () utilize a função Triângulo::desenho() NÃO a função Figura::desenho() Mas a classe triângulo nem mesmo estava ESCRITA quando Figura::centro() estava! Não se conhece Triângulo!

9 Pearson Education Slide 9 Exemplo Figuras : Virtual! Função virtual é a resposta Diz ao compilador: Não sei como a função será implementada Espere até que ela seja utilizada em um programa Então obtenha a implementação da instãncia do objeto Chamada de ligação tardia ou ligação dinâmica Funções virtuais implementam a ligação tardia

10 Pearson Education Slide 10 Funções virtuais: Outro Exemplo Um exemplo maior é melhor para demonstrar Programa de arquivo de registros para uma loja de peças de automóveis Controle das vendas Não conhecemos todas as vendas ainda 1 o somente vendas regulares ao varejo Mais tarde: descontos, maior e menor venda, etc. Dependem de outros fatores além do preço e dos impostos

11 Pearson Education Slide 11 Funções Virtuais : Auto-peças O programa precisa: Calcular as vendas brutas diárias Calcular a maior/menor venda do dia Talvez a média de vendas para o dia Tudo vem de faturas individuais Mas muitas funções para calcular faturas serão acrescentadas mais tarde! Quando diferentes tipos de vendas forem acrescentadas ! Então a função para cálculo da fatura será virtual

12 Pearson Education Slide 12 Definição da Classe Venda class Sale { public: Sale(); Sale(double thePrice); double getPrice() const; virtual double bill() const; double savings(const Sale& other) const; private: double price; };

13 Pearson Education Slide 13 Função-Membro economia(savings) e o operador < double Sale::savings(const Sale& other) const { return (bill() – other.bill()); } bool operator < (const Sale& first, const Sale& second) { return (first.bill() < second.bill()); } Observe que ambos usam a função-membro fatura(bill)!

14 Pearson Education Slide 14 Classe Venda Representa as vendas de itens simples sem nenhum desconto acrescentado ou modificado. Observe a palavra reservada virtual na na declaração da função-membro fatura Impacto: mais tarde, classes derivadas de Venda podem definir suas próprias versões da função fatura Outras funções-membros de Venda usarão a versão baseada nos objetos da classe derivada! Elas não usarão automaticamente a versão de Venda!

15 Pearson Education Slide 15 Definição da Classe Derivada VendaComDesconto class DiscountSale : public Sale { public: DiscountSale(); DiscountSale(double thePrice, double the Discount); double getDiscount() const; void setDiscount(double newDiscount); double bill() const; private: double discount; };

16 Pearson Education Slide 16 Implementação de VendaComDesconto de Fatura() double DiscountSale::bill() const { double fraction = discount/100; return (1 – fraction)*getPrice(); } Qualificador virtual não se repete na definição da função Automaticamente virtual na classe derivada Declaração (na interface) não requer a palavra- chave virtual (mas usa-se com freqüência)

17 Pearson Education Slide 17 Implementação de VendaComDesconto de Fatura() Função virtual na classe-base: Automaticamente virtual na classe derivada Declaração da classe derivada (na interface) Não requer a palavra-chave virtual Mas é adicionada com freqüência por motivos de legibilidade

18 Pearson Education Slide 18 Classe Derivada VendaComDesconto A função-membro fatura() de VendaComDesconto é implementada diferentemente do que em Venda Específica para descontos Funções-membros economia e < Usará essa definição de fatura() para todos os objetos da classe VendaComDesconto! Em vez da versão padrão definida na classe Venda!

19 Pearson Education Slide 19 Virtual: UAU! Lembre-se da classe Venda escrita muito tempo antes da classe derivada VendaComDesconto Os membros economia e < compilados antes, sequer tinham idéia de uma classe VendaComDesconto Mesmo em uma chamada como: VendaComDesconto d1, d2; d1.economia(d2); A chamada em economia() para a função fatura() sabe como usar a definição de fatura() dada para a classe VendaComDesconto Poderoso!

20 Pearson Education Slide 20 Virtual: Como? Para escrever programas em C++: Assuma que isso aconteça por mágica! Mas a explicação envove a Ligação Tardia Funções virtuais implementam ligação tardia Diz ao compilador para esperar até que a função seja usada no programa Decide qual definição usar baseado no objeto que chamou Princípio muito importante de OOP!

21 Pearson Education Slide 21 Sobrescrita (Overriding) Definição de função virtual modificada em uma classe derivada Dizemos que ela foi sobrescrita Parecido com redefinição Lembre-se: Funções-padrão Assim: Funções virtuais modificadas: sobrescritas Funções não-virtuais modificadas : redefinidas

22 Pearson Education Slide 22 Funções Virtuais : Porque não todas? Nós vimos vantagens claras para usarmos funções virtuais A maior desvantagem: elevado gasto de memória! Exige mais espaço de armazenamento Ligação tardia ocorre on the fly (enquanto o programa roda) então o programa roda mais lentamente Se não é necessário o uso de funções virtuais, não devem ser usadas

23 Pearson Education Slide 23 Funções Virtuais Puras A classe-base pode não ter definições significativas para alguns de seus membros! Lembre-se da Classe Figura Todas as figuras são objetos de classes derivadas Retângulo, círculos, triângulos, etc. A Classe Figura não tem idéia de como desenhar! Torne-a uma Função virtual pura: virtual void desenho() = 0;

24 Pearson Education Slide 24 Classes-Base Abstratas Funções virtuais não requerem definição Força todas as classes derivadas a definir sua própria versão Classe com uma ou mais funções virtuais puras é chamada de: classe-base abstrata Pode somente ser usada como classe-base Nenhum objeto pode ser criado a partir dela Uma vez que ela não tem definições completas de todos os seus membros!

25 Pearson Education Slide 25 Compatibilidade de Tipo Estendida Dado: Derivada é uma classe derivada de Base Objetos de tipo Derivada podem ser atribuídos a Objetos de tipo Base Mas o contrário NÃO é verdade! Considere o exemplo anterior: Uma VendaComDesconto é uma Venda, mas o oposto não é verdade

26 Pearson Education Slide 26 Exemplo de Compatibilidade de Tipo Estendida class Animal { public: string nome; virtual void imprime() const; }; class Cachorro : public Animal { public: string raca; virtual void imprime() const; };

27 Pearson Education Slide 27 Classes Animal e Cachorro Agora dadas as Declarações: Cachorro vCachorro; Animal vAnimal; Observe que as variáveis-membros nome e raca são públicas! Somente com propósito de exemplo!

28 Pearson Education Slide 28 Usando as Classes Animal e Cachorro Tudo que é um Cachorro é um Animal: vcachorro.nome = Rex; vcachorro.raca = Dinamarquês; vanimal = vcachorro; Isto é permitido Pode-se atribuir valores a um tipo pai, mas não o inverso Um animal não é um cachorro (não necessariamente)

29 Pearson Education Slide 29 Problema do Fatiamento (Slicing) O valor atribuído à vanimal perde seu campo raca! cout << vanimal.raca; Produz uma mensagem de ERRO! Chamado de Problema do Fatiamento Pode parecer apropriado Cachorro foi movido para a variável Animal, assim deverá ser tratado com um animal Então não tem propriedades de cachorro Assunto para um debate filosófico interessante

30 Pearson Education Slide 30 Resolvendo o Problema do Fatiamento Em C++, o Problema do fatiamento é um incômodo Ele ainda é um Dinamarquês chamado Rex Gostaríamos de nos referir à sua raça, ainda que o tratássemos como um Animal Utilizamos ponteiros para variáveis dinâmicas

31 Pearson Education Slide 31 Exemplo do Problema do Fatiamento Animal *panimal; Cachorro *pcachorro; pcachorro = new Cachorro; pcachorro->nome = Rex; pcachorro->raca = Dinamarquês; panimal = pcachorro; Não podemos acessar o campo raca do objeto apontado por panimal: cout raca;// ILEGAL!

32 Pearson Education Slide 32 Exemplo do Problema do Fatiamento Deve-se usar uma função-membro virtual: panimal->imprime(); Chama a função-membro imprime na classe Cachorro Porque ela é virtual C++ espera para ver qual objeto o ponteiro panimal está atualmente apontando antes de conectar a chamada

33 Pearson Education Slide 33 Destrutores Virtuais Lembre-se: destrutores precisam desalocar dados dinamicamente alocados Considere: Base *pBase = new Derivada; … delete pBase; Chamaria o destrutor da classe-base mesmo que apontasse para o objeto da classe derivada! Tornar o destrutor virtual resolve isso! Boa política para todos os destrutores serem virtuais

34 Pearson Education Slide 34 Casting Considere: Animal vanimal; Cachorro vcachorro; … vcachorro = static_cast (vanimal); //ILEGAL! Não se pode converter um animal em um cachorro, mas: vanimal = vcachorro;// Legal! vanimal = static_cast (vcachorro); // Também é legal! Upcasting é seguro Do tipo descendente para um tipo ancestral

35 Pearson Education Slide 35 Downcasting Downcasting é Perigoso! Casting de um tipo ancestral para um tipo descendente Assume que estamos acrescentando informações Pode ser feito com o dynamic_cast: Animal *panimal; panimal = new Cachorro; Cachorro *pcachorro = dynamic_cast (panimal); Legal, mas perigoso! Downcasting é raramente feito devido às armadilhas Deve-se controlar todas as informações que serão acrescrentadas Todas as funções-membros devem ser virtuais

36 Pearson Education Slide 36 Trabalho Secreto das Funções Virtuais Não é preciso saber como são implementadas Princípio da ocultação de informação Tabela de funções virtuais O compilador as cria Tem ponteiros para cada função-membro virtual Aponta para o local correto do código da função Objetos de classes semelhantes também têm ponteiros Apontando para a tabela de funções virtuais

37 Pearson Education Slide 37 Sumário 1 A ligação tardia atrasa a decisão de qual função-membro será chamada até a execução Em C++, funções virtuais usam a ligação tardia Funções virtuais puras não têm definição Classe com pelo menos uma é abstrata Nenhum objeto pode ser criado a partir de classes abstratas Usadas estritamente como base para outras classes derivadas

38 Pearson Education Slide 38 Sumário 2 Objetos de classes derivadas podem ser atribuídos a objetos de classes-base Membros das classes-base são perdidos: Problema do fatiamento Atribuições de ponteiros e objetos dinãmicos Permitem resolver o problema do fatiamento Torne todos os destrutores virtuais Boa prática de programação Garante a correta desalocação da memória


Carregar ppt "Pearson Education Slide 1. Pearson Education Slide 2 Cap í tulo 15 Criado por Frederick H. Colclough, Colorado Technical University Polimorfismo e Funções."

Apresentações semelhantes


Anúncios Google