apostila c++.pdf

29
Classes e Objectos Uma classe  é um tipo definido pelo programad or que cont ém o molde, a especif icação para os objectos, tal como o tipo inteiro cont ém o molde para as variáveis declaradas como inteiros. A classe envolve e/ou associa, fun ções e dados, controlando o acesso a estes, defin í-la implica especif icar os seus atributos ( dados ) e suas fun ções membro ( código ). ex:. Um programa que utiliza uma interface controladora de um motor eléctric o defini ria a classe motor. Os atributos desta classe seriam: temperatura, velocidade, tens ão aplicad a. Estes seriam repr esentad os na classe por tipos como float ou long . As fun ções membro desta classe seriam fun ções para alterar a velocidade, ler a temperatura, etc. Especificar uma Classe Vamos supor um programa que controla um motor el éctrico através de uma saída serie. A velocidade do motor  é proporcional  à tensão aplicada, e esta proporcional aos bits que v ão para saída serie que passam por um conversor digital anal ógico ( DAC ). Vamo - nos abstrair de todos estes detalhes por enquanto e modelar somente a interf ace do moto r como uma classe, a pergun ta  é que funções e que dados membro deve ter nossa classe, e que argumentos e valores de retorno devem ter essas funções membro: Representa ção da velocidade A velocidade do motor ser á representada por um atributo, inteiro (int). Usaremos o número de bits que precisarmos, caso o valor de bits necessário não possa ser fornecido pelo tipo , usaremos ent ão o tipo long , isto depende do conver sor digital anal ógico utilizado e do compilado r. Representa ção da saí da série O motor precisa conhecer a sa ída serie, a sua ligação com o "motor do mundo real". Vamos supor uma representa ção em hexadecimal do atributo endereço de porta serie, um poss ível nome para o  atributo: enderecomotor .

Upload: edson-morais

Post on 18-Oct-2015

183 views

Category:

Documents


0 download

