Técnicas Avançadas de Programação
Embed Size (px)
description
Transcript of Técnicas Avançadas de Programação
-
Tcnicas Avanadas de Programao - Apontamentos -
Francisco Morgado
-
ProgramaI- Introduo s Tcnicas de P. O. O.O que a programao orientada por objectosPerspectiva tradicional versus orientada aos objectosConceitos bsicosConceito de generecidade e polimorfismoII- ClassesConstrutor e destructorRelao entre classes estruturas e uniesFunes in-lineAtribuio, passagem e devoluo de objectosFunes friendIII- Vectores, Ponteiros e RefernciasVectores de objectosPonteiros para objectos e thisAlocao dinmica - new e deleteAtribuio, passagem e devoluo de referncias para objectosIV- Overloading de Funes e OperadoresOverloading de construtoresOverloading de operadoresUtilizao de funes friendV- HeranaControle do acesso classe baseMembros protegidos - protectedConstrutores, destructores e heranaHerana mltiplaClasses bases virtuaisVI- Funes VirtuaisPonteiros para classes derivadasUtilizao de funes virtuaisFunes virtuais puras - classes abstractasPolimorfismoiProgramaii
-
ProgramaVII- Sistema de Entrada/SadaEntrada/sada formatadaLeitura e escrita de objectosEntrada/sada binriaAcesso aleatrioVIII-Generecidade e ExcepesFunes e classes genricas - templatesExcepes - exception handlingMtodos estticosFunes de converso entre tiposIX- Regras Prticas de P. O. O.Criao de uma interface de objectosInterface de uma aplicao MDICriao de um modelo de construo e manipulao de objectosTeach Yourself - C++ Second EditionHerbert SchildtOsborne/Mc Graw-Hill - 1994
C++ The Complete Reference Second Edition - A Compreensive Desktop ResourceHerbert SchildtOsborne/Mc Graw-Hill - 1994
Grafics Programming in Turbo C++Ben EzzelAddison/Wesley - 1990
Programao Orientada para ObjectosBrad J. CoxAddison/Wesley - 1986
C ++Bruce EckelOsborne/McGraw-HilliiiBibliografiaiv
-
BibliografiaC AvanadoRuben Romano Borges BarbosaGraficria - 1994
The C Programming LanguageKernighan & RitchiePrentice-Hall - 1988Cota: 03-05-03
Top Speed CL. John RibarMcGraw-Hill
A Book on CAl Kelley & Ira PohlBenjamin-CummingsCota: 03-05-15Todas as linguagens de programao orientadas por objectos partilham os seguintes trs conceitos:vO que a Programao Orientada por Objectos1Introduo s Tcnicas de P. O. O.ENCAPSULAMENTOPrivadoProtegidoPblicoEmbalagem de estado (propriedades) e comportamento (mtodos) dos objectos;Estado apenas acessvel atravs de operaes invocadas por mensagens;Interface externa do objecto separada da implementao.POLIMORFISMOUma InterfaceMltiplasImplementaesDefinio de uma interface para actividades relacionadas;Criao de uma classe com comportamento genrico;Classes derivadas com comportamento especfico.HERANAHerana das propriedades e comportamento protegidos e pblicos das classes derivadas;Todos herdamos caractersticas e comportamentos dos nossos pais.
-
Perspectiva Tradicional /Orientada aos ObjectosPerspectiva tradicional : programao orientada por funes
Perspectiva orientada por objectos2Exemplo: Jogo - Soluo Tradicional3Introduo s Tcnicas de P. O. O.Variveis GlobaisF1F2F3F4 F5Estado 1Mtodos 1Estado 2Mtodos 2Estado 3Mtodos 3Estado 4Mtodos 4Estado 5Mtodos 5Estado 6Mtodos 6Identificar as funesIdentificar as relaes entre as funesIdentificar as caractersticas das funesIntroduo s Tcnicas de P. O. O.
-
Exemplo: Jogo - Soluo Orientada por ObjectosRaquete
Jogo
Tijolo
4Estruturao do Problema5Introduo s Tcnicas de P. O. O.Introduo s Tcnicas de P. O. O.Identificar os objectosIdentificar as relaes entre os objectosIdentificar as caractersticas dos objectosParede
Bola
A prespectiva tradicional decide primeiro quais os mtodos (funes) necessrios, sendo os dados encaixados depois.A prespectiva orientada por objectos comea por decidir quais as entidades (objectos) a manipular e o estado (propriedades) que as caracteriza.JogobolaraqueteladosparedeBolaposiodimetrodirecovelocidadeRaquete
posiolarguraalturaParede
tijolos
Tijolo
posiolarguraalturaDe seguida completam-se os objectos com os mtodos necessrios. Exemplo: bola.EstadoPosioDimetroDirecoVelocidadeComportamentoPosio?MoverFazer ricocheteBateu num obstculo?
-
Conceitos BsicosA recepo de uma mensagem invoca um dado mtodo.Os objectos interagem exclusivamente atravs de mensagens.Exemplo:3+4
A diferena relativamente perspectiva tradicional que quem controla a resposta mensagem o receptor (3) e no o + (que selector e no operador).A mesma mensagem enviada para objectos diferentes origina normalmente reaces (mtodos invocados) diferentes.
Exemplo:a + 36Conceitos Bsicos7Introduo s Tcnicas de P. O. O.Introduo s Tcnicas de P. O. O.Objectos = dados (atributos) + operaes(mtodos)Classe - Descrio de objectos com caractersticas comunsInstncia - Objecto descrito por uma classe. As instncias duma classe tm todas operaes e estrutura de dados comuns, mas valores de dados prpriosAbstrao - Descrio formal do comportamento de uma dada entidade. Uma classe concretiza uma dada abstrao com uma implementao especfica das operaesEncapsulamento - Os dados de um objecto s podem ser acedidos pelos seus mtodosMensagem = selector + argumentosSelector - Especifica o mtodo a invocar no objecto receptorReceptor - Objecto que recebe uma mensagemreceptorselectorargumentointeiromatrizstring?
-
Definico de Objecto (segundo vrios autores)7.17.2Introduo s Tcnicas de P. O. O.Um objecto pode ser definido como uma abstraco de software que modela todos os aspectos relevantes de uma nica entidade conceptual ou tangvel, que pertena ao domnio da soluo [Donald Firesmith];Um objecto uma coisa, criada como uma instncia de um tipo de objectos. Cada objecto tem uma identidade nica distinta e independente de quaisquer das caractersticas. Cada objecto tem uma ou mais operaes (http://www.omg.org);Algo ao qual se pode fazer qualquer coisa; tem estado, comportamento e identidade [Grady Booch];Objectos so entidades reais ou conceptuais que podem ser encontradas no mundo que nos rodeia [E. V. Berard]; Uma abstraco de qualquer coisa no domnio de um problema, reflectindo a capacidade do sistema de manter informao sobre ele e de interagir com ele; um encapsulamente de valores de atributos e dos seus servios exclusivos[Peter Coad and Edward Yourdon].Um objecto um conceito, abstraco ou coisa com fronteiras bem definidas e com significado para o problema em questo; promove a reutilizao e funciona como uma base concreta para a respectiva implementao em software [J. Rumbaugh].Um objecto uma abstraco de um conjunto de coisas do mundo real de tal forma que todos os elementos do conjunto (instncias) tm as mesmas caractersticas e respeitam as mesmas regras e polticas[S. Shlaer and Neil Lang].
-
ObjectosA classe descreve a estrutura comum a vrios objectos, onde cada instncia da classe tem o seu prprio estadoA classe especificada pelo programador, definindo a interface e a implementao dos objectosA classe a unidade de modularidade na programao orientada por objectosUm objecto no uma classe (mas em algumas linguagens uma classe um objecto)8Classes9Introduo s Tcnicas de P. O. O.Introduo s Tcnicas de P. O. O.Um objecto composto por:- estado (variveis)- comportamento (mtodos)- identidade nica (caractersticas prprias)Os objectos conhecem a identidade de outros e o seu comportamentoOs objectos interagem por mensagensUm objecto corresponde, muitas vezes, a uma entidade do mundo real, podendo, no entanto representar entidades abstractas (exemplos: o nmero 3, letra A, etc)EstadoHorasMinutosSegundosPonteirosComportamentoIdentidade nicadingdongtictac 22:02:4512:15 22:02:4512:15EstadoHorasMinutosSegundosClssico ou digital?ComportamentoHoras?AcertarTocarClasse Relgio
-
Benefcios da ProgramaoOrientada por Objectos Linguagens diferentes usam conceitos e terminologias no totalmente coincidentesNo h um modelo semntico de objectos padro e universalNo existem metodologias de anlise e projecto universalmente aceites (por exemplo: mtodo Fusion)Tcnicas convencionais de anlise estruturada no so aplicveisAinda uma rea de investigao activaFormaoLinguagens de P. O. O. so conceptualmente diferentes das tradicionais preciso desaprender algumas coisas, pois estamos to habituados a formas iterativas que esquecemos que o mundo real constitudo por objectosLer sobre o assunto no suficiente, sobretudo essencial programarO tempo de aprendizagem bastante elevado, mesmo em linguagens de 4 gerao (Visual Basic, Delphi, etc).10Dificuldades na Utilizao da Programao Orientada por Objectos11Introduo s Tcnicas de P. O. O.Introduo s Tcnicas de P. O. O.Produtividade - Construir software mais fcil e baratoRobustez - O software mais fivel (por reutilizao e melhores regras)Manuteno - Muito mais fcil melhorias e achar os bugsExtensibilidade - Muito mais fcil acomodar novos requisitosModularidade - Abstrao e encobrimento da informaoNaturalidade - Programao orientada por abstraes do mundo real
-
GenerecidadeO polimorfismo permite em parte resolver o problema da limitao da generecidade. Com efeito, supondo que existem a classe Polgono e as classes derivadas Rectngulo e Quadrado, podemos ter uma Fila de Polgonos, com rectngulos e quadrados.Polgono P; Rectngulo R; Quadrado Q;P = R; P = Q; R = Q;R = P; // Erro, pois um polgono no um rectnguloP ponteiro para um polgono e como R e Q tambm so, podem ser tratados como tal, o que permite que um ponteiro para um Polgono possa apontar para qualquer objecto das suas subclasses (polimorfismo de incluso) - relao is-aNo entanto, a partir de um polgono no podemos aceder aos mtodos privados de um rectngulo ou quadrado. Resoluo:Polgono *P; Rectngulo R, *PR;P = &R; // A partir de P apenas se acede parte do polgonosPR = TYPESAFE_DOWNCAST(P, Rectngulo); // PR um ponteiro para o rectngulo R podendo aceder aos seus mtodos12Polimorfismo13Introduo s Tcnicas de P. O. O.Introduo s Tcnicas de P. O. O.Consiste em definir classes genricas (parametrizadas por outras classes)Tal como as funes convencionais, h parmetros formais e actuais (parmetros genricos)Exemplos:
Associao A(k, 10);A.AlterarValor(5);Fila FI;Fila FA;FI.Colocar(3);FA.Colocar(A);FI.Colocar(A) // erro, pois FI apenas pode receber inteirosEstadoC ChaveV ValorComportamentoV Valor?C Chave?AlterarValor(V val)Classe AssociaoEstadoT Vector[Max]int NumElemComportamentoT Frente?Colocar(T elem)Retirar()Classe Fila
-
Entradas/Sadas em C++Overloading da funo divisao:#include
int Divisao (int i, int j);float Divisao (float i, int j);
void main(){int a = 5, b = 2;float c=5.0;cout
-
Membros de uma Classe#include
class TPonto{int X, Y;public:TPonto(); // Construtor~TPonto(); // Destrutorvoid Mostrar();};
TPonto::TPonto(){cout > X >> Y;}
TPonto::~TPonto(){cout
-
Construtor com Argumentos#include
class Base {char C;public:char Chave();void DefinirChave(char c);};
class Derivada : public Base {int V;public:void DefinirValor(int v);void Mostrar();};
char Base::Chave() { return C; }
void Base::DefinirChave(char c) { C = c; }
void Derivada::Mostrar(){cout
-
Relao entre Classes,Estruturas e Unies#include
union Bits{double D;unsigned char V[sizeof(double)];Bits(double d);void Mostrar();};
Bits::Bits(double d){D = d;}
void Bits::Mostrar(){int i, j;for (j = sizeof(double)-1; j>=0; j--){cout
-
Funes In-Line#include #include #include #include ponto.h
class Ident{char *Nome;public:Ident(char *nome);~Ident() {cout
-
Passagem e Devoluo de ObjectosUma funo friend acede aos membros no pblicos sem no entanto pertencer classe.#include
class TLinha;
class TPonto{int X, Y;public:TPonto() { cout
-
Funes friend - IntroduoA funo Iguais friend da classe TPonto para poder aceder s coordenadas (X e Y) no pblicas de p.A funo TPonto::Juntar friend da classe TLinha para poder aceder s coordenadas no pblicas de lin.A funo Exemplo friend das classes TPonto e TLinha para poder aceder s coordenadas no pblicas de lin e p.Podemos igualmente ter uma classe friend de outra (todos os membros no pblicos da classe podem ser acedidos pela outra classe), por exemplo: a classe TLinha friend da classe TPonto.Neste momento, j deve ter verificado o nmero exagerado de vezes que so construdos e destrudos os objectos. Tal, deve-se passagem por valor dos objectos. Este problema ser resolvido atravs da utilizao da passagem por referncia, a introduzir no captulo seguinte.26Funes friend - Introduo27ClassesClassesTPonto TPonto::Juntar(TLinha lin){return TPonto (lin.P1.X, Y); // Acede a P1 pois friend de TLinha}
TLinha::TLinha(TPonto p1, TPonto p2){cout > X >> Y;TPonto P(X, Y);TLinha L(TPonto(2, 6), P);L.PontoMedio().Mostrar();Exemplo(L, P).Mostrar();cout
-
Vectores e Ponteiros de Objectosthis um ponteiro que automaticamente passado para qualquer funo membro quando chamada, onde this o ponteiro para o objecto que gera a chamada.
#include
class TPonto{public:int X, Y;TPonto() { cout
-
Alocao Dinmica - new e deleteA alocao e desalocao dinmica de vectores efectuada do seguinte modo:pont = new tipo [num_elementos];delete[ ] pont;
#include "ponto.h"
void main(){int *VI = new int[5];cout > VI[i];for (i = 0; i < 5; i ++)cout
-
Atribuio, Passagem e Devoluode Referncias para ObjectosA devoluo de uma referncia para uma varivel permite a consulta, alterao do valor e acesso ao endereo desta.
#include
class TPonto {public:int X, Y;TPonto() { cout
-
Atribuio, Passagem e Devoluode Referncias para Objectos// Permite consultar o ponto na posio iTPonto TVectorPontos::Consultar(int i){if (i < 0 || i >= NumPontos){cout > V.Colocar(i).X >> V.Colocar(i).Y;V.Colocar(2) = TPonto(8, 8); // Equivalente a V.VP[2]= TPonto(8, 8);V.Colocar(0).Mostrar(); // Equivalente a V.VP[0].Mostrar();for (i = 1; i < 4; i ++) // Se VP fosse pblicoV.Consultar(i).Mostrar(); // O mtodo Consultar dispensvel}
Deve ter em ateno o seguinte erro:
int &f(){int x;return x; // Devolve a referncia para uma varivel local}// Soluo: alocao dinmica
void main(){f() = 10; // Atribuio de um valor a uma varivel desalocada}34Atribuio, Passagem e Devoluo de Referncias para Objectos35Vectores, Ponteiros e RefernciasVectores, Ponteiros e Referncias#include "ponto.h"
class TVectorPontos{int NumPontos;TPonto *VP;public:TVectorPontos(int np);~TVectorPontos() { delete[ ] VP; }TPonto &Colocar(int i);TPonto Consultar(int i);};
TVectorPontos::TVectorPontos(int np){VP = new TPonto[NumPontos = np];if (!VP) {cout = NumPontos){cout
-
Overloading dos Construtores#include
class TPonto {public:int X, Y;TPonto() { cout
-
Overloading dos ConstrutoresConverso automtica
#include float f(float a) { return (2 * a); }float f(double b) { return (3 * b); }
void main() {float x = 1.5;double y = 1.5;cout
-
Endereo de uma Funo OverloadingO overloading de operadores tem a forma geral:tipo nomeclasse::operator nomeoperador(argumentos){// implementao}
No pode efectuar o overloading dos operadores: . :: .* ?
#include
class Simples{int I;public:Simples(int i) { I = i; }void Mostrar() { cout
-
Overloading de Operadores Binrios#include
class TPonto{ // Ver pgina anteriorTPonto operator-();TPonto operator++(); // Pr-incremento: ++pTPonto operator++(int /* nao usado */); // Ps-incremento: p++};
TPonto TPonto::operator-() {return TPonto (-X, -Y); // Cuidado se os argumentos forem// dependentes - TPonto(++X, X)}
TPonto TPonto::operator++() {++X;++Y;return *this;}
TPonto TPonto::operator++(int) {return TPonto (X++, Y++);}
void main() {TPonto P1(1, 2), P2(3, 4), P3;P3 = -P1; // Invoca operator-()P3.Mostrar();P3 = ++P2; // Invoca operator++()P3.Mostrar();P3 = P1++; // Invoca operator++(int)P3.Mostrar();P1.Mostrar();}42Overloading de Operadores Unrios43Overloading de Funes e OperadoresOverloading de Funes e Operadores#include
class TPonto {int X, Y;public:TPonto(int x=0, int y=0) { cout
-
Overloading de OperadoresRelacionais e Lgicos#include #include
class TPonto { int X, Y;public:TPonto(int x=0, int y=0) { cout P2;cout
-
Tipo de Acesso aos Membros de uma ClasseA forma geral de derivao de uma classe :class nomeclassederivada : acesso nomeclassebase{// declarao};onde o acesso pode ser:public (pblico) - A classe derivada tem acesso protegido e pblico, respectivamente, aos membros protegidos e pblicos da classe base.protected (protegido) - A classe derivada tem acesso protegido aos membros protegidos e pblicos da classe base.private (privado) - A classe derivada tem acesso privado aos membros protegidos e pblicos da classe base.46Tipo de Acesso Classe Base47HeranaHeranaOs membros privados de uma classe no podem ser acedidos pelos objectos instanciados, nem pelas classes derivadas. Os membros protegidos de uma classe no podem ser acedidos pelos objectos instanciados, podendo ser acedidos pelas classes derivadas. Os membros pblicos de uma classe podem ser acedidos pelos objectos instanciados e pelas classes derivadas.
#include
class Base {char Codigo;protected:int Numero;public:void Atribuir(char codigo, int numero);};
void Base::Atribuir(char codigo, int numero){Codigo = codigo;Numero = numero;}
void main(){Base B;B.Atribuir('K', 12);cout
-
Acesso Pblico Classe Base#include #include
class Base {char Codigo;protected:int Numero;public:void Atribuir(char codigo, int numero);};
void Base::Atribuir(char codigo, int numero){ Codigo = codigo; Numero = numero; }
class DerivadaProtegido : protected Base {char Ident[20];protected: // Acesso protegido aos membros protegidos// e pblicos da classe Baseint Chave;public:void Atribuir(char codigo, int numero, int chave);};
void DerivadaProtegido::Atribuir(char codigo, int numero, int chave) {Base::Atribuir(codigo, numero);Chave = chave;sprintf(Ident, "%i%c%i", Chave, Codigo, Numero);} // Erro, pois Codigo no acessvel na classe DerivadaProtegido
void main() {DerivadaProtegido D;D.Base::Atribuir('K', 12); // Erro, pois Base::Atribuir() protegidocout
-
Acesso Privado Classe BaseUm construtor da classe A pode ter uma lista de iniciaes, que permite invocar os construtores das classes bases e das variveis membro da classe A, antes da execuo da primeira instruo do construtor A. A forma geral de um construtor :nomeclassederivada(args): nomeclassebase1(vals), ..., nomeclassebaseN(vals), varivelmembro1(vals), ..., varivelmembroM(vals){// Implementao};
#include
class TPonto {public:int X, Y;TPonto(int x = 0, int y = 0) : X(x), Y(y) // Iniciao de X e Y { cout
-
Hierarquia de FigurasVerso da classe TLinha derivando da classe TFigura
class TLinha : public TFigura{TPonto P2;public:TLinha(const TPonto &p1 = TPonto(), const TPonto &p2 = TPonto()): TFigura(p1), P2(p2) { cout
- Hierarquia de FigurasTDesenho::TDesenho(int mf, const TPonto &p = TPonto()): TFigura(p), MaxFig(mf), NumFig(0){cout
-
Hierarquia de Figuras#include
class Chave {char C;public:Chave(char c) : C(c) { cout
-
Herana MltiplaPara evitar a duplicao de informao necessrio que as classes TTriangulo e TRectangulo derivem virtualmente da classe TFigura.
class TTriangulo : virtual public TFigura { ... };
class TRectangulo : virtual public TFigura { ... };
class TTrianguloRectangulo : public TTriangulo, public TRectangulo {public:TTrianguloRectangulo(const TPonto &p1 = TPonto(), const TPonto &p2 = TPonto(), const TPonto &p3 = TPonto());~TTrianguloRectangulo() { cout P2;cout > P3;TTrianguloRectangulo TR(P1, P2, P3);TR.Mover(P2);}58Classes de Base Virtual 59HeranaHeranaAo pretender criar um tringulo rectngulo a partir de um tringulo e de um rectngulo surge a duplicao da informao da classe TFigura, pois a classe base de ambos.
class TTrianguloRectangulo : public TTriangulo, public TRectangulo{public:TTrianguloRectangulo(const TPonto &p1 = TPonto(), const TPonto &p2 = TPonto(), const TPonto &p3 = TPonto());~TTrianguloRectangulo() { cout P2;cout > P3;TTrianguloRectangulo TR(P1, P2, P3);TR.Mover(P2);}
-
Funes Virtuais - Introduo#include
class Base{char C;public:Base(char c) : C(c) { cout
- Exemplo Prticoint DerivadaCar::Resultado(){cout
-
Funes Virtuais PurasO polimorfismo o processo, pelo qual uma interface comum aplicada em duas ou mais situaes semelhantes, mas tcnicamente diferentes, implementando a filosofia de uma interface, mltiplos mtodos.O polimorfismo de incluso (relao is-a) processo, pelo qual um ponteiro para uma classe de interface pode apontar para instncias das suas classes derivadas, permitindo atravs deste elaborar os mtodos de interface das instncias apontadas e no da classe de interface.
void main() {BaseInterface *P;// Desenhar() mtodo de interfaceDerivadaABaseInterface A;DerivadaBBaseInterface B;P = &A; P->Desenhar(); // Invoca A.Desenhar()P = &B; P->Desenhar(); // Invoca B.Desenhar()}O polimorfismo global processo, pelo qual se tem acesso aos mtodos prprios das instncias das classes derivadas apontadas por um ponteiro para uma classe de interface.
void main() {DerivadaABaseInterface A, *PA;BaseInterface *P = &A;PA=TYPESAFE_DOWNCAST(P, DerivadaABaseInterface);PA->MetodoProprio(); // Invoca A. MetodoProprio()}64Polimorfismo65Funes VirtuaisFunes VirtuaisUma funo virtual pura uma funo virtual sem implementao de cdigo na classe base, devendo ser implementada nas classes derivadas.Uma funo virtual pura definida do modo seguinte: class Exemplo{...public: // ou protected:virtual char funcvp (int i) = 0;};Uma classe com uma funo virtual pura designada por classe abstracta, pelo facto de ter pelos menos um mtodo sem cdigo concreto.Uma classe abstracta no pode ser instnciada, podendo, no entanto, ser declarados ponteiros para essa classe, apontando para instncias das classes derivadas (desde que no sejam abstractas).void main(){BaseAbstracta B; // Erro, pois no se pode intnciar a// classe BaseAbstracta DerivadaBaseAbstracta D;BaseAbstracta *PB = &D;// Correcto, pois PB um ponteiro para a classe// BaseAbstracta, podendo apontar para instncias// das classes derivadas};
-
BindingNa pgina 55, como o mtodo Mover() no virtual invocado o mtodo TFigura::Mover(), o que apenas move a localizao do desenho e o primeiro ponto das figuras deste, e no as figuras como pretendido.
void TDesenho::Mover(const TPonto &p) {TFigura::Mover(p);for (int i = 0; i < NumFig; i++)VF[i]->TFigura::Mover(p);}
Na pgina 56, no programa principal ao movermos o desenho Des, apenas movido o primeiro ponto de cada figura nele inserida.void main() {TDesenho Des(4);TPonto P1, P2, P3;cout > P1;cout > P2;cout > P3;TLinha L(P1, P2);TRectangulo R(P1, P3);TTriangulo T(P1, P2, P3);TQuadrado Q(P2, P3);Des.Inserir(L);Des.Inserir(R);Des.Inserir(T);Des.Inserir(Q);Des.Mover(P2);}
66Hierarquia de Figuras Utilizando o Polimorfismo67Funes VirtuaisFunes VirtuaisBinding - Determinao do mtodo a executar correspondente a um dado selector:Binding esttico (mais eficiente) - O compilador sabe qual a classe do receptor e rigorosamente, qual o mtodo a invocar (exemplo: TQuadrado Q(P1, P2); Q.Desenhar() )Binding dinmico - O compilador sabe apenas que o receptor pertence a uma dada classe ou s suas classes derivadas. Verifica apenas se o mtodo existe na classe (em compile-time), determinando em run-time, qual o selector apropriado. utilizado em C++ sempre que se aplica o polimorfismo de incluso (exemplo: TFigura *PF; PF = LerTipoObjecto(); PF->Desenhar(); )Binding tardio (menos eficiente) - O compilador no sabe qual a classe do receptor, pelo que tem que efectuar a sua escolha em run-time (utilizado em SmallTalk)
- Hierarquia de Figuras Utilizando o Polimorfismoclass TTriangulo : public TFigura{protected:TPonto P2, P3;public:TTriangulo(const TPonto &p1 = TPonto(),const TPonto &p2 = TPonto(), const TPonto &p3 = TPonto()): TFigura(p1), P2(p2), P3(p3) { }~TTriangulo() { }virtual void Mover(const TPonto &p) { cout
-
Hierarquia de Figuras Utilizando o PolimorfismoTDesenho::~TDesenho(){delete[] VF;}
void TDesenho::Inserir(TFigura *f){if (NumFig == MaxFig){cerr
-
Hierarquia de Figuras Utilizando o PolimorfismoDes.Inserir(PF);Des.Desenhar();Des.Mover(P2);for (int I = 0; I < 5; I++)switch (Des.Figura(I)->Tipo()){// Acesso aos mtodos prprios das figuras// Polimorfismo Globalcase TFigura::Linha :cout DistanciaX() no acessival,// pois Des.Figura(3) um ponteiro para uma TFigurabreak;case TFigura::Rectangulo :TYPESAFE_DOWNCAST(Des.Figura(I), TRectangulo)->Diagonal().Mover(P3);break;case TFigura::Triangulo :cout Diagonal().Mover(P3);PQ->Lado().Mover(P3);break;}}
72Hierarquia de Figuras Utilizando o Polimorfismo73Funes VirtuaisFunes Virtuaisvoid main(){TDesenho Des(5);TPonto P1, P2, P3;cout > P1;cout > P2;cout > P3;TLinha L(P1, P2);TRectangulo R(P1, P3);TTriangulo T(P1, P2, P3);TQuadrado Q(P2, P3);Des.Inserir(&L);Des.Inserir(&R);Des.Inserir(&T);Des.Inserir(&Q);cout > Tp;TFigura *PF;switch (Tp){case TFigura::Linha :PF = new TLinha(P1, P3);break;case TFigura::Rectangulo :PF = new TRectangulo(P1, P3);break;case TFigura::Triangulo :PF = new TTriangulo(P1, P2, P3);break;case TFigura::Quadrado :PF = new TQuadrado(P1, P3);}
-
Entrada e Sada FormatadaAs flags de formato de leitura e escrita em C++ so enumeradas na classe ios.
Ficheiros padro em C++ cin - entrada padro (teclado por defeito)cout - sada padro (ecran por defeito)cerr - sada de erro padro (ecran por defeito)clog - sada de erro padro bufferizada (ecran por defeito)
Funes de manipulao do formato de E/S (classe ios) long setf (long flags);Activa as flags e devolve o formato anterior.long unsetf (long flags);Desactiva as flags e devolve o formato anterior.long flags ();Devolve o formato actual.long flags (long flags);Estipula o formato atravs das flags e devolve o formato anterior. A utilizao deste mtodo implica a desactivao de todas as flags anteriormente activadas.74Entrada e Sada Formatada75Sistema de Entrada/SadaSistema de Entrada/SadaO sistema de entradas/sadas em C++ definido pela hierarquia de classes derivadas da classe ios definida no ficheiro iostream.h
Flags de formato de entrada/sada em C++skipws - define o desprezo dos caracteres espao na leituraleft - define escrita justificada esquerdaright - define escrita justificada direitainternal - define escrita com preenchimento com espaos brancos se necessriodec - define escrita em decimaloct - define escrita em octalhex - define escrita em hexadecimalshowbase - define a escrita da base numricashowpoint - define a escrita obrigatria do ponto decimaluppercase - define a escrita da base em maisculasscientific - define a escrita em notao cientficafixed - define a escrita em notao normalunitbuf - define a actualizao da informao em disco (flush) aps cada instruo de sadastdio - define a actualizao da informao em disco dos ficheiros stdout e stderr
-
Entrada e Sada Formatadaint width (int w);Fixa o tamanho do campo para escrita e devolve o tamanho anterior.int precision (int p);Fixa a preciso de um campo (por defeito 6) e devolve a preciso anterior.char fill (char ch);Define o caracter de preenchimento quando necessrio, devolvendo o anterior.
Exemplo:
#include void main() {cout.width(10); cout.precision(5); cout.fill('*');cout
-
Manipuladores de Entrada/SadaO overloading dos operadores > tem a forma geral:ostream &operator(istream &is, classe &obj) {// implementaoreturn is;}
#include
class TPonto { int X, Y;public:TPonto(int x=0, int y=0) : X(x), Y(y) {}friend ostream &operator p;};
ostream &operator P1 >> P2;cout
-
Implementao de Manipuladoresde Entrada/SadaAs classes ifstream, ofstream e fstream definem respectivamente ficheiros de entrada, sada e entrada/sada formatada, e esto definidas no ficheiro fstream.hvoid open (const char *fic, int modo, int acesso); Abre um ficheiro, onde o modo pelo menos um dos valores: ios::app - abre um ficheiro para acrscimo de informaoios::ate - abre um ficheiro, colocando-se no seu fimios:: binary - abre um ficheiro em modo binrioios:: in - abre um ficheiro com potencialidades de leituraios:: nocreate - abre um ficheiro, apenas caso j existaios:: noreplace - abre um ficheiro, apenas caso no existaios:: out - abre um ficheiro com potencialidades de escritaios:: trunc - abre um ficheiro, destruindo a informao anterior e onde o acesso pelo menos de um dos tipos: 0 - ficheiro com acesso normal1 - ficheiro com acesso apenas de leitura2 - ficheiro escondido4 - ficheiro de sistema8 - arquivo de conjunto de bitsvoid close (); Fecha o ficheiro, actualizando o seu contedo em disco. int eof (); Define se o ponteiro para o ficheiro chegou ao fim deste. 80Ficheiros de Entrada/Sada81Sistema de Entrada/SadaSistema de Entrada/SadaOs manipuladores de entrada/sada tm a forma geral:ostream &nomemanipulador(ostream &os) {// implementaoreturn os;}istream & nomemanipulador(istream &is) {// implementaoreturn is;}
#include "ponto.h"
ostream &setup(ostream &os) {os.width(5);os.precision(3);os.fill(-);return os;}
ostream &atencao(ostream &os) {os introducaoponto >> P;cout
-
Ficheiros de Entrada/SadaAs funes binrias de manipulao de ficheiros podem ser executadas em qualquer tipo de ficheiro, no sendo necessrio abrir o ficheiro como binrio (ios::binary).istream &get (char &ch); L um caracter a partir do ficheiro associado e coloca o valor em ch. Devolve uma referncia para o ficheiro, ou null em caso de erro.ostream &put (char ch); Escreve o caracter ch no ficheiro associado e devolve o ficheiro. istream &read (unsigned char *buf, int num); L num bytes a partir do ficheiro associado, colocando-os no buffer apontado por buf. Devolve o ficheiro, ou null em caso de erro.ostream &write (unsigned char *buf, int num); Escreve num bytes no ficheiro associado a partir do buffer apontado por buf e devolve o ficheiro.long gcount ();Devolve o n de caracteres lidos pela ltima operao binria de entrada.82Entrada/Sada Binria83Sistema de Entrada/SadaSistema de Entrada/Sada#include #include
// Este programa efectua a cpia do ficheiro entradas// para o ficheiro saidasint main(){ifstream FEnt("entradas");if (!FEnt){cout C;FSai
-
Entrada/Sada Binria#include "ponto.h"#include #include
void main(){TPonto VP[5];cout > VP[i];ofstream fpo("pontos");int N = 5;fpo.write((char *) &N, sizeof(int));fpo.write((char *) VP, N * sizeof(TPonto));fpo.close();ifstream fpi("pontos");fpi.read((char *) &N, sizeof(int));fpi.read((char *) VP, N * sizeof(TPonto));fpi.close();for (i = 0; i < 5; i++)cout
-
Acesso Aleatrio#include "ponto.h"#include #include
class TVectorFicheiro {int NumElem; fstream *Fic;public:TVectorFicheiro(int numElem, char *nomeFic);~TVectorFicheiro() { Fic->close(); delete Fic; }void Colocar(int i, const TPonto &p);TPonto Ponto(int i);};
TVectorFicheiro::TVectorFicheiro(int numElem, char *nomeFic) {NumElem = numElem;if (! (Fic = new fstream(nomeFic, ios::in | ios::out)) exit (1);}
void TVectorFicheiro::Colocar(int i, const TPonto &p) {if (i < 0 || i >= NumElem) exit(1);Fic->seekp(i * sizeof(TPonto), ios::beg);Fic->write((char *) &p, sizeof(TPonto));}
TPonto TVectorFicheiro::Ponto(int i) {if (i < 0 || i >= NumElem) exit(1);Fic->seekg(i * sizeof(TPonto), ios::beg);TPonto P;Fic->read((char *) &P, sizeof(TPonto));return P;}
int main() {TVectorFicheiro VPF(5, "VecFic");VPF.Colocar(3, TPonto(-3, 3));cout
-
Funes GenricasUma classe genrica (template class) uma classe que definida utilizando outras classes que recebe como parmetros, pelo que, igualmente designada por classe parametrizada.As classes genricas so bastantes teis nas estruturas de dados que contm uma lgica genrica. Por exemplo, listas, pilhas, filas, etc.A definio de uma classe genrica tem a forma geral:templateclass nomeclasse : ... {// implementao}
#include
template class TAssociacao {C Cha;V Val;public:TAssociacao() {}TAssociacao(const C &cha, const V &val);const C &Chave() {return Cha; }V &Valor() { return Val; }int operator==(const TAssociacao &a);V &operator()() { return Val; }V &operator[](const C &cha);friend ostream &operator(istream &is, TAssociacao &a);};
88Classes Genricas89Generecidade e ExcepesGenerecidade e ExcepesUma funo genrica (template function) define um conjunto de operaes gerais que podem ser aplicadas a vrios tipos de dados. Uma funo genrica igualmente designada por funo parametrizada, por necessitar da passagem dos tipos de dados com os quais vai operar.A definio de uma funo genrica tem a forma geral:templatetipo nomefuncao(args) {// implementao}
#include "ponto.h"#include
template void Trocar(T &x, T &y) {T Temp = x;x = y;y = Temp;}
void main() {int I = 1, J = 2;TPonto P1(1, 2), P2(3, 4);Trocar(I, J);Trocar(P1, P2);cout
-
Classe Genrica TAssociacao#include "associac.h"#include "ponto.h"
void main(){TAssociacao AIC1(3,'A'), AIC2(3, 'K');cout
-
Criao de uma Lista Genrica Ordenadatemplate TNoListaDupla *TListaDupla::Pesquisar(const T &elem){TNoListaDupla *S = Inicio->Seg;while (S->Elem < elem)S = S->Seg;return S;}
template void TListaDupla::Inserir(const T &elem){TNoListaDupla *S = Pesquisar(elem);new TNoListaDupla(elem, S);}
template int TListaDupla::Remover(const T &elem){TNoListaDupla *S = Pesquisar(elem);if (S->Elem == elem){S->Ant->Seg = S->Seg;S->Seg->Ant = S->Ant;delete S;return 1;}return 0;}92Criao de uma Lista Genrica Ordenada93Generecidade e ExcepesGenerecidade e Excepestemplate class TNoListaDupla{public:T Elem;TNoListaDupla *Ant, *Seg;TNoListaDupla(const T &elem): Elem(elem) { Seg = Ant = this; }TNoListaDupla(const T &elem, TNoListaDupla *seg): Elem(elem) { Seg = seg; Ant = seg->Ant; Seg->Ant = Ant->Seg = this; }};
template class TIteradorListaDupla; // Declarao forward
template class TListaDupla{TNoListaDupla *Inicio;TNoListaDupla *Pesquisar(const T &elem);// Devolve ponteiro para seguintepublic:typedef void (*FuncOper)(T &, void *);typedef int (*FuncCond)(const T &, void *);friend TIteradorListaDupla; // Para poder aceder ao Inicio da listaTListaDupla(const T &lim) { Inicio =new TNoListaDupla(lim); }void Inserir(const T &elem);int Remover(const T &elem);void EfectuarOperacao( FuncOper oper, void *args);T &PrimeiroQue(FuncCond cond, void *args );};
-
Criao de uma Lista Genrica Ordenadatemplate class TIteradorListaDupla{TListaDupla *Lista;TNoListaDupla *Cor;int Tipo;public:enum { Inicio, Fim };TIteradorListaDupla(TListaDupla &lista, int tipo = Inicio){ Lista = &lista; Tipo = tipo; Cor = (Tipo == Inicio) ? Lista->Inicio->Seg : Lista->Inicio->Ant; }operator int () { return Cor != Lista->Inicio; }T &Corrente(){if (! int(*this))exit(1);return Cor->Elem;}T &operator++(){if (Cor->Seg == Lista->Inicio)exit(1);Cor = Cor->Seg;return Cor->Elem;}94Criao de uma Lista Genrica Ordenada95Generecidade e ExcepesGenerecidade e Excepestemplate void TListaDupla::EfectuarOperacao(TListaDupla::FuncOper oper, void *args){TNoListaDupla *S = Inicio->Seg;while (S != Inicio){oper(S->Elem, args);S = S->Seg;}}
template T &TListaDupla::PrimeiroQue(TListaDupla::FuncCond cond, void *args){TNoListaDupla *S = Inicio->Seg;while (S != Inicio){if (cond(S->Elem, args))return S->Elem;S = S->Seg;}return Inicio->Elem;}
-
Criao de uma Lista Genrica Ordenada#include #include "listadpl.h"
void Escrever(int &i, void *) {cout Elem;}void Reiniciar() { if (Tipo == Inicio)Cor = Lista->Inicio->Seg; elseCor = Lista->Inicio->Ant; }};
-
Definio e Encaminhamentode Excepes#include
void main(){cout
-
Definio de umaFuno de ExcepesResultado:ExcepesCatch inteiro: -3Catch string: Valor NuloCatch por defeitoFim
#include #include
#define PRECONDICAOX(cond, mens) \try { if (! cond) throw cond; } \catch (...) { cout A >> B;cout
-
Redefinio da Classe TIteradorListaDupla com ExcepesT &operator--(){PRECONDITION(Cor->Ant != Lista->Inicio);Cor = Cor->Ant;return Cor->Elem;}T &operator--(int){PRECONDITION(Cor != Lista->Inicio);TNoListaDupla *Aux = Cor;Cor = Cor->Ant;return Aux->Elem;}void Reiniciar() { if (Tipo == Inicio)Cor = Lista->Inicio->Seg; elseCor = Lista->Inicio->Ant; }};
Em Borland C++ no ficheiro checks.h esto definidos os macros:PRECONDITION(cond) - se cond = 0 define a excepo e escreve a mensagem #condPRECONDITIONX(cond,mens) - se cond = 0 define a excepo e escreve a mensagem mens102Redefinio da Classe TIteradorListaDupla com Excepes103Generecidade e ExcepesGenerecidade e Excepestemplate class TIteradorListaDupla{TListaDupla *Lista;TNoListaDupla *Cor;int Tipo;public:enum { Inicio, Fim };TIteradorListaDupla(TListaDupla &lista, int tipo = Inicio){ Lista = &lista; Tipo = tipo; Cor = (Tipo == Inicio) ? Lista->Inicio->Seg : Lista->Inicio->Ant; }operator int () { return Cor != Lista->Inicio; }T &Corrente(){PRECONDITION( int(*this));return Cor->Elem;}T &operator++(){PRECONDITION(Cor->Seg != Lista->Inicio);Cor = Cor->Seg;return Cor->Elem;}T &operator++(int){PRECONDITION(Cor != Lista->Inicio);TNoListaDupla *Aux = Cor;Cor = Cor->Seg;return Aux->Elem;}
- Membros Estticosvoid main(){char C;int V;cout > C;cout > V;A::Iniciar(0); // Invocao de mtodo da classe AA VA(C);VA.Mostrar();B VB(C, V);VB.Mostrar();cout
- Membros Estticosvoid main(){char C;int V;cout > C;cout > V;A::Iniciar(0); // Invocao de mtodo da classe AA VA(C);VA.Mostrar();B VB(C, V);VB.Mostrar();cout