TRANSCRIPT

  • Classes e ObjectosUma classe um tipo definido pelo programador que contm o molde,

    a especificao para os objectos, tal como o tipo inteiro contm o molde paraas variveis declaradas como inteiros. A classe envolve e/ou associa, funese dados, controlando o acesso a estes, defin-la implica especificar os seusatributos ( dados ) e suas funes membro ( cdigo ).

    ex:. Um programa que utiliza uma interface controladora de um motorelctrico definiria a classe motor. Os atributos desta classe seriam:temperatura, velocidade, tenso aplicada. Estes seriam representados na classepor tipos como float ou long . As funes membro desta classe seriam funespara alterar a velocidade, ler a temperatura, etc.

    Especificar uma ClasseVamos supor um programa que controla um motor elctrico atravs de

    uma sada serie. A velocidade do motor proporcional tenso aplicada, eesta proporcional aos bits que vo para sada serie que passam por umconversor digital analgico ( DAC ).

    Vamo - nos abstrair de todos estes detalhes por enquanto e modelarsomente a interface do motor como uma classe, a pergunta que funes eque dados membro deve ter nossa classe, e que argumentos e valores deretorno devem ter essas funes membro:

    Representao da velocidadeA velocidade do motor ser representada por um atributo, inteiro (int).Usaremos o nmero de bits que precisarmos, caso o valor de bits

    necessrio no possa ser fornecido pelo tipo , usaremos ento o tipo long , istodepende do conversor digital analgico utilizado e do compilador.

    Representao da sada srieO motor precisa conhecer a sada serie, a sua ligao com o "motor do

    mundo real". Vamos supor uma representao em hexadecimal do atributoendereo de porta serie, um possvel nome para o atributo: enderecomotor.

  • Alterao do valor da velocidadeInternamente o utilizador da classe motor pode desejar alterar a

    velocidade, cria-se ento a funo :void altera_velocidade(int novav);O valor de retorno da funo void ( valor vazio ), poderia ser criado

    um valor de retorno (int) que indicasse se o valor de velocidade era permitidoe foi alterado ou no era permitido e portanto no foi alterado.

    Mtodos ou Funes MembroO C++ permite que se acrescente funes de manipulao da struct na

    declarao, juntando tudo numa s entidade que uma classe. Essas funesmembro podem ter sua declarao ( cabealho ) e implementao ( cdigo )dentro da struct ou s o cabealho ( assinatura ) na struct e a implementao,cdigo, fora. Este exemplo apresenta a primeira verso, o prximo a segundaverso ( implementao fora da classe ). Essas funes compem a interfaceda classe. A terminologia usada para design-las bastante variada: funesmembro, mtodos, etc. Quando uma funo membro chamada, diz - se que oobjecto est a receber uma mensagem ( para executar uma aco ). Umprograma simples para testes sobre funes membro seria o seguinte:Exemplo 1 :#include

  • umcontador.comeca();//nao esquecas os parenteses, uma funcao membro e no atributo!cout
  • {float raio;float x; //atributo coordenada cartesiana xfloat y; //atributo coordenada cartesiana y

    void move(float dx,float dy) //funo membro ou funo membro move{x+=dx; //equivale a x=x+dx;y+=dy;

    }

    void mostra(void) //funo membro ou funo membro mostra{cout

  • Raio:10X:100Y:1

    Comentrios: A funo membro move altera as coordenadas do objecto. Oobjecto tem as coordenadas x e y somadas com os argumentos dessa funomembro. Nota que esta funo membro representa uma maneira mais segura,clara, elegante de alterar as coordenadas do objecto do que acess-lasdirectamente da seguinte forma: ac.x+=dx;. ac.y+=dy;. Lembre-se queac.x+=dx uma abreviao para ac.x=ac.x+dx; .

    Como funcionam no compilador as chamadas de funes membro: possvel imaginar que as definies de funes membro ocupam um grandeespao na representao interna dos objectos, mas lembre-se que elas sotodas iguais para uma classe, ento basta manter para cada classe uma tabelade funes membro que consultada no momento da chamada . Os objectoss precisam ter uma referncia para esta tabela.

    Funes Membro que retornam um valorAt agora s tnhamos visto funes membro com valor de retorno

    igual a void. Uma funo membro, assim como uma funo comum, poderetornar qualquer tipo, inclusive os definidos pelo programador. Sendo assim,sua chamada no programa aplica - se a qualquer lugar onde se espera um tipoigual ou equivalente ao tipo do seu valor de retorno, seja numa lista deargumentos de outra funo , numa atribuio ou num operador como o cout

  • };

    void main() //teste do contador{contador umcontador;

    umcontador.comeca();//nao esqueca dos parenteses, e uma funo membro nao dado!cout

  • struct teste{int x;

    void altera_x(int v);//somente definicao implementacao vem depois, fora da classe

    };

    void teste::altera_x(int v) { x=v;} //esta j a implementacao codigovoid main(){teste a; //instaciao de um objectoa.altera_x(10);//chamada da funo membro com valor 10 que sera impresso a seguircout

  • void move(float dx,float dy);void mostra(void);

    };

    void circulo::inicializa(float ax,float by,float cr){x=ax;y=by;raio=cr;

    }

    void circulo::altera_raio(float a){raio=a;

    }

    float circulo::retorna_raio(void){return raio;

    }

    void circulo::move(float dx,float dy){x+=dx;y+=dy;

    }

    void circulo::mostra(void){cout

  • ac.mostra();ac.move(1.0,1.0);ac.mostra();ac.x=100.0;ac.altera_raio(12.0);ac.mostra();

    }

    Comentrios: Observe que a funo membro mostra chama a funo membrofloat retorna_raio( void ) que da mesma classe. Fica implcito da definiode mostra que retorna_raio() se aplica ao mesmo objecto instanciado querecebeu a chamada de mostra, ou seja, no necessrio usar o . na chamadade retorna_raio(). Em programas maiores, chamadas aninhadas de funesmembro so bastante comuns.Programao orientada a objectos e interfaces grficas com o utilizador:Existem libraries de classes que permitem o programador C++ desenvolveraplicaes para ambientes como o Microsoft Windowsreg. de uma maneirabastante abstracta, este um exemplo claro de reuso de cdigo, afinal oprogramador no precisa saber de detalhes da interface para programar nela.Resultado do programa:Raio:10X:0Y:0Raio:10X:1Y:1Raio:12.0X:100.0Y:1

    C++: As classes em C++ englobam os dados membros e as funes membros.Para executar uma ao sobre o objecto ou relativa a este basta chamar umafuno membro para este: ac.mostra();A funo membro no precisa de muitos argumentos, porque prpria daclasse e portanto ganha acesso aos dados membro do objecto para o qual elafoi associada:

  • float circulo::retorna_raio(void){return raio; //tenho acesso direto a raio.

    }

    Segurana: Em C++ o programador pode aceder directamente os dados dotipo definido pelo usurio: ac.x=100.0.Veremos maneiras de proibir em C++ este tipo de acesso directo ao dadomembro, deixando este ser modificado somente pelas funes membro. Istonos garante maior segurana e liberdade pois podemos permitir ou no oacesso para cada dado membro de acordo com nossa vontade.

    Eficincia: Algum pode argumentar que programas que usam bastantechamadas de funes podem se tornar pouco eficientes e que poderia sermelhor aceder diretamente os dados de um tipo definido pelo usurio ao envsde passar por todo o trabalho de cpia de argumentos, insero da funo nopilha, etc.

    Na verdade no se perde muito em eficincia, e alm disso muitas vezes nose deseja permitir sempre o acesso directo aos dados de um tipo definido peloprogramador por razes de segurana. Nesse sentido o C++ oferece umrecurso que permite ganhos em segurana sem perder muito em eficincia.

    ConstructoresConstrutores so funes membro especiais chamadas pelo sistema nomomento da criao de um objecto. Elas no possuem valor de retorno,porque voc no pode chamar um construtor para um objecto. Construtoresrepresentam uma oportunidade de inicializar de forma organizada os objectos;imagina se tu te esqueces de inicializar correctamente ou o fazes duas vezes,etc.

    Um construtor tem sempre o mesmo nome da classe e no pode ser chamadopelo utilizador desta. Para uma classe string o construtor teria a formastring(char* a); com o argumento char* especificado pelo programador. Eleseria chamado automaticamente no momento da criao, declarao de umastring:

  • string a("Texto"); //alocacao estatica implica na chamada do construtor

    a.mostra(); //chamada de metodos estatica.

    Existem variaes sobre o tema que veremos mais tarde: Sobrecarga deconstrutor, "copy constructor", como conseguir construtores virtuais (avanado, no apresentado neste texto ), construtor de corpo vazio.O exemplo seguinte simples, semelhante aos anteriores, presta ateno nafuno membro com o mesmo nome que a classe ( struct ), este oconstrutor:

    Exemplo 6 :#include

  • {x+=dx;y+=dy;

    }

    void main(){ponto ap(0.0,0.0);

    ap.mostra();ap.move(1.0,1.0);ap.mostra();

    }

    Resultado do programa:X:0 , Y:0X:1 , Y:1

    Comentrios: Nota que com a definio do construtor, s obrigado a passaros argumentos deste no momento da criao do objeto.

    Constructores e AgregaoO programa exemplo deste tpico cria uma classe recta com dois dadosmembro da classe ponto este exemplo o resultado do exerccio anterior, comum recurso a mais de C++. C++ permite que no construtor da classe recta,voc chame os construtores dos atributos da classe ponto, se no o fizeres ocompilador acusar um erro, pois os atributos ponto possuem constructores eeles precisam ser chamados para que a inicializao se complete de modocorrecto para o conjunto.

    Observa o cdigo do constructor da classe recta usado no exemplo:recta(float x1,float y1,float x2,float y2):p1(x1,y1),p2(x2,y2){//nada mais a fazer, os construtores de p1 e p2 ja foram chamados

    }

  • p1(x1,y1) e p2(x2,y2) so as chamadas dos constructores da classe ponto, elasdevem ficar fora do corpo {} do constructor, nesta lista separada por vrgulasdeves inicializar todos os atributos. Os tipos bsicos como int, float, etcpodem ser inicializados nessa lista.

    Por exemplo se a classe recta tivesse um atributo inteiro de nomeidentificao, a lista poderia ser da seguinte forma:reta(float x1,float y1,float x2,float y2):p1(x1,y1),p2(x2,y2),identificacao(10){//nada mais a fazer, os construtores de p1 e p2 ja foram chamados

    }

    seria como se identificao tivesse um constructor que tem como argumento oseu valor. ou

    recta(float x1,float y1,float x2,float y2):p1(x1,y1),p2(x2,y2){identificacao=10;//tambem pode, porque tipos bsicos (int) em C++ no so objectos// portanto nao tem construtores

    }

    Vamos ao exemplo, que novamente semelhante aos anteriores, para que oleitor preste ateno somente nas mudanas, que so os conceitos novos, semter que se esforar muito para entender o programa:Exemplo 7 :#include

  • } //construtor

    void move(float dx,float dy){ x+=dx; y+=dy; } //funcao membro comum

    void inicializa(float a,float b){ x=a; y=b; }

    void mostra(void){cout

  • X:1 , Y:1X:10 , Y:10 DestructoresAnlogos aos constructores, os destructores tambm so funes membrochamadas pelo sistema, s que elas so chamadas quando o objecto sai deescopo ou em alocao dinmica, tem seu ponteiro desalocado, ambas( construtor e destrutor ) no possuem valor de retorno.No se pode chamar o destructor, o que se faz fornecer ao compilador ocdigo a ser executado quando o objecto destrudo, apagado. Ao contrriodos constructores, os destructores no tem argumentos.Os destructores so muito teis para "limpar a casa" quando um objecto deixade ser usado, no escopo de uma funo em que foi criado, ou mesmo numbloco de cdigo. Quando usados em conjunto com alocao dinmica elesfornecem uma maneira muito prctica e segura de organizar o uso do "heap".A importncia dos destructores em C++ aumentada pela ausncia de"garbage collection" ou coleta automtica de lixo.A sintaxe do destructor simples, ele tambm tem o mesmo nome da classes que precedido por ~ , ele no possui valor de retorno e o seu argumento void sempre:

    ~nomedaclasse(void) { /* Codigo do destrutor */ }

    O exemplo a seguir simples, porque melhorias e extenses sobre o temadestructores sero apresentadas ao longo do texto:Exemplo 8 ://destrutor de uma classe

    #include

  • //funcao membro comum, pode ser chamada pelo usuario

    ~contador(void){cout

  • automaticamente o destructor. Voltando ao bloco de cdigo de main(),minutos novamente incrementado. Finalizamos main(), agora, todas asvariveis declaradas em main() saem de escopo, mas antes o sistema chama osdestructores daquelas que os possuem.

    Encapsulamento com "Class"Encapsulamento, "data hiding". Neste tpico vamos falar das maneiras derestringir o acesso as declaraes de uma classe, isto feito em C++ atravsdo uso das palavras reservadas public, private e protected. Friends tambmrestringe o acesso a uma classe.

    No apresentaremos mais exemplos de classes declaradas com struct. Tudoque foi feito at agora pode ser feito com a palavra class ao envs de struct,incluindo pequenas modificaes. Mas porque usar s class nesse tutorial? Adiferena que os dados membro e funes membro de uma struct soacessveis por "default" fora da struct enquanto que os atributos e mtodos deuma classe no so, acessveis fora dela (main) por "default".Ento como controlar o acesso de atributos e mtodos numa classe? Simples,atravs das palavras reservadas private, public e protected.Protected est relacionada com herana, por agora vamos focalizar a nossaateno em private e public que qualificam os dados membro e funesmembro de uma classe quanto ao tipo de acesso ( onde eles so visveis ) .Public, private e protected podem ser vistos como qualificadores,"specifiers".

    Para facilitar a explicao suponha a seguintes declaraes equivalentes declasses:

    1)class ponto {

    float x; //dados membrofloat y;

    public: //qualificador

    void inicializa(float a, float b) {x=a; y=b;}; //funcao membro

  • void move(float dx, float dy) {x+=dx; y+=dy; };};

    a declarao 1 equivale totalmente :2)

    class ponto {private:

    float x;float y;

    public:

    //qualificadorvoid inicializa(float a, float b) {x=a; y=b;};void move(float dx, float dy) {x+=dx; y+=dy; };

    };

    que equivale totalmente :3)

    struct ponto {private://se eu nao colocar private eu perco o encapsulamento em struct.

    float x;float y;

    public:

    //qualificadorvoid inicializa(float a, float b) {x=a; y=b;};void move(float dx, float dy) {x+=dx; y+=dy; };

    };

  • Fica fcil entender essas declaraes se pensares no seguinte: essesqualificadores aplicam - se aos mtodos e atributos que vem aps eles, sehouver ento um outro qualificador, teremos agora um novo tipo de acessopara os mtodos declarados posteriormente.Mas ento porque as declaraes so equivalentes? porque o qualificadorprivate "default" para class, ou seja no especificares nada , at que se insiraum qualificador, tudo o que for declarado numa classe private. J em struct,o que default o qualificador public.Agora vamos entender o que private e o que public:Vamos supr que instanciaste ( criaste ) um objecto do tipo ponto em seuprograma:

    ponto meu; //instanciaoSegundo o uso de qualquer uma das definies da classe ponto dadas acimano podes escrever no teu programa:meu.x=5.0; //erro !

    ,como fazias antes, a no ser que x fosse declarado depois de public nadefinio da classe o que no ocorre aqui. Mas podes escrever x=5.0; naimplementao ( dentro ) de um mtodo porque enquanto no for feito usode herana, porque uma funo membro tem acesso a tudo o que de suaclasse, veja o programa seguinte.

    Voc pode escrever: meu.move(5.0,5.0); ,porque a declarao ( move ) est naparte public da classe. Aqui o leitor j percebe que podem existir funesmembro private tambm, e estas s so acessveis dentro do cdigo da classe(outras funes membro).Atributos Private, Funes Membro PublicAplicar encapsulamento a classe ponto definida anteriormente.

    Exemplo 9 :#include

  • class ponto{private: //nao precisaria por private, em class e default

    float x; //sao ocultos por defaultfloat y; //sao ocultos por default

    public: //daqui em diante tudo e acessivel.

    void inicializa(float a,float b) { x=a; y=b; }//as funcoes de uma classe podem acessar os atributos private dela mesma.

    void mostra(void) {cout

  • Alm disso fornecemos aqui a funo membro move, para que voc possatirar o ponto do lugar.

    Exemplo 10 :#include

  • ap.mostra();ap.move(1.0,1.0);ap.mostra();ap.y=100.0;ap.mostra();

    }

    Resultado do programa:X:0 , Y:0X:1 , Y:1X:1 , Y:100

    Comentrios: Observa que agora nada impede que acesses directamente y:ap.y=100.0, porm ap.x=10.00 um erro. Observa em que parte (rea) daclasse cada um desses dados membro foi declarado.

    Compilar um Programa com Vrios ArquivosNormalmente os programas C++ so divididos em arquivos para melhororganizao e encapsulamento, porm nada impede que o programador faaum programa num s arquivo. O programa exemplo da classe ponto depoderia ser dividido da seguinte forma:

    Exemplo 11 ://Arquivo 1 ponto.h, definicao para a classe ponto.

    class ponto{public: //daqui em diante tudo e acessivel.

    void inicializa(float a,float b);void mostra(void);

    private:

    float x; //sao ocultos por defaultfloat y; //sao ocultos por default

    };

  • //Arquivo 2 , ponto.cpp , implementacao para a classe ponto.

    #include

  • 3)Uma representao para ngulos na forma (Graus, Minutos, Segundos).Tambm com as operaes relacionadas, bem como as operaes paraconverter para radianos, entre outras.

    Tipo abstracto de dados um conceito muito importante em programaoorientada a objectos e por este motivo logo apresentado neste tutorial. Osexemplos seguintes so simples devido ao facto de no podermos usar todosos recursos C++ por razes didcticas. Devido a esta importncia, medidaem que formos introduzindo novos recursos exemplificaremos tambm comaplicaes na implementao tipos abstratos de dados.

    TAD FracoTipo abstraxto de dados frao. Baseado no conceito de nmero racional docampo da matemtica. Algumas operaes no foram implementadas porserem semelhantes s existentes. Por equanto no podemos fazer uso derecursos avanados como sobrecarga de operador e templates.Resumo das operaes matemticas envolvidas:Simplificao de fraco: (a/b)=( (a/mdc(a,b)) / (b/mdc(a,b)) )Onde mdc(a,b) retorna o mximo divisor comum de ab.Soma de frao: (a/b)+(c/d)=( (a.d+c.b) / b.d ) simplificada.Multiplicao de frao: (a/b) * (c/d)= ( (a*c) / (b*d) ) simplificada.Igualdade: (a/b)== (c/d) se a*d == b*c.

    No igualdade: (a/b) != (c/d) se a*d b*cMaior ou igual que: (a/b)(c/d) se a*d b*c

    Tpicos abordados: Constructores em geral, destructores, tipo long, criandomtodos de converso de tipos, mtodos chamando mtodos do mesmoobjecto, operador % que retorna o resto da diviso de dois inteiros.Exemplo 12 ://header file para o TAD fraco.

  • //File easyfra.h

    long mdc(long n,long d); //maximo divisor comum metodo de Euclides.

    class fraccao {

    private:

    long num; //numeradorlong den; //denominador

    public:

    fraccao(long t,long m); //constructor comumvoid simplifica(void); //diviso pelo mdc~fraccao() { /* nao faz nada*/ } //No preciso fazer nada.//operaes matemticas bsicasfraccao soma (fracao j);fracao multiplicacao(fracao j);

    //operaes de comparaoint igual(fraccao t);int diferente(fraccao t);int maiorouigual(fracao t);

    //operaes de input outputvoid mostra(void); //exibe fraco no videovoid cria(void); //pergunta ao utilizador o valor da fraco//operaes de converso de tiposdouble convertedbl(void); //converte para doublelong convertelng(void); //converte para long

    };

    //implementao para a classe fraco.#include

  • long mdc(long n,long d) //maximo divisor comum

    //metodo de Euclides +- 300 anos AC.{

    if (n

  • {fraccao g(num*j.num,den*j.den);return g;

    }

    int fraccao::igual(fraccao t){

    return ((num*t.den)==(den*t.num));//funcciona bem mesmo para no simplificada

    }

    int fraccao::diferente(fraccao t){

    return ((num*t.den)!=(den*t.num));}

    int fraccao::maiorouigual(fraccao t){

    return ((num*t.den)=(t.num*den));}

    void fraccao::mostra(void){

    cout

  • dbl=(double(num)/double(den));return dbl;

    }

    long fracao::convertelng(void) //conversao para long{

    long lng;

    lng=num/den;return lng;

    }

    #include

  • cout