Baixe no formato DOC, PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 246
TUTORIAL:
"C++ COMO UMA LINGUAGEM DE
PROGRAMAO ORIENTADA A OBJETOS." Copyright 1996 Andr Augusto Cesta. [email protected] Orientadora: Profa Dra Ceclia Mary Fiscer !ubira PROGRAMAO ORIENTADA A OBJETOS "ste tutorial se prop#e a ensinar programa$%o orientada a ob&etos em C''. A maioria dos li(ros n%o apresenta a linguagem nesse conte)to* dando uma aten$%o maior para os recursos de C'' do +ue para a metodologia de programa$%o. , recomend-(el +ue o leitor tena acesso a um desses li(ros (isto +ue n%o ensinaremos a+ui aspectos considerados b-sicos +ue s%o em geral +uase todos +ue permitem usar C'' como um C melorado. .oc/ pode usar C''* como uma linguagem procedural com recursos a(an$ados* mais uma (e0 n%o isso +ue pretendemos ensinar neste te)to. 1a pr-tica de programa$%o orientada a ob&etos estaremos atentos em nossos programas para pontos como: 2Compatibilidade* portabilidade. 23eguran$a. 2!eusabilidade. 2Facilidade de integra$%o. 2Facilidade de e)tens%o. 2"fici/ncia. Os t4picos seguintes nos guiar%o nesses ob&eti(os* mostrando numa cur(a de aprendi0ado sua(e* como programar usando orienta$%o a ob&etos em C''. 1. CLASSES E OBJETOS 5ma classe um tipo definido pelo usu-rio +ue contm o molde* a especifica$%o para os ob&etos* assim como o tipo inteiro contm o molde para as (ari-(eis declaradas como inteiros. A classe en(ol(e* associa* fun$#es e dados* controlando o acesso a estes* defin2la implica em especificar os seus atributos 6dados7 e suas fun$#es membro 6c4digo7. 5m programa +ue utili0a uma interface controladora de um motor eltrico pro(a(elmente definiria a classe motor. Os atributos desta classe seriam: temperatura* (elocidade* tens%o aplicada. "stes pro(a(elmente seriam representados na classe por tipos como float ou long . As fun$#es membro desta classe seriam fun$#es para alterar a (elocidade* ler a temperatura* etc. 5m programa editor de te)tos definiria a classe par-grafo +ue teria como um de seus atributos uma string ou um (etor de strings* e como fun$#es membro* fun$#es +ue operam sobre estas strings. 8uando um no(o par-grafo digitado no te)to* o editor cria a partir da classe par-grafo um ob&eto contendo as informa$#es particulares do no(o te)to. 9sto se cama instancia$%o ou cria$%o do ob&eto. Classes podem ser declaradas usando a pala(ra reser(ada struct ou a pala(ra reser(ada class* nos e)emplos posteriores entraremos em mais detales. As classes do pr4)imo t4pico :.; s%o declaradas com struct por ra0#es did-ticas. 8uando cegarmos em encapsulamento :.< mostraremos como declarar classes com class e n%o usaremos mais struct no tutorial. 1.1. ESPECIFICANDO UMA CLASSE 3upona um programa +ue controla um motor eltrico atra(s de uma sada serial. A (elocidade do motor proporcional a tens%o aplicada* e esta proporcional aos bits +ue (%o para sada serial e passando por um con(ersor digital anal4gico. .amos abstrair todos estes detales por en+uanto e modelar somente a interface do motor como uma classe* a pergunta +ue fun$#es e +ue dados membro de(e ter nossa classe* e +ue argumentos e (alores de retorno de(em ter essas fun$#es membro: !epresenta$%o da (elocidade: A (elocidade do motor ser- representada por um atributo* ou dado membro* inteiro 6int7. 5saremos a fai)a de bits +ue precisarmos* caso o (alor de bits necess-rio n%o possa ser fornecido pelo tipo * usaremos ent%o o tipo long * isto depende do con(ersor digital anal4gico utili0ado e do compilador. !epresenta$%o da sada serial: O motor precisa conecer a sua sada serial* a sua liga$%o com o =motor do mundo real=. 3upona uma representa$%o em e)adecimal do atributo endere$o de porta serial* um poss(el nome para o atributo: enderecomotor. 1%o se preocupe em saber como usar a representa$%o e)adecimal. Altera$%o do (alor da (elocidade: 9nternamente o usu-rio da classe motor pode dese&ar alterar a (elocidade* cria2se ent%o o mtodo 6 em C'' fun$%o membro7: void altera_velocidade(int novav); . O c4digo anterior corresponde ao cabe$alo da fun$%o membro* ela definida &unto com a classe motor* associada a ela. O (alor de retorno da fun$%o void 6(alor (a0io7* poderia ser criado um (alor de retorno (int) +ue indicasse se o (alor de (elocidade era permitido e foi alterado ou n%o era permitido e portanto n%o foi alterado. 1%o fa0 sentido usar* camar* esta fun$%o membro separada de uma (ari-(el do tipo motor* mas ent%o por+ue na lista de argumentos n%o se encontra um motor> "ste pensamento reflete a maneira de associar dados e c4digo 6fun$#es7 das linguagens procedurais. "m linguagens orientadas a ob&etos o c4digo e os dados s%o ligados de forma diferente* a pr4pria declara$%o de um tipo definido pelo usu-rio &- engloba as declara$#es das fun$#es inerentes a este tipo* isto ser- e)plicado em :.;.;. 1ote +ue n%o fornecemos o c4digo da fun$%o* isto n%o importante* por ora a preocupa$%o com a interface definida pela classe: suas fun$#es membro e dados membro. Apenas pense +ue sua interface de(e ser fle)(el de modo a n%o apresentar entra(es para a cria$%o do c4digo +ue seria feita numa outra etapa. 1esta etapa teramos +ue imaginar +ue o (alor numrico da (elocidade de(e ir para o con(ersor onde ir- se transformar numa diferen$a de potencial a ser aplicada nos terminais do motor* etc. 5m diagrama simplificado da classe motor com os dados membro e as fun$#es membro: Exercc!": :7?embre2se de algum programa em +ue (oc/ trabalou* cite +ue tipos de classes seriam criadas se esse programa fosse escrito em C''* +ue atributos e +ue fun$#es membro estariam associadas a esses ob&etos> ")emplo: ="u trabalei em um programa de contas a pagar e contas a receber. 3e esse programa fosse escrito em C'' eu definiria a classe conta@bancaria. Os atributos seriam: saldo, taxa_de_juros, liite_de_sa!ue, etc. Mina op$%o seria por represent-2los como (ari-(eis do tipo float" = =Dentre as fun$#es membros desta classe estariam fun$#es para efetuar sa+ues* dep4sitos e computar &uros.= 1.#. STRUCT EM C++ Ob&etos s%o instAncias de uma classe. 8uando um ob&eto criado ele precisa ser iniciali0ado* ou se&a para uma Bnica classe : "studante de gradua$%o podemos ter (-rios ob&etos num programa: "studante de gradua$%o Carlos* 9dentifica$%o CD:;:E* Curso Computa$%oF "studante de gradua$%o ?ui0a * 9dentifica$%o CD<;DC* Curso "ngenaria Ci(il... A classe representa somente o molde para a cria$%o dos ob&etos* estes sim contm informa$%o* (e&a t4pico classes e ob&etos. 1.#.1. ATRIBUTOS OU DADOS MEMBRO. "ste e)emplo declara uma struct e em seguida cria um ob&eto deste tipo em main alterando o conteBdo desta (ari-(el. 5ma struct parecida com um record de Pascal* a nossa representa um crculo com os atributos raio* posi$%o ) * posi$%o y* +ue s%o coordenadas cartesianas. 1ote +ue este ob&eto n%o possui fun$#es membro ainda. Ginclude Hiostream.I struct circulo JJstruct +ue representa um circulo. K float raioF float )F JJposicoes em coordenadas cartesianas float yF LF (oid main67 K circulo acF JJcriacao de (aria(el * (e&a comentarios. ac.raioM:N.NF JJmodificacao de conteudo 6atributos7 da struct ac.)M:.NF JJcolocando o circulo em uma posicao determinada ac.yM:.NF JJcolocando o circulo em uma posicao determinada cout HH =!aio:=HHac.raio HHendlF JJ(erificacao dos atributos alterados. cout HH =O:=HHac.) HH =Pn=F JJ =Pn=MMendl cout HH =Q:= HHac.yHH endlF L Re"$%&'(! (! )r!*r'+': !aio::N O:: Q:: C!+e,&-r!": struct circulo JJstruct +ue representa um circulo. K float raioF float )F JJposicoes em coordenadas cartesianas float yF LF "ste c4digo a declara$%o da classe crculo* entre ca(es (em os dados membro e as fun$#es membro +ue n%o foram apresentadas ainda. A sinta)e para cria$%o de ob&etos da classe crculo (circulo ac;) * por en+uanto n%o difere da sinta)e para a cria$%o de (ari-(eis do tipo int. O acesso aos dados membro de(e ser feito usando o nome do ob&eto e o nome do dado membro* separados por um ponto: ac"raio#1$"$; . 1ote +ue raio so0ino n%o fa0 sentido no programa* precisa2se especificar de +ue ob&eto se dese&a acessar o raio. A!" .$e )r!*r'+'+ e+ C: Os programadores C podem notar algo interessante: =C'' n%o re+uer a pala(ra struct na declara$%o da (ari-(el* ela se comporta como um tipo +ual+uer: int , float ...=. Outros programadores +ue n%o a(iam usado struct pre(iamente em C n%o se preocupem* fa$am apenas os e)erccios deste e)emplo e estar%o aptos a prosseguir. Exercc!": :7 !epita o mesmo e)emplo s4 +ue agora mo(a o crculo alterando as componentes ) e y. Pona o crculo em 6N.N*N.N7 atra(s de atribui$#es do tipo ac"x#1"$; mo(a o crculo para 6:.N*:.N7. Acompane todas as modifica$#es da struct atra(s de coutRs. ;73implifi+ue o programa anterior retirando o atributo raio. .oc/ pode dar o nome de ponto ou ponto@geometico para esta classe. 1.#.#. M/TODOS OU FUN0ES MEMBRO. C'' permite +ue se acrescente fun$#es de manipula$%o da struct em sua declara$%o* &untando tudo numa s4 entidade +ue uma classe. "ssas fun$#es membro podem ter sua declara$%o 6cabe$alo7 e implementa$%o 6c4digo7 dentro da struct ou s4 o cabe$alo 6assinatura7 na struct e a implementa$%o* c4digo* fora. "ste e)emplo apresenta a primeira (ers%o* o pr4)imo a segunda (ers%o 6implementa$%o fora da classe7. "ssas fun$#es comp#em a interface da classe. A terminologia usada para design-2las bastante (ariada: fun$#es membro* mtodos* etc. 8uando uma fun$%o membro camada* se di0 +ue o ob&eto est- recebendo uma mensagem 6para e)ecutar uma a$%o7. 5m programa simples para testes sobre fun$#es membro seria o seguinte: Ginclude Hiostream.I struct contador JJconta ocorrencias de algo K int numF JJnumero do contador (oid incrementa6(oid7KnumMnum':FLF JJincrementa contador (oid comeca6(oid7KnumMNFLF JJcomeca a contar LF (oid main67 JJteste do contador K contador umcontadorF umcontador.comeca67F JJnao es+ueca dos parenteses* e uma funcao membro e nao atributoS cout HH umcontador.num HH endlF umcontador.incrementa67F cout HH umcontador.num HH endlF L Re"$%&'(! (! )r!*r'+': N : C!+e,&-r!": O programa define um ob&eto +ue ser(e como contador* a implementa$%o representa a contagem no atributo num +ue um nBmero inteiro. As fun$#es membro s%o simples: increenta adiciona um ao contador em +ual+uer estado e comeca iniciali0a a contagem em 0ero. S,&'xe: A sinta)e para declara$%o de fun$#es membro dentro de uma classe a mesma sinta)e de declara$%o de fun$#es comuns : tipoderetorno noedafuncao(lista_de_arguentos) % &'codigo '& (. A diferen$a +ue como a fun$%o membro est- definida na classe* ela gano acesso direto aos dados membros* sem precisar usar o =ponto=* e)emplo u_o)jeto"dadoe)ro; . ?embre2se +ue as camadas de fun$#es membro &- se referem a um ob&eto especfico* embora elas se&am definidas de uma forma geral para toda a classe. A sinta)e de camada ou acesso T fun$#es membro semelante a sinta)e de acesso aos dados membro com e)ce$%o dos par/nteses +ue contm a lista de argumentos da fun$%o* mesmo +ue a lista se&a (a0ia eles de(em estar presentes: ucontador"increenta();" Primeiro insere2se o nome do ob&eto e depois a camada da fun$%o* estes s%o separados por um ponto. Cuidado para n%o es+uecer os par/nteses nas camadas de fun$#es membro em programas futuros* este um erro bastante comum. Agora o programa mais complicado* porm baseado no e)emplo :.;.:: Ginclude Hiostream.I JJpara cout struct circulo K float raioF float )F JJatributo coordenada cartesiana ) float yF JJatributo coordenada cartesiana y (oid mo(e6float d)*float dy7 JJfun$%o membro ou fun$%o membro mo(e K )'Md)F JJe+ui(ale a )M)'d)F y'MdyF L (oid mostra6(oid7 JJfun$%o membro ou fun$%o membro mostra K cout HH =!aio:=HHraio HHendlF cout HH =O:=HH) HH endlF cout HH =Q:= HHyHH endlF L LF (oid main67 K circulo acF JJ U instancia$%o de um ob&eto circulo 6criacao7 ac.)MN.NF ac.yMN.NF ac.raioM:N.NF ac.mostra67F ac.mo(e6:.N*:.N7F ac.mostra67F ac.)M:NN.NF ac.mostra67F L Re"$%&'(! (! )r!*r'+': !aio::N O:N Q:N !aio::N O:: Q:: !aio::N O::NN Q:: C!+e,&-r!": A fun$%o membro mo(e altera as coordenadas do ob&eto. O ob&eto tem suas coordenadas ) e y somadas com os argumentos dessa fun$%o membro. 1ote +ue esta fun$%o membro representa uma maneira mais segura* clara* elegante de alterar as coordenadas do ob&eto do +ue acess-2las diretamente da seguinte forma: ac"x*#dx;" ac"y*#dy;" ?embre2se +ue ac"x*#dx uma abre(ia$%o para ac"x#ac"x*dx; . C!+! 1$,c!,'+ ,! c!+)%'(!r '" c2'+'('" (e 1$,34e" +e+5r!: , poss(el imaginar +ue as defini$#es de fun$#es membro ocupam um grande espa$o na representa$%o interna dos ob&etos* mas lembre2se +ue elas s%o todas iguais para uma classe ent%o basta manter para cada classe uma tabela de fun$#es membro +ue consultada no momento da camada . Os ob&etos s4 precisam ter uma refer/ncia para esta tabela. Exercc!": :71este mesmo programa* crie uma fun$%o para a struct camada =iniciali0a= +ue de(e ter como argumentos um (alor para )* um para y e outro para o raio* e de(e alterar os atributos iniciali0ando2os com os (alores passados. .oc/ pode abstrair o uso dessa fun$%o como uma maneira de iniciali0ar o ob&eto de uma s4 (e0 embora a fun$%o o fa$a se+Vencialmente. Comente as (antagens de fa0/2lo* comparando com as outras op$#es* tena sempre em mente a +uest%o de seguran$a +uando a(aliar tcnicas diferentes de programa$%o. ;71o programa anterior* (erifi+ue +ue nada impede +ue (oc/ acesse diretamente os (alores de ) * y e raio e os modifi+ue. Como (oc/ pode criar um nBmero enorme de fun$#es : altera_x(float a); ove_raio(float dr); seria dese&-(el +ue somente essas fun$#es pudessem modificar )* y e raio. .oc/ (er- +ue isso poss(el em encapsulamento :.<. Por ora* crie essas fun$#es. <7Weste a fun$%o membro mo(e com argumentos negati(os* e)emplo ac"ove(+1"$,+ 1",);" O resultado coerente> D7Crie uma no(a struct +ue representa um ponto* +ue informa$#es (oc/ precisa arma0enar> 8ue fun$#es seriam Bteis > Fa$a um programa para testar sua classe. X7Melore a classe contador* defina uma fun$%o +ue imprime o contador na tela. 3e (oc/ esti(esse fa0endo um programa para rodar numa interface gr-fica com o usu-rio esta fun$%o de imprimir na tela seria a mesma> Definir uma fun$%o +ue retorna uma copia do (alor atual do contador garante maior portabilidade> Por +u/> Para aprender a retornar (alores consulte: :.;.<. Y7=Z- uma tend/ncia em definir o maior nBmero de fun$#es membro em uma classe* por+ue nunca se pode pre(er e)atamente o seu uso em programas futuros=. Comente esta frase* tendo em (ista o conceito de portabilidade. .oc/ &- capa0 de citar outras medidas +ue tornem suas classes mais port-(eis> ?eia o e)erccio anterior. 1.#.6. FUN0ES MEMBRO 7UE RETORNAM 8ALORES. At agora s4 tnamos (isto fun$#es membro com (alor de retorno igual a void" 5ma fun$%o membro* assim como uma fun$%o comum* pode retornar +ual+uer tipo* inclusi(e os definidos pelo usu-rio. 3endo assim* sua camada no programa se aplica a +ual+uer lugar onde se espera um tipo igual ou e+ui(alente ao tipo do seu (alor de retorno* se&a numa lista de argumentos de outra fun$%o * numa atribui$%o ou num operador como o cout -- variavel; Ginclude Hiostream.I struct contador JJconta ocorrencias de algo K int numF JJnumero* posicao do contador (oid incrementa6(oid7KnumMnum':FLF JJincrementa contador (oid comeca6(oid7KnumMNFLF JJcomeca a contar* =reset= int retorna@num6(oid7 Kreturn numFLF LF (oid main67 JJteste do contador K contador umcontadorF umcontador.comeca67F JJnao es+ueca dos parenteses* e uma funcao membro nao dadoS cout HH umcontador.retorna@num67 HH endlF umcontador.incrementa67F cout HH umcontador.retorna@num67 HH endlF L Re"$%&'(! (! )r!*r'+': N : 1.#.9. FUN0ES DECLARADAS E:TERNAS A CLASSE ; FUN0ES MEMBRO C<AMAMANDO FUN0ES MEMBRO. "ste e)emplo apresenta a implementa$%o* defini$%o* das fun$#es fora da declara$%o da struct. Alm disso introdu0 uma no(a fun$%o camada =iniciali0a= e fun$#es float retorna_raio(void); e void altera_raio(float a)" 9niciali0a coloca o ponto nas coordenadas passadas como seus argumentos. 9ntrodu0imos esta fun$%o membro a+ui para preparar a e)plica$%o sobre construtores dada no pr4)imo e)emplo: :.;.Y. C!+e,&-r!": "m uma declara$%o de uma classe normalmente se coloca a declara$%o das fun$#es membro depois da declara$%o dos atributos* porm podemos fa0er intercala$#es ou adotar +ual+uer ordem +ue nos con(ena. O programador n%o obrigado a implementar as fun$#es membro dentro da declara$%o da classe* basta defini2las e apresentar a implementa$%o em separado segundo a sinta)e 6compil-(el7 descrita a seguir: Ginclude Hiostream.I struct teste K int )F (oid altera@)6int (7F JJsomente definicao implementacao (em depois* fora da classe LF (oid teste::altera@)6int (7 K )M(FL JJesta &a e a implementacao codigo (oid main67 K teste aF JJinstaciacao de um ob&eto a.altera@)6:N7F JJcamada da funcao membro com (alor :N +ue sera impresso a seguir cout HH a.)F JJimprimindo o dado membro L Re"$%&'(! (! )r!*r'+' ',&er!r: :N Programa e)emplo crculo* mais comple)o baseado no e)emplo de 1.#.#: Ginclude Hiostream.I JJpara cout struct circulo K float raioF float )F float yF (oid iniciali0a6float a)*float by*float cr7F (oid altera@raio6float a7F float retorna@raio6(oid7F (oid mo(e6float d)*float dy7F (oid mostra6(oid7F LF (oid circulo::iniciali0a6float a)*float by*float cr7 K )Ma)F yMbyF raioMcrF L (oid circulo::altera@raio6float a7 K raioMaF L float circulo::retorna@raio6(oid7 K return raioF L (oid circulo::mo(e6float d)*float dy7 K )'Md)F y'MdyF L (oid circulo::mostra6(oid7 K cout HH =!aio:=HH retorna@raio67 HHendlF cout HH =O:=HH) HH endlF cout HH =Q:= HHyHH endlF L (oid main67 K circulo acF ac.iniciali0a6N.N*N.N*:N.N7F ac.mostra67F ac.mo(e6:.N*:.N7F ac.mostra67F ac.)M:NN.NF ac.altera@raio6:;.N7F ac.mostra67F L C!+e,&-r!": Obser(e +ue a fun$%o membro mostra cama a fun$%o membro float retorna_raio(void) +ue da mesma classe. Fica implcito da defini$%o de ostra +ue retorna_raio() se aplica ao mesmo ob&eto instanciado +ue recebeu a camada de mostra* ou se&a* n%o necess-rio usar o . na camada de retorna_raio(). "m programas maiores* camadas aninadas de fun$#es membro s%o bastante comuns. Pr!*r'+'3=! !re,&'(' ' !5>e&!" e ,&er1'ce" *r-1c'" c!+ ! $"$-r!: ")istem =libraries= de classes +ue permitem o programador C'' desen(ol(er aplica$#es para ambientes como o Microsoft [indo\sreg. de uma maneira bastante abstrata* este um e)emplo claro de reuso de c4digo* afinal o programador n%o precisa saber de detales da interface para programar nela. Re"$%&'(! (! )r!*r'+': !aio::N O:N Q:N !aio::N O:: Q:: !aio::;.N O::NN.N Q:: Exercc!": :79mplemente outras fun$#es do estilo (oid altera@raio6float a7 e float retorna@raio6(oid7 para os atributos O e Q. ;7Fa$a um programa simples para testar uma struct +ue representa um mouse e +ue contm a posi$%o na tela* os indicadores de estado dos bot#es e os fun$%o membros: clica_)otao.(void); ove(float dx, float dy);" 1%o preciso fa0er a liga$%o da struct com a entrada serial* embora o leitor interessado possa encontrar na literatura de C e)emplos de como fa0/2lo* esta uma tarefa complicada. 3eu mouse de(e ser capa0 de caminar para +ual+uer lugar da tela atra(s de camadas de fun$#es membro* n%o de(e ultrapassar os limites estabelecidos* e de(e indicar se os bot#es est%o pressionados ou n%o atra(s de uma fun$%o semelante a fun$%o ostra( ) deste e)emplo. O mouse pode ter de : a < bot#es. " (oc/ pode substituir a fun$%o membro ove(float dx,float dy) por ove_x(float dx); e ove_y(float dy); 1.#.?. ALGO PARECIDO EM UMA LINGUAGEM PROCEDURAL "ste t4pico apresenta uma compara$%o entre C'' e Pascal* para tal implementou2se dois programas semelantes. O programa C'' o programa crculo do t4pico anterior: :.;.D. O programa em Pascal (em a seguir: P!O]!AM ComparacaoF KCOMPA!ACAO COM 5M P!O]!AMA C''L WQP" CirculoM!"CO!D ):realF KCOO!D"1ADA3 O " QL y:realF r:realF Ksomente dadosL "1DF (ar ac:circuloF leitura:integerF P!OC"D5!" 9niciali0a6(ar altereme:CirculoFa)*by*cr:real7F KCO?OCA O C9!C5?O "M D"W"!M91ADA PO39CAOL ^"]91 altereme.):Ma)F altereme.y:MbyF altereme.r:McrF "1DF P!OC"D5!" Altera@!aio6(ar altereme:CirculoFar:real7F KA?W"!A O !A9O DO C9!C5?OL ^"]91 altereme.r:MarF "1DF F51CW9O1 !etorna@!aio6copieme:Circulo7:realF ^"]91 !etorna@!aio:Mcopieme.rF "1DF P!OC"D5!" Mo(e6(ar altereme:CirculoFd)*dy:real7F KMOD" A3 COO!D"1ADA3 O " Q AC!"3C"1WA1DO DO " DQL ^"]91 altereme.):Maltereme.)'d)F altereme.y:Maltereme.y'dyF "1DF P!OC"D5!" Mostra6copieme:Circulo7F KMO3W!A O C9!C5?O 1A W"?AL ^"]91 \riteln6RO:R*copieme.)*R Q:R*copieme.y*R !:R*copieme.r7F "1DF ^"]91 KW"3W"3L 9niciali0a6ac*N.N*N.N*:N.N7F Mostra6ac7F Mo(e6ac*:.N*:.N7F Mostra6ac7F ac.):M:NN.NF Altera@!aio6ac*:;.N7F Mostra6ac7F read6leitura7F "1D. Re"$%&'(! (! )r!*r'+': O: N.NNNNNNNNNN"'NN Q: N.NNNNNNNNNN"'NN !: :.NNNNNNNNNN"'N: O: :.NNNNNNNNNN"'NN Q: :.NNNNNNNNNN"'NN !: :.NNNNNNNNNN"'N: O: :.NNNNNNNNNN"'N; Q: :.NNNNNNNNNN"'NN !: :.;NNNNNNNNN"'N: C!+e,&-r!": C++: As classes em C'' englobam os dados membros e as fun$#es membros. Para e)ecutar uma a$%o sobre o ob&eto ou relati(a a este basta camar uma fun$%o membro para este: ac"ostra(); A fun$%o membro n%o precisa de muitos argumentos* por+ue pr4pria da classe e portanto gana acesso aos dados membro do ob&eto para ao +ual ela foi associada: float circulo//retorna_raio(void) K return r'!F JJteno acesso direto a raio. L P'"c'%: "m Pascal os procedimentos e os dados s%o criados de forma separada* mesmo +ue s4 tenam sentido &untos. A &un$%o entre os dados e procedimentos se d- atra(s de passagem de parAmetros. 1o caso de uma linguagem procedural como Pascal* o +ue normalmente feito se assemela ao c4digo seguinte: 0ove(ac,1"$,1"$); . Ac nesse caso um =record=* mas sem fun$#es membro* algo semelante ao struct de C 6n%o C''7. 0ove, acessa os dados do =record= alterando os campos. O parAmetro passado por refer/ncia e o procedimento definido a parte do registro* embora s4 sir(a para aceitar argumentos do tipo Circulo e mo(er suas coordenadas. Se*$r',3': "m ambos programas 6Pascal* C''7 o programador pode acessar diretamente os dados do tipo definido pelo usu-rio: ac"x:#1$$"$; 6Pascal7 ou ac"x#1$$"$; (C**)" .eremos em :.< ENCAPSULAMENTO maneiras de proibir em C'' este tipo de acesso direto ao dado membro* dei)ando este ser modificado somente pelas fun$#es membro. 9sto nos garante maior seguran$a e liberdade pois podemos permitir ou n%o o acesso para cada dado membro de acordo com nossa (ontade. E1c@,c': Algum pode argumentar +ue programas +ue usam bastante camadas de fun$#es podem se tornar pouco eficientes e +ue poderia ser melor acessar diretamente os dados de um tipo definido pelo usu-rio ao en(s de passar por todo o trabalo de c4pia de argumentos* inser$%o da fun$%o no pila* etc. "m (erdade n%o se perde muito em efici/ncia* e alm disso muitas (e0es n%o se dese&a permitir sempre o acesso direto aos dados de um tipo definido pelo usu-rio por ra0#es de seguran$a. 1esse sentido C'' oferece um recurso +ue permite ganos em seguran$a sem perder muito em efici/ncia* (e&a: :.X.;. Exercc!": :7.erifi+ue +ue em main67 (oc/ pode modificar o atributo x do ob&eto da classe ponto ou crculo da seguinte forma: a"x#11"1; . 9sto pode n%o ser muito Btil* imagine2se criando uma library +ue implementa a classe ponto e uma srie de fun$#es relacionadas* por ra0#es de seguran$a (oc/ gostaria +ue o usu-rio se limitasse ao uso da interface 6fun$#es membro7 do ob&eto* como fa0/2lo ser- e)plicado em :.< encapsulamento. Por ora* apenas crie fun$#es +ue a&udem a e(itar este tipo de acesso direto. 1.#.A. CONSTRUTORES Construtores s%o fun$#es membro especiais camadas pelo sistema no momento da cria$%o de um ob&eto. "las n%o possuem (alor de retorno* por+ue (oc/ n%o pode camar um construtor para um ob&eto. Contrutores representam uma oportunidade de iniciali0ar de forma organi0ada os ob&etos* imagine se (oc/ es+uece de iniciali0ar corretamente ou o fa0 duas (e0es* etc. 5m construtor tem sempre o mesmo nome da classe e n%o pode ser camado pelo usu-rio desta. Para uma classe string o construtor teria a forma string(char' a); com o argumento char' especificado pelo programador. "le seria camado automaticamente no momento da cria$%o* declara$%o de uma string: string a6=We)to=7F JJalocacao estatica implica na camada do construtor a.mostra67F JJcamada de metodos estatica. ")istem (aria$#es sobre o tema +ue (eremos mais tarde: 3obrecarga de construtor* =copy constructor=* como conseguir construtores (irtuais 6a(an$ado* n%o apresentado neste te)to7 * construtor de corpo (a0io. O e)emplo a seguir simples* semelante aos anteriores* preste aten$%o na fun$%o membro com o mesmo nome +ue a classe (struct) * este o construtor: Ginclude Hiostream.I struct ponto K float )F float yF public: ponto6float a*float b7F JJesse e o contrutor* note a ausencia do (alor de retorno (oid mostra6(oid7F (oid mo(e6float d)*float dy7F LF ponto::ponto6float a*float b7 JJconstrutor tem sempre o nome da classe. K )MaF JJinciali0ando atributos da classe yMbF JJcolocando a casa em ordem L (oid ponto::mostra6(oid7 Kcout HH =O:= HH ) HH = * Q:= HH y HH endlFL (oid ponto::mo(e6float d)*float dy7 K )'Md)F y'MdyF L (oid main67 K ponto ap6N.N*N.N7F ap.mostra67F ap.mo(e6:.N*:.N7F ap.mostra67F L Re"$%&'(! (! )r!*r'+': O:N * Q:N O:: * Q:: C!+e,&-r!": Dei)aremos para nos aprofundarmos em aloca$%o dinAmica e construtores em :.X.<. Por ora (oc/ pode se ater ao uso est-tico de ob&etos. 1ote +ue com a defini$%o do construtor* (oc/ obrigado a passar os argumentos deste no momento da cria$%o do ob&eto. 3e (oc/ precisa ter a op$%o de n%o passar esses (alores* as poss(eis solu$#es ser%o dadas em <. Exercc!": :7.oc/ sabia +ue uma fun$%o membro pode camar outra fun$%o membro> Parta do e)emplo de :.;.D e crie um construtor +ue cama a antiga fun$%o iniciali2a(float a,float )) passando os argumentos do construtor: ponto6float a* float b7 K iniciali0a6a*b7F L 1a camada de iniciali2a()fica implcito +ue ela se aplica ao ob&eto cu&o construtor foi camado. 9sto (-lido tambm para outras fun$#es membro +ue camam fun$#es membro* ou se&a* n%o necess-rio o operador identificador"iniciali2a(a,)); * (e&a :.;.<. "ste e)erccio Btil para mostrar outro recurso de C''* o ponteiro this" 3his uma pala(ra reser(ada e dentro de +ual+uer fun$%o membro this um ponteiro para o ob&eto em +uest%o* ent%o o c4digo descrito acima poderia tambm assumir a seguinte forma e+ui(alente: ponto6float a* float b7 K tis2Iiniciali0a6a*b7F L JJ.erifi+ueS , l4gico +ue neste e)emplo tis n%o tem muita utilidade* mas e)istem casos onde um ob&eto precisa passar seu ponteiro para alguma fun$%o +ue o modifica* ou fica possuindo uma refer/ncia para ele* ent%o usa2se tis. .eremos outras aplica$#es mais adiante. ;7 9ntrodu0a mensagens no construtor tipo: cout -- 45)jeto instanciado"4; introdu0a tambm trecos no seu programa parecidos com: cin 66 a; * s4 para +ue o programa n%o rode todo de uma (e0* rapidamente. O ob&eti(o acompanar (isualmente a se+V/ncia de cria$%o e modifica$%o dos ob&etos. <7Crie uma classe reta +ue tem como atributos dois ob&etos da classe ponto. Dica: N=! $"e c!,"&r$&!re"* use fun$#es do tipo iniciali2a(), &- apresentadas. 8uando seu programa ficar pronto acrescente fun$%o membros para esta reta tais como inclina$%o* coeficiente linear* etc. Para acrescentar construtores leia :.;._. ")istem maneiras mais eficientes e compactas de representar uma reta* porm fa$a como foi sugerido* neste caso o ob&eti(o n%o efici/ncia. 1.#.B. CONSTRUTORES E AGREGAO O programa e)emplo deste t4pico cria uma classe reta com dois dados membro da classe ponto este e)emplo o resultado do e)erccio anterior* com um recurso a mais de C''. C'' permite +ue no construtor da classe reta* (oc/ came os construtores dos atributos da classe ponto, se (oc/ n%o o fi0er o compilador acusar- um erro* pois os atributos ponto possuem construtores e eles precisam ser camados para +ue a iniciali0a$%o se complete de modo correto para o con&unto. Obser(e o c4digo do construtor da classe reta usado no e)emplo: reta6float ):*float y:*float );*float y;7:p:6):*y:7*p;6);*y;7 K JJnada mais a fa0er* os construtores de p: e p; &a foram camados L p:6):*y:7 e p;6);*y;7 s%o as camadas dos construtores da classe ponto* elas de(em ficar fora do corpo KL do construtor* nesta lista separada por (rgulas (oc/ de(e iniciali0ar todos os atributos. Os tipos b-sicos como int* float* etc )!(e+ ser iniciali0ados nessa lista. Por e)emplo se a classe reta ti(esse um atributo inteiro de nome identifica$%o* a lista poderia ser da seguinte forma: reta6float ):*float y:*float );*float y;7:p:6):*y:7*p;6);*y;7*identificacao6:N7 K JJnada mais a fa0er* os construtores de p: e p; &a foram camados L seria como se identifica$%o ti(esse um construtor +ue tem como argumento seu (alor. ou reta6float ):*float y:*float );*float y;7:p:6):*y:7*p;6);*y;7 K identificacaoM:NF JJtambem pode* por+ue tipos b-sicos 6int7 em C'' n%o s%o ob&etos JJ portanto nao tem construtores L 5ma outra alternati(a seria usar aloca$%o dinAmica para os atributos pontos +ue passariam a ser agora ponteiros para pontos* dei)aremos para discutir este t4pico mais tarde em :.X.<* mas saiba +ue nesse caso o construtor da classe reta n%o precisaria criar os pontos. .amos ao e)emplo* +ue no(amente semelante aos anteriores* para +ue o leitor preste aten$%o somente nas mudan$as* +ue s%o os conceitos no(os* sem ter +ue se esfor$ar muito para entender o programa: Ginclude Hiostream.I struct ponto K float )F float yF JJcoordenadas ponto6float a*float b7 K )MaF yMbF L JJconstrutor (oid mo(e6float d)*float dy7 K )'Md)F y'MdyF L JJfuncao membro comum (oid iniciali0a6float a*float b7 K )MaF yMbF L (oid mostra6(oid7 Kcout HH =O:= HH ) HH = * Q:= HH y HH endlFL LF struct reta K ponto p:F ponto p;F reta6float ):*float y:*float );*float y;7:p:6):*y:7*p;6);*y;7 K JJnada mais a fa0er* os contrutores de p: e p; &a foram camados L (oid mostra6(oid7F LF (oid reta::mostra6(oid7 K p:.mostra67F p;.mostra67F L (oid main67 K reta r:6:.N*:.N*:N.N*:N.N7F JJinstanciacao da reta r: r:.mostra67F L Re"$%&'(! (! )r!*r'+': O:: * Q:: O::N * Q::N Exercc!": :7 9mplemente um programa +ue use a mesma l4gica do e)emplo anterior para criar uma classe composta de outras . .oc/ estar- usando agrega$%o. Por e)emplo um triAngulo precisa de tr/s pontos para ser definido. ;75ma implementa$%o mais eficiente da classe reta seria feita arma0enando apenas um coeficiente angular e um linear* mas esta reta de(eria ent%o pro(er um construtor +ue aceitasse dois pontos como argumentos. Como (oc/ n%o aprendeu sobrecarga de construtores 6definir (-rios construtores7* use s4 um construtor +ue tem coeficiente angular e linear como argumentos e implemente esta no(a classe reta sem usar agrega$%o agora. <7Defina uma fun$%o membro para a classe reta +ue retorna o ponto de intercess%o com outra reta: ponto reta//intercessao(reta a);" 1%o se es+ue$a de tratar os casos degenerados* tais como retas paralelas e coincidentes* use por e)emplo mensagens de erro. .erifi+ue +ue uma fun$%o membro de uma reta recebe outra reta 6mesmo tipo7 como argumento. Dentro da fun$%o membro os dados membro do argumento a de(em ser acessados do seguinte modo: a"p1"x; Mais tarde* em D.X tratamento de e)ce$#es* (eremos maneiras melores de lidar com esses casos degenerados. D7Defina uma fun$%o membro camada ove para a classe reta* lembre2se de mo(er os dois pontos &untos 6a inclina$%o n%o de(e mudar7. Y7Defina uma fun$%o membro void gira(tipox angulo); para a classe reta. "sta fun$%o membro recebe um Angulo como argumento* (oc/ pode optar por representar o Angulo em radianos 6float7 ou criar a classe Angulo 6graus* minutos* segundos7. !esol(a tambm o problema da escola do ponto em torno do +ual a reta de(e ser girada. 5se fun$#es matem-ticas 6seno cosseno7 da library -ath"h6" 1.#.C. DESTRUTORES. An-logos aos construtores* os destrutores tambm s%o fun$#es membro camadas pelo sistema* s4 +ue elas s%o camadas +uando o ob&eto sai de escopo ou em aloca$%o dinAmica* tem seu ponteiro desalocado* ambas 6construtor e destrutor7 n%o possuem (alor de retorno. .oc/ n%o pode camar o destrutor* o +ue (oc/ fa0 fornecer ao compilador o c4digo a ser e)ecutado +uando o ob&eto destrudo* apagado. Ao contr-rio dos construtores* os destrutores n%o tem argumentos. Os destrutores s%o muito Bteis para =limpar a casa= +uando um ob&eto dei)a de ser usado* no escopo de uma fun$%o em +ue foi criado* ou mesmo num bloco de c4digo. 8uando usados em con&unto com aloca$%o dinAmica eles fornecem uma maneira muito pr-tica e segura de organi0ar o uso do =eap=. A importAncia dos destrutores em C'' aumentada pela aus/ncia de =garbage collection= ou coleta autom-tica de li)o. A sinta)e do destrutor simples* ele tambm tem o mesmo nome da classe s4 +ue precedido por 7 * ele n%o possui (alor de retorno e seu argumento (oid sempre: `nomedaclasse6(oid7 K JU Codigo do destrutor UJ L O e)emplo a seguir simples* por+ue melorias e e)tens#es sobre o tema destrutores ser%o apresentadas ao longo do te)to: JJdestrutor de uma classe Ginclude Hiostream.I struct contadorK int numF contador6int n7 KnumMnFL JJconstrutor (oid incrementa6(oid7 Knum'M:FL JJfuncao membro comum* pode ser camada pelo usuario `contador6(oid7 Kcout HH =Contador destruido* (alor:= HH num HHendlFL JJdestrutor LF (oid main67 K contador minutos6N7F minutos.incrementa67F cout HH minutos.num HH endlF K JJinicio de no(o bloco de codigo contador segundos6:N7F segundos.incrementa67F cout HH segundos.num HHendlF JJfim de no(o bloco de codigo L minutos.incrementa67F L Re"$%&'(! (! )r!*r'+': : :: Contador destruido* (alor::: Contador destruido* (alor:; C!+e,&-r!": 1o escopo de ain criado o contador minutos com (alor inicialMMN. 0inutos incrementado* agora inutos"nu##1" O (alor de nu em minutos impresso na tela. 5m no(o bloco de c4digo criado. 8egundos criado* instanciado como uma (ari-(el deste bloco de c4digo* o (alor inicial de segundos :N* para n%o confundir com o ob&eto &- criado. 8egundos incrementado atingindo o (alor ::. O (alor de segundos impresso na tela. Finali0amos o bloco de c4digo em +ue foi criado segundos* agora ele sai de escopo* apagado* mas antes o sistema cama automaticamente o destrutor. .oltando ao bloco de c4digo de ain(), minutos no(amente incrementado. Finali0amos main67* agora* todas as (ari-(eis declaradas em ain()saem de escopo* mas antes o sistema cama os destrutores da+uelas +ue os possuem. 1.6. ENCAPSULAMENTO COM "CLASS" "ncapsulamento* =data iding=. 1este t4pico (amos falar das maneiras de restringir o acesso as declara$#es de uma classe* isto feito em C'' atra(s do uso das pala(ras reser(adas pu)lic, private e protected" 9riends tambm restringe o acesso a uma classe e apresentado em D.:. Considera$#es sobre C'':CONSIDERAES C++::.X* apresenta tambm um recurso de C'' para declarar ob&etos constantes e proteger argumentos de camadas de mtodos +ue possam modific-2los* usando const :.X.:. 1%o mais apresentaremos e)emplos de classes declaradas com struct" Wudo +ue foi feito at agora pode ser feito com a pala(ra class ao en(s de struct, incluindo pe+uenas modifica$#es. Mas por+ue usar s4 class nesse tutorial> A diferen$a +ue os dados membro e fun$#es membro de uma struct s%o acess(eis por =default= fora da struct en+uanto +ue os atributos e mtodos de uma classe n%o s%o* acess(eis fora dela (ain) por =default=. .oc/ nem de(e ter se preocupado com isso por+ue usando struct da forma como us-(amos* tudo fica(a acess(el. "nt%o como controlar o acesso de atributos e mtodos em uma classe> 3imples* atra(s das pala(ras reser(adas private, pu)lic e protected. :rotected ser- e)plicada em ;.: pois est- relacionada com eran$a* por ora (amos focali0ar nossa aten$%o em private e pu)lic +ue +ualificam os dados membro e fun$#es membro de uma classe +uanto ao tipo de acesso 6onde eles s%o (is(eis7 . :u)lic, private e protected podem ser (istos como +ualificadores* =specifiers=. Para facilitar a e)plica$%o supona a seguintes declara$#es e.$D'%e,&e" de classes: :7 class ponto E float x; &&dados e)ro float y; )$5%c: &&!ualificador void iniciali2a(float a, float )) %x#a; y#);(; &&funcao e)ro void ove(float dx, float dy) %x*#dx; y*#dy; (; FF a declara$%o : e+ui(ale totalmente T: ;7 class ponto E )rD'&e: float x; float y; )$5%c: &&!ualificador void iniciali2a(float a, float )) %x#a; y#);(; void ove(float dx, float dy) %x*#dx; y*#dy; (; FF +ue e+ui(ale totalmente T: <7 struct ponto E )rD'&e: &&se eu nao colocar private eu perco o encapsulaento e struct" float x; float y; )$5%c: &&!ualificador void iniciali2a(float a, float )) %x#a; y#);(; void ove(float dx, float dy) %x*#dx; y*#dy; (; FF Fica f-cil entender essas declara$#es se (oc/ pensar no seguinte: esses +ualificadores se aplicam aos mtodos e atributos +ue (em ap4s eles* se ou(er ent%o um outro +ualificador* teremos agora um no(o tipo de acesso para os mtodos declarados posteriormente. Mas ent%o por+ue as declara$#es s%o e+ui(alentes> , por+ue o +ualificador private =default= para class* ou se&a se (oc/ n%o especificar nada * at +ue se insira um +ualificador* tudo o +ue for declarado numa classe pri(ate. a- em struct* o +ue default o +ualificador pu)lic" Agora (amos entender o +ue pri(ate e o +ue public: .amos supor +ue (oc/ instanciou 6criou7 um ob&eto do tipo ponto em seu programa: ponto meuF JJinstanciacao 3egundo o uso de +ual+uer uma das defini$#es da classe ponto dadas acima (oc/ ,=! pode escre(er no seu programa: meu.)MX.NF JJerr! G *como fa0amos nos e)emplos de :.; * a n%o ser +ue ) fosse declarado depois de pu)lic na defini$%o da classe o +ue n%o ocorre a+ui. Mas (oc/ pode escre(er x#,"$; na implementa$%o 6dentro7 de um mtodo por+ue en+uanto n%o for feito uso de eran$a* por+ue uma fun$%o membro tem acesso a tudo +ue de sua classe* (e&a o programa seguinte. .oc/ pode escre(er: eu"ove(,"$,,"$); *por+ue sua declara$%o (ove) est- na parte pu)lic da classe. A+ui o leitor &- percebe +ue podem e)istir fun$#es membro private tambm* e estas s4 s%o acess(eis dentro do c4digo da classe 6outras fun$#es membro7. .isibilidade das declara$#es de uma classe* fora dela e de sua ierar+uia. .e&a +ue s4 a parte pu)lic (is(el neste caso: .isibilidade das declara$#es de uma classe* dentro dela mesma: Exercc!": :7 8ual das seguintes declara$#es permite +ue se acesse em main "!+e,&e os mtodos ove e iniciali2a* encapsulando todos os outros elementos da classe> Obs.: A ordem das -reas private e pu)lic pode estar in(ertida com rela$%o aos e)emplos anteriores. a7 "&r$c& ponto E JJse eu nao colocar pri(ate eu perco o encapsulamento em struct. float )F float yF )$5%c: JJ+ualificador (oid iniciali0a6float a* float b7 K)MaF yMbFLF (oid mo(e6float d)* float dy7 F K)'Md)F y'MdyF LF FF b7 class ponto E )$5%c: JJ+ualificador (oid iniciali0a6float a* float b7 K)MaF yMbFLF (oid mo(e6float d)* float dy7 F K)'Md)F y'MdyF LF )rD'&e: float )F float yF FF c7 class ponto E )$5%c: JJ+ualificador (oid iniciali0a6float a* float b7 K)MaF yMbFLF JJfuncao membro (oid mo(e6float d)* float dy7 F K)'Md)F y'MdyF LF float )F JJdados membro float yF FF 1.6.1. ATRIBUTOS PRIVATE, FUN0ES MEMBRO PUBLIC Aplicando encapsulamento a classe ponto definida anteriormente. Ginclude Hiostream.I class ponto K pri(ate: JJnao precisaria por pri(ate* em class e default float )F JJsao ocultos por default float yF JJsao ocultos por default public: JJda+ui em diante tudo e acessi(el. (oid iniciali0a6float a*float b7 K )MaF yMbF L JJas funcoes de uma classe podem acessar os atributos pri(ate dela mesma. (oid mostra6(oid7 Kcout HH =O:= HH ) HH = * Q:= HH y HH endlFL LF (oid main67 K ponto apF JJinstanciacao ap.iniciali0a6N.N*N.N7F JJmetodos public ap.mostra67F JJmetodos public L Re"$%&'(! (! )r!*r'+': O:N * Q:N C!+e,&-r!": "ste programa n%o dei)a (oc/ tirar o ponto de ($,$) a n%o ser +ue se&a camada iniciali2a no(amente. Fica claro +ue agora* encapsulando x e y precisamos de mais mtodos para +ue a classe n%o tena sua funcionalidade limitada. 1o(amente: escre(er ap"x#1$; em main um erroS Pois x est- +ualificada como private. ?eia os e)erccios. Exercc!": :7 9mplemente os mtodos void altera_x(float a) , float retorna_x(void), void ove (float dx,float dy ); .9mplemente outros mtodos +ue acar importantes e)emplo void distancia(ponto a) % return dist(;,<,a";,a"<); (, onde dist representa o con&unto de opera$#es matem-ticas necess-rias para obter a distAncia entre (;,<) (a";,a"<)" .oc/ pro(a(elmente usar- a funcao s!r() da =library= -ath"h6 +ue define a rai0 +uadrada de um float" .e&a +ue no mtodo distancia* podemos acessar os dados membro O e Q do argumento a* isto permitido por+ue distancia uma fun$%o membro da mesma classe de a* embora n%o do mesmo ob&eto* uma maneira de pro(er este tipo de acesso para outras classes dotar a classe ponto de mtodos do tipo float retorna_x(void);" 9riends D.: um t4pico a(an$ado sobre encapsulamento +ue lida com (isibilidade entre classes distintas. 8uando (oc/ precisar de outras fun$#es matem-ticas 6seno* coseno7* lembre2se da =library= -ath"h6, s4 pes+uisar o manual do compilador ou usar a&uda sens(el ao conte)to para Hmat.I ou at mesmo dar uma oladina na interface dela* no diret4rio das =libraries=* alias essa uma boa maneira de aprender sobre como implementa2las. ;7 !etorne ao incio deste t4pico e releia as defini$#es e+ui(alentes de classes declaradas com struct e com class" !efa$a o programa e)emplo anterior usando struct, use encapsulamento em outros programas +ue (oc/ implementou. 1.6.#. UM DADO MEMBRO / PUBLIC "ste programa uma (ariante do anterior* a Bnica diferen$a +ue Q colocado na parte pu)lic da defini$%o da classe e acessado diretamente. Alm disso fornecemos a+ui a fun$%o membro ove* para +ue (oc/ possa tirar o ponto do lugar. Ginclude Hiostream.I class ponto K float )F JJsao ocultos por default public: JJda+ui em diante tudo e acessi(el. ponto6float a*float b7F JJconstrutor tambem pode ser inline ou nao (oid mostra6(oid7F (oid mo(e6float d)*float dy7F float yF JJU Q nao eR mais ocultado LF ponto::ponto6float a*float b7 K )MaF yMbF L (oid ponto::mostra6(oid7 Kcout HH =O:= HH ) HH = * Q:= HH y HH endlFL (oid ponto::mo(e6float d)*float dy7 K )'Md)F y'MdyF L (oid main67 K ponto ap6N.N*N.N7F ap.mostra67F ap.mo(e6:.N*:.N7F ap.mostra67F ap.yM:NN.NF ap.mostra67F L Re"$%&'(! (! )r!*r'+': O:N * Q:N O:: * Q:: O:: * Q::NN C!+e,&-r!": Obser(e +ue agora nada impede +ue (oc/ acesse diretamente y: ap"y#1$$"$* porm ap"x#1$"$$ um erro. Obser(e em +ue parte 6-rea7 da classe cada um desses dados membro foi declarado. Exercc!": :7Crie os mtodos float retorna_x(void), void altera_x(float a); +ue de(em ser(ir para retornar o (alor arma0enado em x e para alterar o (alor arma0enado em x respecti(amente. Crie tambm as respecti(as fun$#es retorna e altera para todos os outros atributos. 1.6.6. COMPILANDO UM PROGRAMA COM 8HRIOS AR7UI8OS. Compilando um programa di(idido em (-rios ar+ui(os. 1ormalmente os programas C' ' s%o di(ididos em ar+ui(os para melor organi0a$%o e encapsulamento* porm nada impede +ue o programador fa$a seu programa em um s4 ar+ui(o. O programa e)emplo da classe ponto de :.<.: poderia ser di(idido da seguinte forma: JJAr+ui(o : ponto.* definicao para a classe ponto. class ponto K public: JJda+ui em diante tudo e acessi(el. (oid iniciali0a6float a*float b7F (oid mostra6(oid7F pri(ate: float )F JJsao ocultos por default float yF JJsao ocultos por default LF JJAr+ui(o ; * ponto.cpp * implementacao para a classe ponto. Ginclude Hiostream.I Ginclude =ponto.= (oid ponto::iniciali0a6float a*float b7 K )MaF yMbF L JJas funcoes de uma classe podem acessar os atributos pri(ate dela mesma. (oid ponto::mostra6(oid7 Kcout HH =O:= HH ) HH = * Q:= HH y HH endlFL JJAr+ui(o < . Programa principal: princ.cpp Ginclude =ponto.= (oid main67 K ponto apF JJinstanciacao ap.iniciali0a6N.N*N.N7F JJmetodos public ap.mostra67F JJmetodos public L Os ar+ui(os com e)tens%o . indicam eader files. , costume dei)ar nesses ar+ui(os somente a interface das classes e fun$#es para +ue o usu-rio possa ol-2lo* como numa =library=. 1ote +ue a parte pu)lic da classe foi colocada antes da parte private* isto por+ue normalmente essa parte da defini$%o da classe +ue interessa para o leitor. 1o nosso caso o Bnico ar+ui(o beaderR 6.7 +ue temos o 4ponto"h4 +ue define a classe ponto" Caso as dimens#es de seu programa permitam* opte por separar cada classe em um beader fileR* ou cada grupo de entidades 6fun$#es* classes7 relacionadas. O ar+ui(o ; =ponto.cpp= um ar+ui(o de implementa$%o. "le tem o mesmo nome do ar+ui(o 4ponto"h4 * embora isto n%o se&a obrigat4rio. , mais organi0ado ir formando pares de ar+ui(os =eader J implementation=. "ste ar+ui(o fornece o c4digo para as opera$#es da classe ponto* da a declara$%o: =include 4ponto"h4" As aspas indicam +ue se trata de um ar+ui(o criado pelo usu-rio e n%o uma =library= da linguagem como -iostrea"h6, portanto o diret4rio onde se de(e encontrar o ar+ui(o diferente do diret4rio onde se encontra -iostrea"h6" O ar+ui(o < 4princ"cpp4 o ar+ui(o principal do programa* n%o costume relacionar seu nome com nomes de outros ar+ui(os como no caso do ar+ui(o ; e o ar+ui(o :. Obser(e +ue o ar+ui(o < tambm declara =include 4ponto"h4, isto por+ue ele fa0 uso das dos tipos definidos em 4ponto"h4 * porm 4princ"cpp4 n%o precisa declarar =include -iostrea"h6 por+ue este n%o usa diretamente as defini$#es de iostrea em nenum momento* caso 4princ"cpp4 o fi0esse* o include -iostrea6 seria necess-rio. O leitor encontrar- em alguns dos e)emplos seguintes as direti(as de compila$%o. 8uando da elabora$%o de uma library para ser usada por outros programadores* n%o se es+ue$a de us-2las: Gifndef M?93WZ@Z Gdefine M?93WZ@Z JJCodigo Gendif Gifndef M?93WZ@Z Gdefine M?93WZ@Z JJdefina a+ui seu eader file. JJperceba +ue =1omear+.= e escrito na direti(a como 1OM"A!8@Z Gendif "ssas direti(as ser(em para e(itar +ue um eader file se&a includo mais de uma (e0 no mesmo pro&eto. O seu uso se d- da seguinte forma: Diagrama sugest%o para organi0a$%o de programas relati(amente simples: 3aber compilar programas di(ididos em (-rios ar+ui(os muito importante. 9sto re+uer um certo esfor$o por parte do programador* por+ue os mtodos podem (ariar de plataforma para plataforma. Pergunte para um programador e)periente de seu grupo. 3e o seu compilador de lina de comando* pro(a(elmente (oc/ poder- compilar programas di(ididos em (-rios ar+ui(os usando macefiles. a- se seu compilador opera num ambiente gr-fico* esta tarefa pode en(ol(er a cria$%o de um pro&eto. 1.9. TIPO ABSTRATO DE DADOS Wipo abstrato de dados* WAD* se preocupa em proporcionar uma abstra$%o sobre uma estrutura de dados em termos de uma interface bem definida. 3%o importantes os aspectos de encapsulamento* +ue mantm a integridade do ob&eto e(itando acessos inesperados* e o fato de o c4digo estar arma0enado em um s4 lugar o +ue cria um programa modific-(el* leg(el* coeso. 5ma classe implementa um tipo abstrato de dados. 3%o e)emplos de tipos abstratos de dados: :7 5ma -r(ore bin-ria com as opera$#es usuais de inser$%o* remo$%o* busca ... ;75ma representa$%o para nBmeros racionais 6numerador* denominador7 +ue possua as opera$#es aritmticas b-sicas e outras de con(ers%o de tipos. <75ma representa$%o para Angulos na forma 6]raus* Minutos* 3egundos7. Wambm com as opera$#es relacionadas* bem como as opera$#es para con(erter para radianos* entre outras. Wipo abstrato de dados um conceito muito importante em programa$%o orientada a ob&eto e por este moti(o logo apresentado neste tutorial. Os e)emplos seguintes s%o simples de(ido ao fato de n%o podermos usar todos os recursos C'' por ra0#es did-ticas. De(ido a esta importAncia* a medida em +ue formos introdu0indo no(os recursos e)emplificaremos tambm com aplica$#es na implementa$%o tipos abstratos de dados. 1.9.1. TAD FRAO Wipo abstrato de dados fra$%o. ^aseado no conceito de nBmero racional do campo da matem-tica. Algumas opera$#es n%o foram implementadas por serem semelantes Ts e)istentes. O e)emplo mais completo se encontra em D.:.;. Por ora n%o podemos fa0er uso de recursos a(an$ados como sobrecarga de operador e templates. !esumo das opera$#es matem-ticas en(ol(idas: 3implifica$%o de fra$%o: 6aJb7M6 6aJmdc6a*b77 J 6bJmdc6a*b77 7 Onde mdc6a*b7 retorna o m-)imo di(isor comum de ab. 3oma de fra$%o: 6aJb7'6cJd7M6 6a.d'c.b7 J b.d 7 simplificada. Multiplica$%o de fra$%o: 6aJb7 U 6cJd7M 6 6aUc7 J 6bUd7 7 simplificada. 9gualdade: 6aJb7MM 6cJd7 se aUd MM bUc. 1%o igualdade: 6aJb7 SM 6cJd7 se aUd bUc Maior ou igual +ue: 6aJb76cJd7 se aUd bUc TI)c!" '5!r('(!": Construtores em geral* destrutores* tipo long, criando mtodos de con(ers%o de tipos* mtodos camando mtodos do mesmo ob&eto* operador d +ue retorna o resto da di(is%o de dois inteiros. JJeader file para o WAD fracao. JJFile easyfra. long mdc6long n*long d7F JJma)imo di(isor comum metodo de "uclides. class fracao K pri(ate: long numF JJnumerador long denF JJdenominador public: fracao6long t*long m7F JJconstrutor comum (oid simplifica6(oid7F JJdi(isao pelo mdc `fracao67 K JU nao fa0 nadaUJ L JJ1ao e preciso fa0er nada. JJoperacoes matematicas basicas fracao soma 6fracao &7F fracao multiplicacao6fracao &7F JJoperacoes de comparacao int igual6fracao t7F int diferente6fracao t7F int maiorouigual6fracao t7F JJoperacoes de input output (oid mostra6(oid7F JJe)ibe fracao no (ideo (oid cria6(oid7F JJpergunta ao usuario o (alor da fracao JJoperacoes de con(ersao de tipos double con(ertedbl6(oid7F JJcon(erte para double long con(ertelng6(oid7F JJcon(erte para long LF JJimplementacao para a classe fracao. Ginclude Hiostream.I Ginclude =easyfra.= long mdc6long n*long d7 JJma)imo di(isor comum JJmetodo de "uclides '2 <NN anos AC. K if 6nHN7 nM2nF if 6dHN7 dM2dF \ile 6dSMN7 K long rMn d dF JJdMMODM!esto da di(isao inteira. nMdF dMrF L return nF L (oid fracao::simplifica6(oid7 K long commdF commdMmdc6num*den7F JJdi(isor comum numMnumJcommdF denMdenJcommdF if 6denHN7 K denM2denF numM2numFLF JJmo(e sinal para cima L fracao::fracao6long t*long m7 K numM6t7F denM6m7F simplifica67F JJcamada para o mesmo ob&eto. L fracao fracao::soma6fracao &7 K fracao g66numU&.den7'6&.numUden7*denU&.den7F return gF L fracao fracao::multiplicacao6fracao &7 K fracao g6numU&.num*denU&.den7F return gF L int fracao::igual6fracao t7 K return 66numUt.den7MM6denUt.num77F JJfunciona bem mesmo para nao simplificada L int fracao::diferente6fracao t7 K return 66numUt.den7SM6denUt.num77F L int fracao::maiorouigual6fracao t7 K return 66numUt.den7IM6t.numUden77F L (oid fracao::mostra6(oid7 K cout HH =6= HH num HH =J= HH den HH =7=F L (oid fracao::cria6(oid7 K cout HH =1umerador:=F cin II numF cout HH =Denominador:=F cin II denF simplifica67F L double fracao::con(ertedbl6(oid7 K double dblF dblM6double6num7Jdouble6den77F return dblF L JJcon(ersao para long long fracao::con(ertelng6(oid7 K long lngF lngMnumJdenF return lngF L Ginclude Hiostream.I Ginclude =easyfra.= JJnossa definicao da classe Ginclude Hstdio.I main67 K fracao a6N*:7*b6N*:7F cout HH = "ntre com fracao a: =F a.cria67F a.mostra67F cout HH = "ntre com fracao b: =F b.cria67F b.mostra67F fracao c6a.soma6b77F JJc6a'b7 cout HH endl HH =c de a'b:=F c.mostra67F cout HH endl HH =aUb=F cMa.multiplicacao6b7F c.mostra67F cout HH endl HH =a'b=F cMa.soma6b7F c.mostra67F cout HH endl HH =aIMb=F cout HH a.maiorouigual6b7F cout HH endl HH =aMMb=F cout HH a.igual6b7F cout HH endl HH =aSMb=F cout HH a.diferente6b7F cout HH endl HH =long6a7 =F cout HH a.con(ertelng67F cout HH endl HH =double6a7 =F cout HH a.con(ertedbl67F return NF L C!+e,&-r!": Obser(e o seguinte c4digo usado no programa: fracao c(a"soa()));" O resultado de a"soa()) uma fra$%o* mas n%o criamos um construtor +ue recebe uma fra$%o como argumento* como isso foi poss(el no programa> 3imples* a linguagem oferece para as classes +ue (oc/ cria a c4pia bit a bit. Cuidado com o uso dessa c4pia em con&unto com aloca$%o dinAmica* ob&etos poder%o ter c4pias iguais de ponteiros* ou se&a compartilar uso de posi$#es na mem4ria. De +ual+uer forma* em N e)plicaremos como redefinir esta c4pia de modo a e(itar situa$#es indese&-(eis como a c4pia de ponteiros e em :.X.< e)plicaremos melor os perigos de usar este tipo de c4pia em con&unto com aloca$%o dinAmica. Re"$%&'(! (! )r!*r'+': "ntre com fracao a: 1umerador:D Denominador:; 6;J:7 "ntre com fracao b: 1umerador:X Denominador:< 6XJ<7 c de a'b:6::J<7 aUb6:NJ<7 a'b6::J<7 aIMb: aMMbN aSMb: long6a7 ; double6a7 ; Exercc!": :7 Modifi+ue o tipo fra$%o para aceitar as seguintes fun$#es membro. long retorna@num6(oid7 Kreturn numFL long altera@den6float a7 K denMaFL Considerando +ue os atributos declarados em private n%o s%o acess(eis fora da classe* descre(a a utilidade dessas fun$#es. "les s%o Bteis se usadas pelas pr4prias fun$#es membro de fra$%o> U;7 9mplemente o tipo abstrato de dados nBmero comple)o com as opera$#es matem-ticas inerentes. Fa$a antes um pro&eto das fun$#es membro +ue ser%o implementadas descre(endo tambm as opera$#es matem-ticas necess-rias. U<7 Outro tipo abstrato de dados e)tremamente Btil o tipo abstrato de dados string +ue de(e fornecer: copy constructor* opera$#es de compara$%o 6 ordem le)icogr-fica 7* concatena$%o* substring * entre outras. 9mplemente este tipo abstrato de dados* tendo em mente a seguinte pergunta: =.oc/ poderia substituir um tipo fracao ou inteiro usado em uma rotina de ordenacao pela sua implementa$%o de string sem fa0er grandes modifica$#es>=. "ssa pergunta final ser- muito importante +uando come$armos a discutir templates D.<. D7Continue trabalando no WAD fra$%o* implemente os mtodos restantes 6menor +ue* subtra$%o7 de modo an-logo Ts implementa$#es fornecidas. X7Pes+uise sobre matri0es em C''. Crie um tipo abstrato de dados matri0 +ue suporte atribui$#es e leituras de clulas contendo elementos do tipo float. Crie outros mtodos para este tipo abstrato de dados como multiplica$%o por uma constante. 1.?. CONSIDERA0ES C++: 1este t4pico iremos e)plicar recursos mais particulares de C''* porm n%o menos importantes para a programa$%o orientada a ob&etos na linguagem. Alguns recursos como const +ue est- relacionado com encapsulamento poder%o ser retirados deste t4pico em no(as (ers#es do tutorial. 1.?.1. CONST "ste e)emplo mostra o uso de fun$#es const e sua importAncia para o encapsulamento. Const pode +ualificar um parAmetro de fun$%o 6assegurando +ue este n%o ser- modificado7* uma fun$%o membro 6assegurando +ue esta n%o modifica os dados membro de sua classe7* ou uma instAncia de ob&etoJtipo 6assegurando +ue este n%o ser- modificado.7 Os modos de +ualifica$%o descritos atuam em con&unto* para assegurar +ue um ob&eto const n%o ser- modificado* C'' s4 permite +ue se&am camados para este ob&eto fun$#es membro +ualificadas como const" Const tambm um +ualificador* =specifier=. Ginclude Hiostream.I Ginclude Hmat.I JJdouble s+rt6double )7F de mat. retorna rai0 +uadrada do numero JJdouble po\6double )* double y7F de mat. calcula ) a potencia de y const float e"!OMN.NF class ponto K pri(ate: float )F JJsao ocultos por default nao precisaria pri(ate mas eR bom float yF JJsao ocultos por default public: JJda+ui em diante tudo e acessi(el em main. ponto6float a*float b7 K )MaF yMbF L (oid mostra6(oid7 const Kcout HH =O:= HH ) HH = * Q:= HH y HH endlFL float distancia6const ponto i7 const K return float6 s+rt6 6 po\6double6i.)2)7*;.N7 ' po\6double6i.y2y7*;.N7 7 7 7F JJteorema de Pitagoras L LF (oid main67 K ponto ap6<.N*D.N7F JJinstanciacao ap.mostra67F JJfuncoes membro public const ponto origem6e"!O*e"!O7F JJdefino ob&eto constante origem.mostra67F cout HH =Distancia da origem:= HH origem.distancia6ap7F L Re"$%&'(! (! )r!*r'+': O:< * Q:D O:N * Q:N Distancia da origem:X C!+e,&-r!": Const +ualificando instAncias de ob&etosJtipos: const ponto origem6e"!O*e"!O7F const float e"!OMN.NF Const +ualificando fun$#es: float distancia6const ponto i7 c!,"&F Const +ualificando argumentos: float distancia6c!,"& ponto i7 constF Exercc!": :75se tudo o +ue (oc/ aprendeu sobre const na classe reta* definida em CO13W!5WO!"3 " A]!"]AfgO :.;._. 1.?.#. FUN0ES INLINE Re.$"&!": 3aber como um programa se comporta na mem4ria* em termos de camadas de fun$%o e gerenciamento da pila* =stacc=. O +ue s%o fun$#es inline: 9magine uma camada de uma fun$%o membro (oid altera@raio6float a7 da classe circulo &- apresentada* ac"altera_raio(a)" "sta camada en(ol(e a passagem de parAmetros* inser$%o da fun$%o na pila 6stacc7* retorno de um (alor (void), tudo isso representa uma diminui$%o da (elocidade do programa com rela$%o a um simples: ac"raio#a; +ue nesse caso funcionaria muito bem. Ocorre +ue n4s dese&amos usar camadas de mtodos* (imos inclusi(e meios de esconder* encapsular o atributo raio para +ue a Bnica alternati(a para alterar seu (alor se&a atra(s da camada de altera_raio(a)" Por+ue programar desta forma> Por+ue mais seguro* mais pr4)imo dos princpios de orienta$%o a ob&etos. "m (erdade POO se caracteri0a por muitas camadas de mtodos e uso do =eap=* -rea de mem4ria usada pela aloca$%o dinAmica. O +ue as fun$#es declaradas como inline fa0em tradu0ir a camada do mtodo em tempo de compila$%o em um e+ui(alente ac"raio#1>"$" e(itando todo o contratempo descrito. "ssa tradu$%o do mtodo colocada na se+u/ncia de c4digo do programa* (oc/ pode ter (-rios trecos +ue camariam fun$#es* des(iariam o flu)o do programa at o retorno desta* con(ertidos em instru$#es simples. Como des(antagem temos o aumento do tamano do programa* (isto +ue passar%o a e)istir (-rias c4pias diferentes da fun$%o no programa 6uma para cada argumento7 ao en(s de um s4 prot4tipo de fun$%o +ue era colocado na pila no momento da camada e ent%o tina os argumentos substitudos. 1os programa anteriores sobre a classe crculo* se a fun$%o membro mostra fosse inline a(eria uma con(ers%o da camada interna 6dentro de mostra7 de retorna_raio()em simplesmente ac"raio" Pode a(er con(ers%o de (-rias fun$#es inline aninadas* estas con(ers#es s%o seguras* por+ue s%o feitas pelo compilador. 1ormalmente (anta&oso usar inline para fun$#es pe+uenas +ue n%o aumentem muito o tamano do programa ou fun$#es onde (elocidade crucial. A+ui (ale a conecida regra EN:;N* oitenta porcento do tempo do programa gasto em (inte por cento dos mtodos. Porm o programador n%o precisa se preocupar muito com fun$#es inline na fase de desen(ol(imento* este um recurso C'' para aumento de efici/ncia +ue pode muito bem ser dei)ado para o final do pro&eto. 3aiba porm +ue as diferen$as de tempo decorrentes de seu uso s%o sens(eis. "ste e)emplo e)plora as possibilidades +ue temos para declarar fun$#es membro e como declar-2las para +ue se&am do tipo inline/ Ginclude Hiostream.I struct ponto K float )F float yF (oid iniciali0a6float a*float b7 K )MaF yMbF L JJApesar de nao especificado compilador tenta JJe)pandir camada da funcao como inline por+ue esta dentro da definicao da classe. (oid mostra6(oid7F JJcom certe0a nao eR inline* e)terna a classe e sem +ualificador. inline (oid mo(e6float d)*float dy7F JJeR inline * prototipo* definicao LF (oid ponto::mostra6(oid7 Kcout HH =O:= HH ) HH = * Q:= HH y HH endlFL inline (oid ponto::mo(e6float d)*float dy7 JJimplementacao* codigo K )'Md)F y'MdyF L (oid main67 K ponto apF ap.iniciali0a6N.N*N.N7F ap.mostra67F ap.mo(e6:.N*:.N7F ap.mostra67F ap.)M:NN.NF ap.mostra67F L C!+e,&-r!": O compilador tenta con(erter a fun$%o iniciali2a em inline, embora n%o este&a especificado com a pala(ra reser(ada inline +ue isto para ser feito. "sta uma regra* sempre +ue a fun$%o esti(er definida na pr4pria classe (struct%() o compilador tentar- con(ert/2la em inline" Foi dito +ue o compilador tenta por+ue isto pode (ariar de compilador para compilador* se ele n%o consegue con(erter em inline * de(ido a comple)idade da fun$%o* (oc/ normalmente a(isado* tendo +ue trocar o lugar da defini$%o da fun$%o membro. 1ote +ue se a fun$%o membro implementada fora da classe* tanto o prot4tipo da fun$%o membro* +uanto a implementa$%o de(em (ir especificados com inline para +ue a con(ers%o ocorra. Re"$%&'(! (! )r!*r'+': O:N * Q:N O:: * Q:: O::NN * Q:: 1.?.6. ALOCAO DINJMICA COM NEK E DELETE. 1este t4pico ser%o apresentados os recursos de C'' para aloca$%o dinAmica de (ari-(eis de tipos simples e ob&etos* ou se&a* estudaremos a aloca$%o de estruturas em tempo de e)ecu$%o. 1.?.6.1. PONTEIROS; "POINTERS" "ste e)emplo mostra como trabalar com ponteiros para (ari-(eis de tipos pr2definidos 6n%o definidos pelo usu-rio7 usando ne? e delete" O programa a seguir cria um ponteiro para uma (ari-(el inteira* aloca mem4ria para esta (ari-(el e imprime seu (alor. Ginclude Hiostream.I (oid main67 K intU aF JJdeclara um ponteiro para endereco de (aria(el inteira aMne\ int6<7F JJaloca memoria para o apontado por a* gra(ando neste o (alor < cout HH 6Ua7 HH endl F JJimprime o (alor do apontado por a delete aF JJdesaloca memoria L Re"$%&'(! (! )r!*r'+': < @iagraa das variAveis na eBria/ C!+e,&-r!": 3e a fosse uma struct ou class e ti(esse um dado membro camado dd* poderamos obter o (alor de dd atra(s de ('a)"dd +ue pode ser todo abre(iado em a+6dd onde +6 uma seta* ou fleca +ue (oc/ pode ler como =o apontado= no(amente. Os par/nteses em ('a)"dd s%o necess-rios de(ido a preced/ncia do operador . com rela$%o ao '. "sta sinta)e abre(iada ser- bastante usada +uando alocarmos dinamicamente ob&etos. O5"erD'3=!: intU aF aMne\ int6<7F pode ser abre(iado por: intU aMne\ int6<7F 1.?.6.#. 8ETORES CRIADOS ESTATICAMENTE O e)emplo a seguir aloca estaticamente* em tempo de compila$%o* um (etor de inteiros com tr/s posi$#es. "m seguida* gra(amos as tr/s posi$#es e as mostramos na tela: Ginclude Hiostream.I (oid main67 K int ah<iF JJaloca o (etor de tamano <* estaticamente ahNiM:F JJatribui a posicao indice N do (etor ah:iM;F JJatribui ; a posicao indice : do (etor ah;iM<F JJatribui < a posicao indice ; do (etor cout HH ahNi HH = = HH ah:i HH = = HH ah;i HH endlF JJmostra o (etor L Re"$%&'(! (! )r!*r'+': : ; < Re"$+! (' ",&'xe (e De&!re": int ah<iF JJcria um (etor de inteiros a com tres posicoes* indices uteis de N ate ; float bhCiF JJcria um (etor de float b com no(e posicoes* indices uteis de N ate E bhEiM<.:D:XY;CXF JJgra(a <.:D:X... na ultima posicao do (etor b if 6bhXiMM;.:_7 K JUacaoUJL F JJteste de igualdade D'*r'+' (! De&!r: Perceba +ue a fai)a Btil do (etor (ai de N at 6n2:7 onde n o (alor dado como tamano do (etor no momento de sua cria$%o* no nosso caso <. 1ada impede +ue (oc/ gra(e ou leia ndices fora dessa -rea Btil* isso muito perigoso* por+ue fora dessa -rea* o +ue (oc/ tem s%o outras (ari-(eis de mem4ria e n%o o espa$o reser(ado para seu (etor. , perfeitamente aceit-(el* embora desastroso escre(er em nosso programa aCDE#F;" O compilador calcula o endere$o de mem4ria da posi$%o D com base na posi$%o inicial do (etor e o tamano do tipo alocado. Ap4s calculado o endere$o da posi$%o D o (alor < copiado* apagando o conteBdo anteriorS C!+e,&-r!": 1ote +ue n%o estamos usando ponteiros neste e)emplo e por isso +ue o (etor alocado estaticamente* em tempo de compila$%o* tambm por este moti(o +ue o argumento +ue (ai no lugar do < no c4digo int aCFE; de(e ser uma e)press%o constante e n%o uma (ari-(el. 1.?.6.6. COPIA DE OBJETOS COM 8ETORES ALOCADOS ESTATICAMENTE. 1o primeiro e)emplo do WAD fra$%o (imos +ue o compilador fornece c4pia bit a bit para ob&etos* alertamos tambm sobre o perigo de usar este tipo de c4pia em con&unto com aloca$%o dinAmica. O e)emplo seguinte mostra um caso onde esta c4pia oferecida pelo compilador segura* o t4pico seguinte :.X.<.D mostra um caso onde esta c4pia n%o segura* leia ambos para ter uma (is%o geral do assunto: Ginclude Hiostream.I class (etor@tres K public: int (eth<iF JJ(etor alocado estaticamente numa classe. (etor@tres6int a*int b*int c7 K (ethNiMaF (eth:iMbF (eth;iMcF L JJconstrutor do (etor (oid mostra6(oid7 K cout HH (ethNi HH = = HH (eth:i HH = = HH (eth;i HH endlFL JJfuncao membro para mostrar o conteudo do (etor LF (oid main67 K (etor@tres (:6:*;*<7F JJcriacao de um ob&eto (etor. (etor@tres (;6:X*:Y*:_7F JJcriacao de um ob&eto (etor. (:.mostra67F JJmostrando o conteudo de (:. (;.mostra67F JJmostrando o conteudo de (;. (;M(:F JJatribuindo ob&eto (: ao ob&eto (;. (;.mostra67F JJmostrando (; alterado. (:.(ethNiMDDF (:.mostra67F JJmostrando o conteudo de (:. (;.mostra67F JJmostrando o conteudo de (;. L Re"$%&'(! (! )r!*r'+': : ; < :X :Y :_ : ; < DD ; < : ; < C!+e,&-r!": Perceba +ue no caso de aloca$%o est-tica* +uando o tamano do (etor conecido em tempo de compila$%o a c4pia segura. Por c4pia segura entenda: as posi$#es do (etor s%o copiadas uma a uma e os ob&etos n%o ficam fa0endo refer/ncia a um mesmo (etor* isto pode ser (isto no resultado do programa* +uando alteramos a c4pia de v1, v1 n%o se altera. 1.?.6.9. 8ETORES CRIADOS DINAMICAMENTE O e)emplo a seguir an-logo ao de :.X.<.;* mas os (etores s%o alocados dinamicamente* ou se&a* (oc/ determina em tempo de e)ecu$%o +ual o tamano do (etor* Pascal n%o permite isso. Ginclude Hiostream.I (oid main67 K int tamanoF JJarma0ena o tamano do (etor a criar. intU (etF JJponteiro para inteiro ou (etor de inteiro ainda nao criado cout HH ="ntre com o tamano do (etor a criar=F cin II tamanoF (etMne\ inthtamanoiF JJalocando (etor de =tamano= posicoes comecando em ahNi for 6int iMNFiHtamanoFi''7 K cout HH ="ntre com o (alor da posicao = HH i HH =:=F cin II (ethiiF cout HH endlF L JJloop de leitura no (etor for 6int &MNF&HtamanoF&''7 K cout HH =Posicao = HH & HH =:= HH (eth&iHHendlF L JJloop de impressao do (etor L Re"$%&'(! (! )r!*r'+': "ntre com o tamano do (etor a criar< "ntre com o (alor da posicao N:: "ntre com o (alor da posicao ::; "ntre com o (alor da posicao ;:< Posicao N:: Posicao ::; Posicao ;:< C!+e,&-r!": intU aF Declara um ponteiro para inteiro. aMne\ inth:NiF Diferente de ne? int(1$); os colcetes indicam +ue para ser criado um (etor de tamano :N e n%o uma (ari-(el de (alor :N como em :.X.<.:. Ao contr-rio de aloca$%o est-tica* o parAmetro +ue (ai no lugar do (alor :N n%o precisa ser uma e)press%o constante. intU aF aMne\ inth:NiF e+ui(ale a forma abre(iada: intU aMne\ inth:NiF A fai)a de ndices Bteis do (etor no(amente (ai de N at 6:N2:7 ou 6n2:7. 1.?.6.?. COPIA DE OBJETOS COM 8ETORES ALOCADOS DINAMICAMENTE. "ssa determina$%o do tamano do (etor em tempo de e)ecu$%o (ai tornar a c4pia de ob&etos feita pelo compilador diferente* ele (ai copiar o ponteiro para o (etor* ou se&a os ob&etos passam a compartilar a estrutura na mem4ria* o +ue nem sempre pode ser dese&-(elS ")istem maneiras de redefinir esta c4pia feita pelo compilador o +ue (eremos em N. Ginclude Hiostream.I class (etor@tres K public: intU (etF JJ(etor alocado estaticamente numa classe. (etor@tres6int a*int b*int c7 K (etMne\ inth<iF (ethNiMaF (eth:iMbF (eth;iMcF L JJconstrutor do (etor (oid mostra6(oid7 K cout HH (ethNi HH = = HH (eth:i HH = = HH (eth;i HH endlFL JJfuncao membro para mostrar o conteudo do (etor LF (oid main67 K (etor@tres (:6:*;*<7F JJcriacao de um ob&eto (etor. (etor@tres (;6:X*:Y*:_7F JJcriacao de um ob&eto (etor. (:.mostra67F JJmostrando o conteudo de (:. (;.mostra67F JJmostrando o conteudo de (;. (;M(:F JJatribuindo ob&eto (: ao ob&eto (;. (;.mostra67F JJmostrando (; alterado. (:.(ethNiMDDF (:.mostra67F JJmostrando o conteudo de (:. (;.mostra67F JJmostrando o conteudo de (;. L Re"$%&'(! (! )r!*r'+': : ; < :X :Y :_ : ; < DD ; < DD ; < C!+e,&-r!": 1ote +ue +uando alteramos a c4pia de (:* (: se altera. 9sto ocorre por+ue o (etor n%o copiado casa a casa como em :.X.<.<* s4 se copia o ponteiro para a posi$%o inicial do (etor* a partir do +ual se calcula os endere$os das posi$#es seguintes vCFE##'(v*F)" 3obre o te)to acima: =a partir do +ual se calcula os endere$os das posi$#es seguintes=* (e&a o programa e)emplo: Ginclude Hiostream.I (oid main67 K intU (F (Mne\ inth<iF cout HH U6(':7HHendlF JJimprime o li)o contido na memoria de (h:i cout HH (h:i HHendlF JJimprime o li)o contido na memoria de (h:i JJU6(7MM(hNi uma e)pressao sempre (erdadeira L Re"$%&'(! (! )r!*r'+': :X; :X; C!+e,&-r!": O +ue importante deste e)erccio +ue s4 se arma0ena a posi$%o inicial do (etor* as outras posi$#es s%o calculadas com base no tamano do tipo alocado e regras de aritmtica de ponteiros. 1%o podemos nos estender muito neste tema* leia sobre aritmtica de ponteiros* porm para este tutorial* basta usar os (etores de forma +ue esta aritmtica fi+ue por conta da linguagem. .etores alocados dinamicamente e ponteiros s%o a mesma coisa* isto pode ser (isto nesse programa e)emplo +ue mistura a sinta)e de (etores e de ponteiros. 1.?.6.A. TAD E ALOCAO DINJMICA. Wipo abstrato de dados (etor. 5m dos grandes problemas de trabalar com (etores comuns de C'' ( int ' a; a#ne? intC1$E; aC11E#F; ) +ue fre+Ventemente lemos ndices in(-lidos* ou pior gra(amos encima deles. ]ra(ar encima de um ndice fora dos limites de um (etor um erro fre+Vente em programa$%o C''. 3aiba +ue fa0endo isso (oc/ pode estar apagando instru$#es de outros programas na mem4ria e outras informa$#es importantesS "m alguns casos +uando isso ocorre obtm2se inclusi(e mensagens do sistema operacional a(isando +ue algo est- errado e +ue necess-rio reiniciali0ar a m-+uina. C$r!"('(e: Zou(e um caso de (rus na internet +ue se basea(a no acesso a ndices fora de um (etor para gra(ar por cima de instru$#es do sistema operacional* c4digo +ue garantisse a sua multiplica$%o. Algumas linguagens de programa$%o como Pascal e M4dula2< cecam os ndices para +ue n%o se acesse -reas in(-lidas de um (etor. M4dula2< fornece inclusi(e os limites dos (etores simples da linguagem atra(s de camadas last(vetor) ou first(vetor) . "m C'' tal tipo de cecagem pode ser implementada pelo programador como faremos neste e)emplo. Dc' (e Pr!*r'+'3=!: ?embre2se: seu sucesso em programa$%o (ai depender em muito de sua disciplina e organi0a$%o tena sempre em mente +ue C'' uma linguagem poderosa e +ue se n%o usada corretamente pode criar transtornos e erros n%o percept(eis em testes do programa. 1%o cecar os ndices de um (etor em programas grandes como instalar uma bomba rel4gio em seu c4digo* muito pro(-(el +ue em algum instante (oc/ ou at mesmo outra pessoa usando seu programa se distraia e acabe por escre(er uma rotina +ue acessa um ndice in(-lido de um (etor* fa0endo na maioria das (e0es o programa falar. A proposta deste e)emplo criar um tipo abstrato de dados (etor com uma interface fle)(el +ue sir(a para (-rias aplica$#es e possa ser facilmente estendida. "ste e)emplo simples e (ai ser reapresentado com muitas melorias no decorrer do tutorial* dentre elas: =templates= D.<* =e)ception andling= D.X* e a cria$%o de uma classe iterador para o (etorD.: . A primeira (ista (oc/ pode acar +ue este programa n%o oferece muito mais +ue o uso comum de (etores em C''* mas com as melorias +ue apresentaremos* certamente (oc/ (ai preferir representar (etores como tipos abstratos de dados ou WADRs. JJfile e)(et:. JJeader file para classe (etor const int inicioMNF class (etorK pri(ate: intU (F JJeste eR o (etor int tamanoF JJtamano ma)imo do (etor* public: (etor 6int tam7F JJconstrutor* aloca mem4ria para o (etor. (oid atribui6int inde)*int (alor7F JJaltera uma posicao do (etor int conteudo6int inde)7F JJretorna conteudo de posicao do (etor int ma)imo6(oid7F JJretorna o maior elemento do (etor int primeiro6(oid7F JJprimeiro indice do (etor int ultimo6(oid7F JJultimo indice do (etor `(etor67 Kdelete (FL JJinline function ou use delete (hiF LF JJcodigo* implementacao* para o eader file Ginclude Hiostream.I Ginclude Hstdlib.I Ginclude =e)(et:.= (etor::(etor 6int tam7 K(Mne\ inthtamiF tamanoMtamFL (oid (etor::atribui6int inde)*int (alor7 K if 6inde)Htamano jj inde)IMinicio7 (hinde)iM(alorF L int (etor::conteudo6int inde)7 K if 6inde)IMtamano kk inde)Hinicio7 Kcerr HH =Fora dos limites=F e)it6:7FL return (hinde)iF L int (etor::primeiro6(oid7 K return inicioFL int (etor::ultimo6(oid7 K return tamano2:FL int (etor:: ma)imo6(oid7 Kint candidatoMinicioF JJcandidato ao ma)imo for 6int iMinicioFiHtamanoFi''7 if 6(hiiI(hcandidatoi7 candidatoMiF return (hcandidatoiFL JJprograma pricipal Ginclude Hiostream.I Ginclude =e)(et:.= main67 K int au)F JJpara ler (alor a atribuir (etor meu6X7F for 6int iMmeu.primeiro67FiHMmeu.ultimo67Fi''7 K cout HH ="ntre com (alor da posicao:= HH i HH =Pn=F cin II au)F meu.atribui6i*au)7F L for 6int &Mmeu.primeiro67F&HMmeu.ultimo67F&''7 coutHH meu.conteudo6&7HH = =F cout HHendl HH =Ma)imo:= HH meu.ma)imo67F return NF L C!+e,&-r!": O mtodo `(etor67 Kdelete (FL JJuse delete hi(Fdepende do compilador um destrutor* assim como o construtor ele n%o tem (alor de retorno por+ue camado pelo sistema operacional +uando o ob&eto sai de escopo ou +uando (oc/ desaloca mem4ria de um ponteiro para o ob&eto. A Bnica a$%o do destrutor liberar a mem4ria ocupada pelo atributo (etor de inteiros (int ' v) da classe (etor. De um modo geral os destrutores ser(em para =arrumar a casa= +uando ob&etos s%o desalocados ou saem de escopo. A sinta)e dos mtodos para dele$%o de (etores delete v; ou delete CEv; podem (ariar de compilador para compilador* o usu-rio de(e cecar +ue sinta)e seu compilador suporta. 1ote +ue +uando n%o dispBnamos do destrutor o programador era obrigado a deletar passo a passo todas as estruturas dinAmicas dos ob&etos +ue saiam de escopo* e)istem tcnicas a(an$adas para obter coleta autom-tica de li)o em C'' baseadas neste ponto. Re"$%&'(! (! )r!*r'+': "ntre com (alor da posicao:N D "ntre com (alor da posicao:: X "ntre com (alor da posicao:; C "ntre com (alor da posicao:< ; "ntre com (alor da posicao:D : D X C ; : Ma)imo:C Dc' (e )r!*r'+'3=!: 3aiba +ue uma pr-tica bastante Btil na fase de testes de um programa introdu0ir mensagens informati(as em pontos con(enientes. 8uando trabalando com ob&etos tal pr-tica pode ser usada de (-rios modos* por e)emplo pode2se inserir uma mensagem no destrutor de uma classe para (erificar +uando os ob&etos s%o eliminados e se s%o eliminados corretamente. Exercc!": :7 1ote +ue os mtodos atribui e conteBdo apresentam estilos diferentes de lidar com ndices fora dos limites do (etor. 5m apresenta uma mensagem de erro e termina o programa. Outro simplesmente n%o e)ecuta a a$%o se os parAmetros n%o esti(erem corretos. "scola um dos estilos e uniformi0e o programa. 8uando (oc/ estudar =e)ception andling= D.X (er- maneiras melores de lidar com esses problemas. ;7 9mplemente uma fun$%o membro camada ordena para o tipo abstrato de dados (etor definido acima. 5se +ual+uer algoritmo de ordena$%o. <7Crie destrutores para as classes +ue (oc/ &- implementou* mesmo +ue elas n%o tenam atributos +ue usem aloca$%o dinAmica. 9ntrodu0a mensagens tipo cout -- 4Good)ye"""4; nos destrutores destas classes . Como essas mensagens podem ser Bteis> Defina (-rios n(eis de blocos de c4digo* fa0endo assim com +ue ob&etos saiam de escopo em tempos diferentes e teste seus destrutores. D7Melore o e)erccio anterior introdu0indo um nome para o ob&eto. "ste nome de(e ir nas sadas de tela e nome dado para o construtor como uma string (char')" 1%o es+ue$a de deletar esta string no destrutor da classe depois de imprimir a mensagem. X7Crie uma fun$%o membro de nome preence* +ue iniciali0a todas as posi$#es de um (etor com o (alor de um de seus argumentos. Y7Defina um programa camado grandes +ue implementa o tipo abstrato de dados nBmeros grandes e inteiros* este tipo de(e usar um (etor do tipo numrico +ue (oc/ acar con(eniente para representar os algarismos. Wal(e0 estudar circuitos l4gicos como somadores* etc o a&ude a implementar as +uatro opera$#es matem-ticas b-sicas para estes tipo em termos de =looc aead carrier= e outras tcnicas de performance para implementar as opera$#es. _71ote +ue na aloca$%o do (etor: (etor::(etor 6int tam7 K(Mne\ inthtamiF tamanoMtamFL * n%o cecado se o (alor passado tam maior +ue N* fa$a este teste. 8uando e)plicarmos =e)ception andling= (oc/ ter- mtodos melores de lidar com esses erros. 1.?.6.B. ALOCANDO OBJETOS Pula* em Modula2< &- s%o alocados. "ste e)emplo mostra como trabalar com ponteiros para ob&etos* ne\ e delete* como alocar mem4ria e camar corretamente os construtores. C!+e,&-r!": Perceba +ue agora n%o estamos alocando um (etor de inteiros com tr/s posi$#es (ne? intCFE), mas um inteiro +ue contm o (alor <. .oc/ pode ler o c4digo ('a) como: =O apontado de a=. 3e a fosse uma struct ou class e ti(esse um dado membro camado dd* poderamos obter o (alor de dd atra(s de 6Ua7.dd +ue pode ser todo abre(iado em a+6dd onde +6 uma seta* ou fleca +ue (oc/ pode ler como =o apontado= no(amente. Os par/nteses em ('a)"dd s%o necess-rios de(ido a preced/ncia do operador . com rela$%o ao '. 1.?.9. REFERLNCIA M A+ui (ou ensinar passagem por refer/ncia* lembre2se +ue ob&etos s%o passados por refer/ncia* por+ue eles s%o refer/ncia* ponteiros. "ste t4pico (ai e)plicar como usar o operador H, tambm camado de operador =endere$o de...=. "ste operador fornece o endere$o* a posi$%o na mem4ria de uma (ari-(el* de um argumento* etc. 3ua utili0a$%o muito simples* se a uma (ari-(el inteira* Ha retorna um ponteiro para a. O programa a seguir ilustra a sinta)e do operador: Ginclude Hiostream.I (oid main67 K int aF aM:NF intU pF pMj aF 6Up7M:<F cout HH aF L Ex)%c',(! ! )r!*r'+' )'""! ' )'""!: int aF Declara uma (ari-(el inteira com nome a. aM:NF atribui (alor :N a (ari-(el a. intU pF Declara um ponteiro de (ari-(el inteira * o nome do ponteiro p. pMj aF Atribui o =endere$o de a= * 4H a4 ao ponteiro p. 6Up7M:<F Atribui :< ao =apontado de p=* =('p) =* mas como p aponta para a* a passa de (alor :N para (alor tre0e atra(s de p. : um =alias= para a. cout HH aF 9mprime o (alor esperado +ue tre0e. O programa a seguir usa o operador =endere$o de= para modificar argumentos* parAmetros de uma fun$%o* ou se&a utili0a passagem por refer/ncia* e+ui(alente ao .A! de Pascal. ?embre2se +ue at agora os argumentos das nossas fun$#es s4 eram passados por (alor. Ginclude Hiostream.I (oid incrementa6intj a7 K a''F L JJprimeira funcao +ue usa passagem por referencia (oid troca6intj a*intj b7 K int au)MaF aMbF bMau)F L JJsegunda funcao +ue usa passagem por referencia (oid main67 K int i:M:NF int i;M;NF incrementa6i:7F cout HH i: HH endlF troca6i:*i;7F cout HH i: HH endlF L Re"$%&'(! (! )r!*r'+': :: ;N Ex)%c',(! )'""! ' )'""!: As fun$#es criadas no programa* s%o como dissemos* capa0es de alterar seus parAmetros* increenta * incrementa seu Bnico parAmetro e troca* troca os dois parAmetros inteiros. 1.A. RECAPITULANDO 1este t4pico apresentaremos programas +ue re(isam todos conceitos &- (istos e acrescentam mais alguns detales da linguagem. 1.A.1. ARGUMENTOS DE LIN<A DE COMANDO. 1este t4pico (amos apresentar um e)emplo +ue usa tudo o +ue foi aprendido at agora e introdu0 mais alguns outros conceitos. "ste e)emplo um &ogo de +uebra cabe$a. Pro(a(elmente (oc/ &- (iu um +uebra cabe$a deste tipo* ele camado +uebra cabe$a de ti&olos desli0antes. , composto de um tabuleiro 6matri07 +uadrado preencido com pe$as de N at 6ladol;2:7 onde lado a dimens%o de um lado do tabuleiro. A representa$%o no programa numrica* mas normalmente esses +uebra cabe$as s%o (endidos com desenos pintados sobre as pecas. 1o lugar onde de(eria estar a Bltima pe$a dei)a2se um espa$o (a0io para +ue se possa mo(er as pe$as do tabuleiro. O ob&eti(o colocar todos os ti&olos em ordem* como no es+uema abai)o: 3olucionadoS O +ue um +uebra cabe$a tem a (er com encapsulamento> 3imples o &ogador obrigado a seguir as regras do &ogo* portanto n%o pode conecer todas as opera$#es +ue se aplicam ao +uebra cabe$a* e tambm n%o pode acessar sua representa$%o interna. .amos (er como isso feito usando as pala(ras reser(adas private e pu)lic * conceitos de agrega$%o e reuso de c4digo de uma classe matri0. Alm disso usamos const para garantir a integridade da matri0 do +uebra2cabe$a. .e&a tambm +ue estamos abordando o t4pico representa$%o* n%o raro (oc/ ter- +ue modelar ob&etos +ue representem algo do mundo real como motor* +uebra2cabe$a* conta banc-ria* circuito eltrico e assim por diante. Outros ob&etos podem ser mais abstratos* e)emplo: -r(ore bin-ria. M'" "!5re '" re*r'": .oc/ concorda +ue dada uma situa$%o onde o espa$o (a0io se encontra no meio do +uebra2cabe$a dado como e)emplo o usu-rio s4 tem D op$#es> 3%o elas: mo(er para cima 6fun$%o membro ovecia7* mo(er para bai)o * mo(er para a es+uerda ou ent%o para a direita. 1ote +ue essas fun$#es membro s4 trocam pe$as (i0inas* isso importante pois pro(ado matematicamente +ue algumas trocas de pe$as distantes 6=Odd permutations=7 podem tornar o +uebra2cabe$a insolB(el. 9sto facil de ser (erificado para um +uebra cabe$a ;);. ]arantimos a solu$%o do +uebra2cabe$a pelo camino in(erso do embaralamento das pe$as* +ue parte do +uebra2cabe$a solucionado e aplica aleatoriamente se+u/ncias de mo(imentos iguais aos +ue o usu-rio usa para solucionar o &ogo. A matri0 bidimensional representada linearmente 6(etor7 e as fun$#es membro de con(ers%o de ndice linear para colunas eJou linas e atribui$#es s%o fornecidas* mas somente as necess-rias para o &ogo . Rec$r"!" $&%N'(!": Argumentos de lina de comando* fun$#es de con(ers%o da stdli), representa$%o linear de uma matri0* const" Ar*$+e,&!" (e %,2' (e c!+',(!: .oc/ pode fa0er programas +ue aceitem argumentos de lina de comandos* resultando em algo e+ui(alente a: dir J\ JJdos format A: JJdos ou ls 2la JJuni) "sses argumentos podem ficar dispon(eis na camada da fun$%o main de seu programa como os parAmetros =argument counter= e =argument (alues=* (e&a treco de programa abai)o. void ain(int argc, char 'argvCE) %"""&'use argv e argc'& """( argc um inteiro argv um (etor de char' contendo os argumentos passados. 6J\ ...7 argv C$E o nome do programa camado. A fai)a Btil de arg(alues : argvC1E"""argvCargc+1E Portanto se argc##1* temos um Bnico argumento de lina de comando* dispon(el como string em argvC1E . Fa$a alguns testes com o mesma main usada no programa abai)o e alguns coutIs imprimindo os argumentos para entender melor o assunto. C!,"&: a- e)emplificado em :.X.: Re)re"e,&'3=! %,e'r (e $+' +'&rN: Pode2se representar uma matri0 de +ual+uer dimens%o em um (etor. .e&a o e)emplo de uma matri0 bidimensional de inteiros mostrada no formato indicelinear:(alor arma0enado .antagem da representa$%o linear 6(etor7: para referenciar uma posi$%o gasta2se somente um inteiro contra dois da representa$%o matri0 6lina*coluna7. Podemos agora considerar posi$#es +ue apontam para outras posi$#es* basta interpretar o conteBdo do (etor como um ndice linear. Des(antagem da representa$%o linear 6(etor7: necess-rio criar fun$#es de con(ers%o de ndice na forma 6lina*coluna7 para 6ndice linear7 e de 6ndice linear7 para 6coluna7 ou 6lina7. .e&a as fun$#es lin e col e linear do e)emplo seguinte. F$,34e" (e c!,Der"=! (' S&(%5: A fun$%o int atoi(char' a) con(erte uma string para um inteiro. Ginclude Hstdlib.I class matri0 JJ+uebra cabeca de ti&olos desli0antes K pri(ate: int linasF JJnumero de linas da matri0 int colunasF JJnumero de colunas na matri0 int tamF JJMlinasUcolunas int UlcF JJ(etor de tamano linaUcolunas representando matri0:N..6tam2:7 public: matri06const int l*const int c7F JJcria matri0 ?)C JJ+ual+uer uma das funcoes abai)o retorna nil se nao conseguiu intU linear6const int lin*const int col7const F JJind linear a partir de lina e coluna intU col6const int indlin7const FJJcoluna a partir do indice linear intU lin6const int indlin7const F JJlina a partir do indice linear int trocaindlin6const int i*const int &7F JJargumentos: ; indices lineares JJretorna : conseguiu* N nao conseguiu int atribuiindlin6const int i*const int (7F JJatribui ( ao indice i JJretorna : conseguiu* N nao conseguiu intU retornaindlin6const int i7F JJretorna conteudo do indice i JJretorna nil se nao conseguiu int getl6(oid7F JJretorna numero de linas int getc6(oid7F JJretorna numero de colunas int gett6(oid7F JJretorna tamano M linasUcolunas `matri067F LF Ginclude =matri0.= matri0::matri06const int l*const int c7 JJcria matri0 K lcMne\ inthlUciF JJl*c dimensoes F lc (etorhlUci linasMlF colunasMcF tamMlinasUcolunasF L intU matri0::linear6const int alin*const int acol7 const JJind linear a partir de lina e coluna K intU resultMne\ intF JJ(alor de retorno if 6 6NHalin7 jj 6alinHMlinas7 jj 6NHacol7 jj 6acolHMcolunas7 7 K 6Uresult7M6alin2:7Ucolunas'acolF return resultF L else return 15??F L intU matri0::col6const int indlin7const JJcoluna a partir do indice linear K intU resultMne\ intF if 6 6NHindlin7 jj 6indlinHMtam7 7 K 6Uresult7M6indlin d colunas7F if 66Uresult7MMN7 6Uresult7McolunasF return resultF L else return 15??F L intU matri0::lin6const int indlin7const JJlina a partir do indice linear K intU resultMne\ intF if 6 6NHindlin7 jj 6indlinHMtam7 7 K 6Uresult7M6int66indlin2:7 J colunas7':7F return resultF L else return 15??F L int matri0::trocaindlin6const int i*const int &7 JJargumentos: ; indices lineares JJretorna : conseguiu* N nao conseguiu K int au)F if 6 6NHi7 jj 6iHMtam7 jj 6NH&7 jj 6&HMtam7 7 K au)Mlchi2:iF JJefetua a troca lchi2:iMlch&2:iF JJembora para usuario a matri0 (ai de : ate lUc JJpara mim (ai de o ate lUc2: lch&2:iMau)F return :F JJsucesso L else return NF JJfalou L int matri0::atribuiindlin6const int i*const int (7 JJretorna : conseguiu* N nao conseguiu K if 6 6NHi7 jj 6iHMtam7 7 K lchi2:iM(F JJefetua a atribuicao return :F L else return NF JJfalou L intU matri0::retornaindlin6const int indlin7 JJretorna nil se nao conseguiu K intU resultMne\ intF if 6 6NHindlin7 jj 6indlinHMtam7 7 K UresultMlchindlin2:iF return resultF L else return 15??F L int matri0::getl6(oid7 JJretorna numero de linas K return linasF L int matri0::getc6(oid7 JJretorna numero de colunas K return colunasF L int matri0::gett6(oid7 JJretorna tamano K return tamF L matri0::`matri067 K delete lcF L JJ+uebra cabecas de ti&olos desli0antes Ginclude Hiostream.I JJpara cin cout Ginclude Hiomanip.I JJformatar cout output com II set\idt67 Ginclude Hstdlib.I JJuso rand67 em embarala Ginclude Hstring.I JJatoi67 para con(erter argumentos de lina de comando Ginclude =matri0.= const int min@ladoM;F JJminimo tamano lateral do +uebracab. const int tam@padraoMXF JJtamano padrao class +uebracab JJ+uebra cabeca de ti&olos desli0antes K pri(ate: int (a0ioF JJindice linear da casa (a0ia int mo(F JJnumero de mo(imentos matri0U m+cF JJmatri0 interna do +uebra cabecas public: +uebracab6const int ldMtam@padrao7F JJcria +uebra cabeca* ldMlado (oid mostra67 constF JJmostra +uebra cabeca (oid mo(edir67F JJmo(e celula a es+ de (a0io para direita. (oid mo(ees+67F JJanalogo (oid mo(ebai)o67F JJanalogo (oid mo(ecima67F JJanalogo (oid embarala67F JJembarala +uebracabeca int tstsolucao67 constF JJtesta se +uebracabeca esta solucionado int retorna@mo(67 K return mo(F L JJretorna numero de mo(imentos `+uebracab67F JJdestroi +uebra cabecas LF +uebracab::+uebracab6const int ld7 JJargumento padrao desnessario* &a declarado K int ldcMabs6ld7F JJld copia M (alor positi(o de ld if 6ldcHmin@lado7 ldcMmin@ladoF m+cMne\ matri06ldc*ldc7F JJiniciali0a ob&eto matri0 for6int iM:FiHm+c2Igett67Fi''7 m+c2Iatribuiindlin6i*i7F JJinitiali0a casas da matri0 m+c2Iatribuiindlin6m+c2Igett67*N7FJJatribui 0ero a posicao da celula (a0ia (a0ioMm+c2Igett67F JJdefine posicao da celula (a0ia mo(MNF JJsem nenum mo(imento embarala67F JJembarala +uebracabeca L (oid +uebracab::mostra67 const JJmostra +uebra cabeca K int i*&F JJlina e coluna intU indF JJ(alor atual for6iM:FiHMm+c2Igetl67Fi''7 JJloop das linas K JJlinas for6&M:F&HMm+c2Igetc67F&''7 JJloop das colunas K JJcolunas indMm+c2Ilinear6i*&7F JJresultado tambem e ponteiro if 66Uind7MM(a0io7 cout HH set\6D7HH= =F JJ(a0ioMespaco else cout HH set\6D7 HH 6Um+c2Iretornaindlin6Uind77F JJnao e o (a0io* mostra conteudo L JJcolunas cout HH endlF JJmudanca de lina L JJlinas cout HH endlF L (oid +uebracab::mo(edir67 JJmo(e celula a es+ de (a0io para direita JJespaco mo(e para es+uerda K if 6 6U6m+c2Icol6(a0io777 SM:7 JUnao esta na borda es+uerdaUJ K m+c2Itrocaindlin6(a0io*(a0io2:7F mo(''F (a0ioM(a0io2:F L L (oid +uebracab::mo(ees+67 JJespaco mo(e para direita K if 6 6U6m+c2Icol6(a0io777SMm+c2Igetc67 7 JUnao esta na borda direitaUJ K m+c2Itrocaindlin6(a0io*(a0io':7F mo(''F (a0ioM(a0io':F L L (oid +uebracab::mo(ebai)o67 JJespaco mo(e para cima K if 66U6m+c2Ilin6(a0io777SM:7 JUnao esta no topoUJ K m+c2Itrocaindlin6(a0io*(a0io26m+c2Igetc6777F JJcama funcao pri(ate mo(''F (a0ioM(a0io26m+c2Igetc677F L L (oid +uebracab::mo(ecima67 JJespaco mo(e para bai)o K if 66Um+c2Ilin6(a0io77SMm+c2Igetl677 JUnao esta em bai)oUJ K m+c2Itrocaindlin6(a0io*(a0io'6m+c2Igetc6777F mo(''F (a0ioM(a0io'6m+c2Igetc677F L L (oid +uebracab::embarala67 JJembarala +uebracabeca K int i*&F JJloop principal* loop secundario int rF JJr times for6&MNF&Hm+c2Igett67F&''7 K rM6rand67d m+c2Igetc677F for6iMNFiHrFi''7 Ktis2Imo(edir67FL JJmo(e r (e0es rM6rand67d m+c2Igetl677F for6iMNFiHrFi''7 Ktis2Imo(ebai)o67FL rM6rand67d m+c2Igetc677F for6iMNFiHrFi''7 Ktis2Imo(ees+67FL rM6rand67d m+c2Igetl677F for6iMNFiHrFi''7 Ktis2Imo(ecima67FL L mo(MNF JJiniciali0a mo(imentos L int +uebracab::tstsolucao67 const JJtesta se +uebracabeca esta solucionado K int iM:*contM:F \ile6 cont jj 6iH 6m+c2Igett677 7 7 K if 66U6m+c2Iretornaindlin6i777MM6i77 contM:F else contMNF i''F L return 6cont7F JJiM+ctam esta solucionado : ; <... ;D N L +uebracab::`+uebracab67 Kif 6m+cSM15??7 delete m+cF cout HH = 8uebra cabeca destruidoSPn=FL JJdestroi +uebracab main6int argc*car Uarg(hi7 JJargumentos sao declarados a+ui K JJmain int ladocompF car opcaoF JJusada em menu como (aria(el de opcao if 6argcI:7 ladocompMatoi6arg(h:i7F JJcon(ertendo argumento de lina de comando para inteiro else ladocompMtam@padraoF JJ(alor default +uebracab a+uebracab6ladocomp7F JJcriando +uebracab do K a+uebracab.mostra67F cout HH=Pn=F JJmenu de opcoes cout HH= Mo(imentos:= HH a+uebracab.retorna@mo(67HH =Pn=F cout HH= DH2 Y2I ECima ;^ai)o 33air "embarala Pn=F cout HH= !econece se+uencias de comandos: ;YEY;D H"nterIPn=F cout HH= Aceita argumento de lina de comando: +uebracab D 6cria +uebracabeca D ) D7Pn=F cout HH= "ntre comando:=F cin II opcaoF JJle opcao do usuario cout HH=Pn=F s\itc6opcao7 JJe)ecuta opcao do usuario K case R"R: case ReR: a+uebracab.embarala67F breacF case RER: a+uebracab.mo(ecima67F breacF case R;R: a+uebracab.mo(ebai)o67F breacF case RDR: a+uebracab.mo(ees+67F breacF case RYR: a+uebracab.mo(edir67F breacF default: F L JJfim do bloco de codigo do s\itc2case if 6a+uebracab.tstsolucao677 opcaoMRsRF JJsai do loop de menu L \ile 66opcaoSMR3R7 jj 6opcaoSMRsR77F JJloop menu if 6a+uebracab.tstsolucao677 Ka+uebracab.mostra67F cout HH = ParabensSPn=FL else cout HH = 8uebra cabeca nao solucionado. Wente no(amenteSPn=F return NF L JJbloco de codigo principal C!+e,&-r!": delete CE!c; "ste destrutor adota uma tcnica diferente para dele$%o de (etores* ce+ue +ue tcnicas seu compilador suporta. Exercc!": :7 3e (oc/ implementou o &ogo de +uebra2cabe$a notar- +ue n%o e)iste apagamento da tela* somente =scroll=. 9sto torna o &ogo um pouco cansati(o por+ue d- para (er o +uebra cabe$a sendo empurrado para o alto da tela e a no(a representa$%o sendo criada na parte de bai)o do =display=. A ra0%o de tal escola simples: a fun$%o de apagamento de tela do DO3 n%o port-(el para o 519O e (ice (ersa. Descubra a fun$%o de C?3 6Clear 3creen7 do seu ambiente de programa$%o e use2a no programa. 1uma segunda etapa introdu0a cores no programa* (oc/ pode usar a fun$%o m4dulo 6nBmero da pe$a *nBmero de cores7 para determinar a cor de uma pe$a. ;7 9mplemente outros &ogos simples. Pense em &ogos compat(eis com a sua e)peri/ncia. A+ui (%o algumas sugest#es: 3ena: aogo bastante conecido* o programa cria um c4digo de n dgitos e m smbolos. Atra(s de cutes o &ogador tenta acertar o c4digo na se+V/ncia. A cada cute o programa da dicas dos acertos sendo elas de dois tipos: Acertou o smbolo O (e0es ou acertou o smbolo e a posi$%o Q (e0es. .oc/ ter- +ue usar uma fun$%o para obter nBmeros aleat4rios* pro(a(elmente rand da =library= -ath"h6" aogo da (ela. 3e (oc/ n%o conece os &ogos procure obter mais informa$#es antes de come$ar a implementa2los. X7Melore a classe matri0 para aceitar nas suas fun$#es argumentos do tipo 6lina*coluna7 e n%o s4 ndices lineares. D7 Construa um programa simples +ue recebe argumentos da lina de comando e os imprime atra(s de cout" 1ormalmente isso +ue de(e ser feito antes de usar um recurso da linguagem pela primeira (e0* e)perimenta2lo em programas simples. #. <ERANA #.1. <IERAR7UIAS DE TIPOS 1este t4pico mostraremos como construir ierar+uias de tipo por generali0a$%o J especiali0a$%o. #.1.1. UMA <IERAR7UIA SIMPLES. Construiremos uma ierar+uia de tipos simples para demonstrar eran$a pBblica em C' '. C!+e,&-r!": O diagrama acima representa a ierar+uia de classes implementada e foi obtido a partir da &anela de edi$%o de uma ferramenta case para programa$%o orientada a ob&etos. A classe ponto +ue est- no topo da ierar+uia camada de classe base* en+uanto +ue as classes ponto_reflete e ponto_ove s%o camadas classes filas ou erdeiras. As classes da ierar+uia s%o simples* ponto_ove apresenta a fun$%o membro ove* &- (ista neste tutorial em :.;.Y* ponto_reflete apresenta a fun$%o membro (reflete) +ue in(erte o sinal das coordenadas. Dada a simplicidade das classes o leitor poderia se perguntar* por+ue n%o &untar as tr/s em uma s4 . A pergunta fa0 sentido* mas e se +uisssemos criar uma classe ponto +ue n%o se mo(esse* apenas refletisse e outra +ue s4 se mo(esse> " se +uisssemos pro&etar nosso programa segundo uma ierar+uia de especiali0a$%o J generali0a$%o da classe ponto> O e)emplo mostra como fa0/2lo. <er',3' PO5%c': 1a eran$a pBblica as classes filas passam a ter as mesmas fun$#es membro pu)lic da classe pai* as classes filas podem acrescentar fun$#es membro* dados membro e at redefinir fun$#es membro erdadas 6(eremos mais tarde7. Os atributos da classe pai n%o s%o acess(eis diretamente na classe fila a n%o ser +ue se&am +ualificados como protected, (e&a ;.:.;. Por isso +ue se di0 +ue as classes filas garantem pelo menos o comportamento =bea(iour= da classe pai* podendo acrescentar mais caractersticas. Diagrama de acesso* (isibilidade* de dados membro e fun$#es membro de uma classe pai para uma classe fila ou erdeira por eran$a pBblica: C!,"&r$&!re" e 2er',3': 1o construtor de uma classe fila o programador pode incluir a camada do construtor da classe pai. De"&r$&!re" e 2er',3': 8uando um ob&eto da classe deri(ada destrudo* o destrutor da classe pai tambm camado dando a oportunidade de liberar a mem4ria ocupada pelos atributos private da classe pai. JJeader file class ponto K pri(ate: float )F JJsao ocultos por default float yF JJsao ocultos por default public: JJda+ui em diante tudo e acessi(el. ponto6float a*float b7F (oid iniciali0a6float a*float b7F float retorna@)6(oid7F float retorna@y6(oid7F (oid altera@)6float a7F (oid altera@y6float b7F (oid mostra6(oid7F LF class ponto@reflete:public ponto JJclasse fila K pri(ate: JJse (oce +uer adicionar atributos... public: ponto@reflete6float a* float b7F (oid reflete6(oid7F LF class ponto@mo(e:public ponto K public: ponto@mo(e6float a*float b7F (oid mo(e6float d)*float dy7F LF JJimplementation file Ginclude Hiostream.I Ginclude =pontos.= ponto::ponto6float a*float b7 K iniciali0a6a*b7F L (oid ponto::iniciali0a6float a*float b7 K )MaF yMbF L float ponto::retorna@)6(oid7 K return )F L float ponto::retorna@y6(oid7 K return yF L (oid ponto::altera@)6float a7 K )MaF L (oid ponto::altera@y6float b7 K yMbF L (oid ponto::mostra6(oid7 K cout HH =6= HH ) HH =*= HH y HH =7= HHendlF L ponto@reflete::ponto@reflete6float a*float b7:ponto6a*b7 K L (oid ponto@reflete::reflete6(oid7 K altera@)62retorna@)677F altera@y62retorna@y677F L ponto@mo(e::ponto@mo(e6float a*float b7:ponto6a*b7 K L (oid ponto@mo(e::mo(e6float d)*float dy7 K altera@)6retorna@)67'd)7F altera@y6retorna@y67'dy7F L Ginclude Hiostream.I Ginclude =pontos.= (oid main67 K ponto@reflete p:6<.:D*;.:_7F p:.reflete67F cout HH =P:=F p:.mostra67F ponto@mo(e p;6:.N*:.N7F p;.mo(e6.X*.X7F cout HH =P;=F p;.mostra67F L Re"$%&'(! (! )r!*r'+': P:62<.:D*2;.:_7 P;6:.X*:.X7 <er',3' PrD'&e: Ainda n%o foi inserido no tutorial nenum e)emplo com este tipo de eran$a* mas o leitor pode e)perimentar mais tarde especificar uma classe erdeira por eranca pri(ate como: class herdeira/ private noe_classe_)ase; * e notar- +ue as fun$#es membro desta classe base s4 s%o acess(eis dentro das declara$#es da classe fila* ou se&a a classe fila n%o atende por essas fun$#es membro* mas pode us-2las em seu c4digo. Zeran$a private um recurso +ue (oc/ precisa tomar cuidado +uando usar. 1ormalmente* +uando usamos eran$a di0emos +ue a classe fila garante no mnimo o comportamento da classe pai 6em termos de fun$#es membro7 * a eran$a private pode in(alidar esta premissa. Muitos programadores usam eran$a private +uando ficaria mais elegante* acad/mico* trabalar com agrega$%o. 5ma classe pila pode ser construda a partir de uma classe +ue implementa uma lista ligada por agrega$%o ou por eran$a private" 1a agrega$%o 6a escolida em hierarquias de impleme!a"#$7 a classe pila possui um dado membro +ue uma lista ligada. #.1.#. PROTECTED 9gual ao e)emplo um* mas agora tornando os atributos da classe pai acess(eis para as classes filas atra(s do uso de protected" :rotected dei)a os atributos da classe pai (is(eis* acess(eis =ierar+uia abai)o=. Diagramas de acesso* (isibilidade* de dados membro e fun$#es membro de uma classe pai para uma classe fila ou erdeira: :ara ua classe filha por heranJa
pK)lica/ Lisi)ilidade da classe herdeira
para o restante do prograa/ JJeader file class ponto K protected: JJUUUUUa+ui esta a diferenca UUUUUU float )F JJ(isi(eis ierar+uia abai)o float yF JJ(isi(eis ierar+uia abai)o public: JJda+ui em diante tudo e acessi(el. ponto6float a*float b7F (oid iniciali0a6float a*float b7F float retorna@)6(oid7F float retorna@y6(oid7F (oid altera@)6float a7F (oid altera@y6float b7F (oid mostra6(oid7F LF class ponto@reflete:public ponto K pri(ate: JJse (oce +uer adicionar dados membro encapsulados... public: ponto@reflete6float a* float b7F (oid reflete6(oid7F LF class ponto@mo(e:public ponto K public: ponto@mo(e6float a*float b7F (oid mo(e6float d)*float dy7F LF JJimplementation file Ginclude Hiostream.I Ginclude =pontos.= ponto::ponto6float a*float b7 K iniciali0a6a*b7F L (oid ponto::iniciali0a6float a*float b7 K )MaF yMbF L float ponto::retorna@)6(oid7 K return )F L float ponto::retorna@y6(oid7 K return yF L (oid ponto::altera@)6float a7 K )MaF L (oid ponto::altera@y6float b7 K yMbF L (oid ponto::mostra6(oid7 K cout HH =6= HH ) HH =*= HH y HH =7= HHendlF L ponto@reflete::ponto@reflete6float a*float b7:ponto6a*b7 K L (oid ponto@reflete::reflete6(oid7 K )M2)F JJUUU protected da esse tipo de acesso aos atributos da classe pai yM2yF L ponto@mo(e::ponto@mo(e6float a*float b7:ponto6a*b7 K L (oid ponto@mo(e::mo(e6float d)*float dy7 K )M)'d)F JJacesso so na ierar+uia* no resto do programa nao. yMy'dyF L Ginclude Hiostream.I Ginclude =pontos.= (oid main67 K ponto@reflete p:6<.:D*;.:_7F p:.reflete67F cout HH =P:=F p:.mostra67F ponto@mo(e p;6:.N*:.N7F p;.mo(e6.X*.X7F cout HH =P;=F p;.mostra67F L #.1.6. REDEFINIO DE FUN0ES MEMBRO <ERDADAS . 9gual ao e)emplo anterior* mas agora redefinindo a fun$%o membro ostra para a classe fila ponto reflete. C!+e,&-r!": 1a (erdade este e)emplo de(eria pertencer ao t4pico de polimorfismo* contudo* nos e)emplos seguintes usaremos tambm redefini$#es de fun$#es membro* portanto fa02se necess-rio introdu0i2lo agora. Weremos mais e)plica$#es sobre o assunto. 5ma classe fila pode fornecer uma outra implementa$%o para uma fun$%o membro erdada* caracteri0ando uma redefini$%o =o(erriding= de fun$%o membro. 9mportante: a fun$%o membro de(e ter a mesma assinatura 6nome* argumentos e (alor de retorno7* sen%o n%o se trata de uma redefini$%o e sim sobrecarga =o(erloading=. 1o nosso e)emplo a classe ponto_reflete redefine a fun$%o membro ostra da classe pai* en+uanto +ue a classe erdeira ponto_ove aceita a defini$%o da fun$%o membro ostra dada pela classe ponto +ue sua classe pai. JJeader file class ponto K pri(ate: float )F JJsao ocultos por default float yF JJsao ocultos por default public: JJda+ui em diante tudo e acessi(el. ponto6float a*float b7F (oid iniciali0a6float a*float b7F float retorna@)6(oid7F float retorna@y6(oid7F (oid altera@)6float a7F (oid altera@y6float b7F (oid mostra6(oid7F LF class ponto@reflete:public ponto K pri(ate: JJse (oce +uer adicionar dados membro public: ponto@reflete6float a* float b7F (oid reflete6(oid7F (oid mostra6(oid7F JJredefinicao LF class ponto@mo(e:public ponto K public: ponto@mo(e6float a*float b7F (oid mo(e6float d)*float dy7F JJesta classe fila nao redefine mostra LF JJimplementation file Ginclude Hiostream.I Ginclude =pontos.= ponto::ponto6float a*float b7 K iniciali0a6a*b7F L (oid ponto::iniciali0a6float a*float b7 K )MaF yMbF L float ponto::retorna@)6(oid7 K return )F L float ponto::retorna@y6(oid7 K return yF L (oid ponto::altera@)6float a7 K )MaF L (oid ponto::altera@y6float b7 K yMbF L (oid ponto::mostra6(oid7 K cout HH =6= HH ) HH =*= HH y HH =7= HHendlF L ponto@reflete::ponto@reflete6float a*float b7:ponto6a*b7 K L (oid ponto@reflete::reflete6(oid7 K altera@)62retorna@)677F altera@y62retorna@y677F L (oid ponto@reflete::mostra6(oid7 K cout HH =O:= HH retorna@)67 HH = Q:=F cout HH retorna@y67 HH endlF L JJsomente altera o formato de impressao ponto@mo(e::ponto@mo(e6float a*float b7:ponto6a*b7 K L (oid ponto@mo(e::mo(e6float d)*float dy7 K altera@)6retorna@)67'd)7F altera@y6retorna@y67'dy7F L Ginclude Hiostream.I Ginclude =pontos.= (oid main67 K ponto@reflete p:6<.:D*;.:_7F p:.reflete67F cout HH =P:=F p:.mostra67F ponto@mo(e p;6:.N*:.N7F p;.mo(e6.X*.X7F cout HH =P;=F p;.mostra67F L Re"$%&'(! (! )r!*r'+': P:O:2<.:D Q:2;.:_ P;6:.X*:.X7 Exercc!": :7Weste redefini$%o de fun$%o membro colocando =coutRs= em fun$#es membro da ierar+uia* tais como: cout -- 4MedefinidoN4; cout -- 45riginalN4; #.1.9. UMA <IERAR7UIA DE LISTAS LIGADAS . Construiremos sem importar nenum outro c4digo* uma ierar+uia de listas ligadas especiali0adas. 5m dos ob&eti(os obter uma implementa$%o de lista +ue possa ser reutili0ada para cria$%o de pilas e filas. O deseno acima foi elaborado segundo metodologia descrita no li(ro =Ob&ect Oriented Modeling and Design= . A associa$%o entre as classes lista e n4 uma associa$%o do tipo =as many= en+uanto +ue a associa$%o entre a classe lista e as classes lista ultio e lista ordenada indica eran$a* uma associa$%o do tipo =is a=. Algumas simplifica$#es foram feitas do diagrama original. 1o t4pico sobre templates N modificaremos este e)emplo para suportar tipos parametri0ados. 1o t4pico sobre ierar+uias de implementa$%o ;.; usamos a (ers%o de lista descrita a+ui para criar uma classe +ue implementa uma fila. Gifndef M?93WZ@Z Gdefine M?93WZ@Z Ginclude Hstdlib.I Ginclude Hiostream.I JJCriacao de uma ierar+uia de listas ligadas. JJO elemento da lista eR um inteiro enum ^ooleanKFA?3"*W!5"LF class noK JJeste eR o no da lista ligada* so eR usado por ela pri(ate: int infoF JJinformacao noU pro)F JJponteiro para o pro)imo public: no67F no6int i*noU p7F noU get@pro)6(oid7F (oid set@pro)6noU p7F int get@info6(oid7F (oid set@info6int i7F noU dobra6(oid7F `no6(oid7F L F class listaK JJesta eR a lista ligada comum. protected: JJ=(isi(el ierar+uia abai)o= noU primeiroF JJprimeiro no da lista* a+ui eu insiro e remo(o. public: lista6(oid7F ^oolean (a0ia6(oid7constF ^oolean contem6int el7constF (oid insere@primeiro6int elem7F intU remo(e@primeiro67F (oid mostra67constF `lista6(oid7F LF JJfim classe lista class listaultimo:public lista K JJessa e a lista util para JJimplementar pilas e filas. protected: JJprotected e uma opcao outra eR get@ultimo67 e set@... noU ultimoF public: listaultimo6(oid7F (oid insere@ultimo6int elem7F JJno(a (oid insere@primeiro6int elem7F JJredefinicao intU remo(e@primeiro67FJJredefinicao `listaultimo6(oid7F JJas operacoes nao redefinidas sao (alidas. LF class listaordenada:public lista K JJessa eR a lista comum com aprimoramentosJespeciali0acoes public: listaordenada6(oid7F ^oolean contem6int el7constF (oid insere@primeiro6int elem7F JJinsere em ordem intU remo(e@elemento6int el7F JJremo(e elemento el se e)istir `listaordenada6(oid7F LF Gendif Ginclude =mlist.= Ginclude Hiostream.I Ginclude Hstdlib.I no::no67 Kpro)M15??Fcout HH =Zi=FL no::no6int i*noU p7 KinfoMiFpro)MpFcout HH =Zi=FL noU no::get@pro)6(oid7Kreturn pro)FL (oid no::set@pro)6noU p7 Kpro)MpFL int no::get@info6(oid7 Kreturn infoFL (oid no::set@info6int i7 KinfoMiFL noU no::dobra6(oid7 K if 6get@pro)67MM15??7 return ne\ no6get@info67*15??7F else return ne\ no6get@info67*tis2Iget@pro)672Idobra677F JJrecursi(idade para duplicacao da lista L no::`no6(oid7 Kcout HH =bye=FL lista::lista6(oid7:primeiro615??7 KL JJbloco de codigo (a0io ^oolean lista::(a0ia6(oid7const K return ^oolean6primeiroMM15??7F L ^oolean lista::contem6int el7 constJJmais rapido +ue iterador K noU currF int ContiF currMprimeiroF ContiMW!5"F \ile 66currSM15??7 jj Conti 7 K if 6curr2Iget@info67SMel7 Kif 6curr2Iget@pro)67MM15??7 ContiMFA?3"F else currMcurr2Iget@pro)67FL else ContiMFA?3"F LF JJ\ile return ^oolean6curr2Iget@info67MMel7F LF (oid lista::insere@primeiro6int elem7 K noU insirameF if 6primeiroMM15??7 JJlista (a0ia primeiroMne\ no6elem*15??7F else K insirameMne\ no6elem*primeiro7F primeiroMinsirameF LF LF intU lista::remo(e@primeiro67 K intU de(ol(ameMne\ intF JJreturn noU tempF JJto delete if 6primeiroMM15??7 return 15??F JJlista (a0ia else K 6Ude(ol(ame7Mprimeiro2Iget@info67F tempMprimeiroF primeiroMprimeiro2Iget@pro)67F delete tempF return de(ol(ameF LF LF (oid lista::mostra67 const K noU currF cout HH =M=F currMprimeiroF \ile 6currSM15??7 K cout HH=6=HHcurr2Iget@info67HH=7=HH=2=F currMcurr2Iget@pro)67F LF L lista::`lista6(oid7 K noU tempF \ile 6primeiroSM15??7 K tempMprimeiroF primeiroMprimeiro2Iget@pro)67F delete tempF LF L listaordenada::listaordenada6(oid7:lista67 KLF ^oolean listaordenada::contem6int el7const K noU currF ^oolean contiMW!5"F currMprimeiroF \ile 66currSM15??7 jj conti7 K if 6curr2Iget@info67Hel7 currMcurr2Iget@pro)67F else contiMFA?3"F LF if 6currMM15??7 return FA?3"F else return ^oolean6curr2Iget@info67MMel7F L (oid listaordenada::insere@primeiro6int elem7 K noU currMprimeiroF noU pre(M15??F noU insirameF ^oolean contiMW!5"F \ile 66currSM15??7 jj conti7 K if 6curr2Iget@info67Helem7 Kpre(McurrF currMcurr2Iget@pro)67FL else contiMFA?3"F LF insirameMne\ no6elem*curr7F if 6pre(MM15??7 primeiroMinsirameF else pre(2Iset@pro)6insirame7F L intU listaordenada::remo(e@elemento6int el7 K intU de(ol(ameMne\ intF noU currMprimeiroF noU pre(M15??F noU deletemeF ^oolean contiMW!5"F \ile 66currSM15??7 jj conti7 JJaca lugar onde pode estar el K if 6curr2Iget@info67Hel7 Kpre(McurrF currMcurr2Iget@pro)67FL JJanda else contiMFA?3"F LF if 6currMM15??7 return 15??F JJfim de lista ou (a0ia else JJpode ser o elemento ou ele nao e)iste K if 6curr2Iget@info67MMel7 K deletemeMcurrF if 6pre(MM15??7 JJlista so com um elemento ou primeiro el primeiroMcurr2Iget@pro)67F else K pre(2Iset@pro)6curr2Iget@pro)677F L 6Ude(ol(ame7Mdeleteme2Iget@info67F JJso para (erificar delete deletemeF return de(ol(ameF L else return 15??F L L listaordenada::`listaordenada6(oid7 Kcout HH =?ista destruida.=FLF listaultimo::listaultimo6(oid7:lista67 K ultimoM15??F L (oid listaultimo::insere@ultimo6int elem7 K noU insirameF insirameMne\ no6elem*15??7F if 6ultimoMM15??7 ultimoMinsirameF JJlista (a0ia else K ultimo2Iset@pro)6insirame7F ultimoMinsirameF LF if 6primeiroMM15??7 primeiroMultimoF JJlista (a0ia L (oid listaultimo::insere@primeiro6int elem7 JJredefinicao K noU insirameF if 6primeiroMM15??7 JJlista (a0ia K primeiroMne\ no6elem*ultimo7F ultimoMprimeiroF LJJlista (a0ia else K insirameMne\ no6elem*primeiro7F primeiroMinsirameF LF L intU listaultimo::remo(e@primeiro67JJredefinicao K intU de(ol(ameMne\ intF JJreturn noU tempF JJto delete if 6primeiroMM15??7 return 15??F JJlista (a0ia else K 6Ude(ol(ame7Mprimeiro2Iget@info67F tempMprimeiroF primeiroMprimeiro2Iget@pro)67F delete tempF if 6primeiroMM15??7 ultimoM15??F JJ(olta lista (a0ia return de(ol(ameF LF L listaultimo::`listaultimo6(oid7 K noU tempF \ile 6primeiroSM15??7 K tempMprimeiroF primeiroMprimeiro2Iget@pro)67F delete tempF LF delete ultimoF L Ginclude =mlist.= main67 K listaordenada minaF car optionF JJuse in menu as option (ariable int elF JJelemento a inserir intU receptorF do K cout HH=Pn=F JJmenu options display cout HH=P:9nsere no primeiro.Pn=F cout HH=!:!emo(e no primeiro.Pn=F cout HH=D:!emo(e elemento.Pn=F cout HH=":")iste elemento>Pn=F cout HH=.:.a0ia>Pn=F cout HH=M:Mostra lista.Pn=F cout HH=8:8uit teste lista.Pn=F cout HH="ntre comando:=F cin II optionF JJreads user option s\itc6option7 JJe)ecutes user option K case RDR: case RdR: cout HH ="ntre elemento:=F cin IIelF receptorMmina.remo(e@elemento6el7F if 6receptorMM15??7 cout HH =15??= HH endlF else cout HH 6Ureceptor7 HH endlF breacF case RPR: case RpR: cout HH ="ntre elemento:=F cin II elF mina.insere@primeiro6el7F breacF case R!R: case RrR: if 6Smina.(a0ia677 cout HH 6Umina.remo(e@primeiro677 HHendlF else cout HH =15??* ?ista (a0ia.= HHendlF breacF case RMR: case RmR: mina.mostra67F breacF case R"R: case ReR: cout HH ="ntre elemento:=F cin IIelF cout HH mina.contem6el7F breacF case R.R: case R(R: cout HH mina.(a0ia67F breacF default: F L JJs\itc2case code blocc L \ile 66optionSMR8R7 jj 6optionSMR+R77F JJmenu loop code blocc return NF L JJmain code blocc C!+e,&-r!": 1ote +ue o programa principal s4 testa a lista ordenada* em outros programas e)emplo baseados neste (eremos testes para a lista_ultio" Exercc!": :7")perimente deri(ar 6criar classes erdeiras7 outras classes lista com propriedades de seu interesse tais como obten$%o de sublista. ;79ntrodu0a na classe lista a contagem do nBmero de elementos numa lista. <7Crie uma fun$%o membro camado void reove_todos(void); +ue simplesmente dei)a a lista (a0ia. UD73upona +ue (oc/ um programador de uma empresa e te(e +ue implementar a ierar+uia de listas para seu grupo de desen(ol(imento* segundo uma especifica$%o dada pelo seu cefe. .oc/ introdu0iria as mudan$as sugeridas nos e)erccios anteriores* mesmo sabendo +ue elas n%o esta(am na especifica$%o> 8ue dificuldade um usu-rio de sua classe lista teria para introdu0i2las caso surgisse a necessidade e (oc/ n%o ti(esse feito> Discuta as seguintes maneiras de um programador de seu grupo conseguir o efeito dese&ado de adicionar as sugest#es dos e)erccios anteriores a ierar+uia: usar eran$a 6deri(ar uma classe com void reove_todos(void) 7* alterar o c4digo original* pedir para (oc/ o programador do c4digo original mudar a implementa$%o. ?embre2se +ue pode e)istir mais de um programador usando a (ers%o original da ierar+uia de listas. #.#. <IERAR7UIAS DE IMPLEMENTAO 1ossas ierar+uias de implementa$%o em termos de c4digo 6eran$a7 n%o s%o ierar+uias* usamos delega$%o para obter pilas a partir listas. Agregamos uma lista em nossas classes e usamos esta lista de acordo com a l4gica en(ol(ida. Wudo o +ue fi0emos poderia ser feito usando eran$a private, o +ue &ustificaria o ttulo =ierar+uias de implementa$%o=* embora tornasse o nosso te)to menos acad/mico. #.#.1. FILA A PARTIR DE UMA LISTA !euso de c4digo de uma lista ligada ;.: para a implementa$%o de uma fila atra(s de agrega$%o. Para podermos declarar e usar um ob&eto lista na nossa classe fila precisamos conecer sua interface. 3abemos +ue nosso ob&eto lista permite inserir em ambas e)tremidades* inicio e fim da lista* mas s4 permite remo$#es em um e)tremo* o inicio. Como uma fila permite inser$#es somente num e)tremo e remo$#es nos e)tremo oposto* precisaremos usar nossa lista da seguinte forma: inser$%o no final da lista e remo$#es no come$o. 3eguem abai)o e)emplos de camadas de fun$#es membro da classe lista implementada em ;.: para trabalar com nBmeros inteiros. Consideremos uma lista al* s%o (-lidas as seguintes opera$#es: al.(a0ia67F JJretorna se a lista 6fila agora7 esta (a0ia. al.contem6el7F JJretorna : se el pertence a lista e N se el nao pertence a lista. al.insere@ultimo6el7F JJinsere no final da lista 6entrada da fila7. al.insere@primeiro6el7F JJnao usaremos na implementacao de fila* usariamos se JJimplementassemos uma pila. al.remo(e@primeiro67F JJremo(e no comeco da lista 6saida da fila7. al.mostra67F JJmostra lista 6mostra fila em ordem contraria de insercao7 Para maiores informa$#es consulte t4pico anterior onde definimos esta lista. Por este moti(o n%o (amos incluir sua defini$%o a seguir. JJeader file para a classe fila Ginclude =mlist.= class fila K JJagregacao de uma lista de pri(ate: listaultimo alF JJa lista public: fila67F ^oolean (a0ia67F ^oolean contem6int el7F (oid insere6int el7F intU remo(e67F (oid mostra67F LF JJimplementacao para a classe fila Ginclude =m+ueue.= Ginclude =mlist.= fila::fila67KLF ^oolean fila::(a0ia67 Kreturn al.(a0ia67FL ^oolean fila::contem6int el7 Kreturn al.contem6el7FL (oid fila::insere6int el7 Kal.insere@ultimo6el7FL intU fila::remo(e67 Kreturn al.remo(e@primeiro67FL (oid fila::mostra67 Kal.mostra67FL JJprograma principal* testes da classe fila Ginclude =m+ueue.= main67 K fila minaF car optionF JJusada em menu como (aria(el de opcao int elF JJelemento a inserir do K cout HH=Pn=F JJopcoes do menu cout HH=9:9nsere.Pn=F cout HH=!:!emo(e.Pn=F cout HH=M:Mostra fila.Pn=F cout HH=8:8uit fila test.Pn=F cout HH=.:.a0ia>Pn=F cout HH=C:Contem>Pn=F cout HH="ntre comando:=F cin II optionF JJle opcao do usuario s\itc6option7 JJe)ecuta opcao do usuario K case R9R: case RiR: cout HH ="ntre elemento:=F cin IIelF mina.insere6el7F breacF case R!R: case RrR: if 6Smina.(a0ia677 cout HH 6Umina.remo(e677 HHendlF else cout HH =15??* fila (a0ia.= HHendlF breacF case RCR: case RcR: cout HH ="ntre elemento:=F cin IIelF cout HH mina.contem6el7F breacF case RMR: case RmR: mina.mostra67F breacF case R.R: case R(R: cout HH =!esultado:= HH mina.(a0ia67 HHendlF breacF default: F L JJs\itc2case bloco de codigo L \ile 66optionSMR8R7 jj 6optionSMR+R77F JJloop do menu fim return NF L JJ bloco de codigo principal 6. POLIMORFISMO; FUN0ES 8IRTUAIS .")istem (-rios tipos de polimorfismo. 1o +ue se refere a ob&etos* Modula2< apresenta polimorfismos classificados como uni(ersais* e)emplos de polimorfismos do tipo =ad2 oc= e ob&etos podem ser encontrados em outras linguagens como C''. 6.1. O 7UE SIGNIFICA POLIMORFISMO Polimorfismo* do grego: muitas formas. Polimorfismo a capacidade de um operador e)ecutar a a$%o apropriada dependendo do tipo do operando. A+ui operando e operador est%o definidos num sentido mais geral: operando pode significar argumentos atuais de um procedimento e operador o procedimento* operando pode significar um ob&eto e operador um mtodo* operando pode significar um tipo e operador um ob&eto deste tipo. 6.1.1. SOBRECARGA DE M/TODOS Modula2< n%o oferece este tipo de polimorfismo +ue pode ser considerado com =ad2 oc=. "ste tipo de polimorfismo permitiria a e)ist/ncia de (-rios procedimentos e mtodos de mesmo nome* porm com assinaturas le(emente diferentes* (ariando no nBmero e tipo de argumentos. Ficaria a cargo do compilador escoler de acordo com as listas de argumentos os procedimentos ou mtodos a serem e)ecutados. 6.1.#. REDEFINIO DE UMA FUNO MEMBRO PARA UMA CLASSE <ERDEIRA ."ste e)emplo &- foi apresentado em ;.:.<. Wambm trata2se de um polimorfismo* pode ser classificado como polimorfismo de inclus%o. 6.1.6. "COPP CONSTRUCTOR" A fun$%o membro ponto(pontoH a); um copy constructor* alm disso tem o mesmo nome +ue ponto(float dx,float dy);" Wal duplica$%o de nomes pode parecer estrana* porm C'' permite +ue eles coe)istam para uma classe por+ue n%o tem a mesma assinatura 6nome'argumentos7. 9sto se cama sobrecarga de fun$%o membro* o compilador sabe distinguir entre esses dois construtores. Outras fun$#es membro* n%o s4 construtores poder%o ser redefinidas* ou sobrecarregadas para (-rios argumentos diferentes* esse recurso um polimorfismo do tipo =ad2oc=. O +ue interessante para n4s o fato de o argumento do construtor ponto(pontoH a); ser da mesma classe para +ual o construtor foi implementado* esse o camado =copy constructor=. "le usa um ob&eto de seu tipo para se iniciali0ar. Outros mtodos semelantes seriam: circulo(circuloH a); ouse(ouseH d);" 9mplementar copy constructor pode ser muito importante* lembre2se dos problemas com c4pias de ob&etos apresentados em :.X.<.X. Ginclude Hiostream.I struct ponto K float )F float yF ponto6float a*float b7F JJconstrutor tambem pode ser inline ou nao ponto6pontoj a7F JJcopy constructor (oid mostra6(oid7F (oid mo(e6float d)*float dy7F LF ponto::ponto6float a*float b7 K )MaF yMbF L ponto::ponto6pontoj a7 K )Ma.)F yMa.yF L (oid ponto::mostra6(oid7 Kcout HH =O:= HH ) HH = * Q:= HH y HH endlFL (oid ponto::mo(e6float d)*float dy7 K )'Md)F y'MdyF L (oid main67 K ponto ap6N.N*N.N7F ap.mostra67F ap.mo(e6:.N*:.N7F ap.mostra67F ponto ap;6ap7F ap;.mostra67F L C!+e,&-r!": Obser(e o c4digo: ponto::ponto6pontoj a7 K )Ma.)F yMa.yF L "ssa fun$%o membro* esse mtodo* pertence a outro ob&eto +ue n%o o argumento a* ent%o para distinguir o atributo x deste ob&eto* do atributo x de a usamos a"x e simplesmente x para o ob&eto local 6dono da fun$%o membro7. Exercc!": :7O copy constructor usa passagem por refer/ncia* construa uma fun$%o +ue troca duas (ari-(eis inteiras usando passagem por refer/ncia. Analise esse recurso sob a 4tica do assunto encapsulamento. "m +ue casos (oc/ pode afirmar ser seguro usar esse recurso> ;7 Defina um copy constructor para o tipo abstrato de dados fra$%o apresentado em: :.D. 6.1.9. SOBRECARGA DE FUNO EM C++. "ste t4pico apresenta e)emplos importantes para o estudo do restante do tutorial. 3obrecarga =O(erloading= de fun$%o um tipo de polimorfismo classific-(el como ad2 oc. C'' permite +ue fun$#es de mesmo nome tenam parAmetros distintos. "ste e)emplo mostra a sobrecarga da fun$%o abs +ue calcula o (alor absoluto de um nBmero: JJeader file funco(er. float abs6float a7F int abs6int a7F JJimplementation file Ginclude =funco(er.= float abs6float a7 K if 6aIN.N7 return aF else return 2aF L int abs6int a7 K if 6aIN7 return aF else return 2aF L Ginclude Hiostream.I Ginclude =funco(er.= (oid main67 K int i:F float f:F cout HH abs6int62:N77HHendlF cout HH abs6float62:N.:77HHendlF f:M2C.:F i:ME.NF cout HH abs6f:7 HH endlF cout HH abs6i:7 HH endlF L Re"$%&'(! (! )r!*r'+': :N :N.: C.: E C!+e,&-r!": cout -- a)s(float(+1$"1))--endl; Perceba +ue +uando camamos a fun$%o abs para um (alor 62:N.:7 e n%o uma (ari-(el 6possui um tipo7* temos +ue fa0er a con(ers%o e)plcita para o compilador* por+ue este n%o sabe decidir +ual fun$%o camar 6para float ou int7* mesmo estando presente o ponto indicando a casa decimal. Obser(e +ue 2:N.: pode ser dou)le ou float. "n+uanto +ue :N pode ser long ou int" 1o e)emplo D (eremos sobrecarga de operador* +ue semelante a sobrecarga de fun$%o. Obser(e +ue os operadores ' + e at mesmo os operadores de e)tra$%o -- 66 usados com cout s%o e)emplos de sobrecarga de operadores. "les &- est%o definidos com a mesma forma para um con&unto restrito de tipos. Exercc!": :7 Melore este e)emplo para +ue se calcule tambm o (alor absoluto de nBmeros em tipo long" ;7Crie um programa an-logo a este e)emplo s4 +ue agora com a fun$%o ax +ue de(e calcular o m-)imo de dois nBmeros. <7Crie um programa an-logo a este e)emplo s4 +ue agora com a fun$%o dc +ue de(e calcular o m-)imo di(isor comum de dois nBmeros int ou long. UD7?embre2se de alguns programas +ue (oc/ tena escrito em +ue se pudesse fa0er uso de fun$#es sobrecarregadas. Comente de +ue modo tal uso facilitaria tanto a programa$%o +uanto a manuten$%o de soft\are. De algum modo esse uso poderia atrapalar o desen(ol(imento do programa> 3e sim de +ue modo> UX7Mude o c4digo de uma das fun$#es abs para calcular o m4dulo do nBmero ele(ando2 o ao +uadrado e e)traindo a rai0 +uadrada* eliminando assim o sinal. .oc/ pro(a(elmente (ai precisar da library -ath"h6 . 1ote +ue o +ue importa para a sobrecarga o cabe$alo* a assinatura da fun$%o e n%o o c4digo em si. "ste programa mostra algumas peripcias +ue podemos fa0er com sobrecarga de fun$#es. .e&a e)emplo anterior primeiro. JJeader file funco(er. float ma)6float a*float b7F float ma)6float a*float b*float c7F int ma)6int a*int b7F Ginclude =funco(er.= float ma)6float a*float b7 K if 6aIb7 return aF else return bF L float ma)6float a*float b*float c7 K if 6aIb7 return ma)6a*c7F else return ma)6b*c7F L int ma)6int a*int b7 K if 6aIb7 return aF else return bF L Ginclude Hiostream.I Ginclude =funco(er.= (oid main67 K cout HH ma)6float6:.;7*float6<.D7*float6;.:77HHendlF cout HH ma)6float6:.X7*float6.YX77 HH endlF cout HH ma)6int6:;7*int6:;N77F L Re"$%&'(! (! )r!*r'+': <.D :.X :;N 6.1.?. "DEFAULT ARGUMENTS"; 8ALORES SUGESTO .alores sugest%o* argumentos padr%o ou =default arguments=* s%o nomes para um tipo de polimorfismo ad2oc fornecido por C''. Para demonstrar o uso de default (alues (amos relembrar o nosso tipo abstrato de dados fra$%o de :.;.:.D. 5m de seus construtores tina a seguinte forma: fracao() %nu#$; den#1;( &&construtor va2io,default en+uanto +ue o construtor normal da fra$%o tina a seguinte forma: fracao(long t,long );" =Default arguments= nos d- a oportunidade de fundir esses dois construtores num s4 resultando no seguinte: fracao(long t#$,long #1); %nu#t; den#;( onde : e N s%o (alores sugest%o para os argumentos. A instancia$%o fracao a( ) segundo a+uele Bnico construtor cria : ($&1) A instancia$%o fracao )(1) segundo a+uele Bnico construtor cria: (1&1) A instancia$%o fracao c(1,1) segundo a+uele Bnico construtor cria: (1&1) Re*r'" )'r' ' cr'3=! (e "De1'$%& 'r*$+e,&"": 1%o s%o permitidas declara$#es do tipo fracao(long t#$,long ); uma (e0 +ue (oc/ inseriu um argumento padr%o na lista de argumentos todos a direita deste tambm de(er%o ter seus (alores sugest%o. "nt%o* por esta regra a Bnica alternati(a restante para o tipo fra$%o seria fracao(long t,long #1); Exercc!": :7Fa$a a modifica$%o do tipo abstrato de dados fracao retirando os dois construtores mencionados e substituindo por um Bnico. O copy constructor (oc/ pode dei)ar como est-. 6.1.A. SOBRECARGA DE OPERADOR O tipo abstrato de dados fra$%o 6(ers%o completa7 de :.;.D.D possui (-rios operadores sobrecarregados. Algumas sobrecargas deste e)emplo en(ol(em o uso da pala(ra ca(e friends +ue (oc/ n%o aprendeu ainda* portanto atena2se aos e)emplos +ue n%o contm essa pala(ra reser(ada. ")tens%o da classe (etor de :.X.<.Y para incluir um iterador. "ste e)emplo &- apresentado com templates. TI)c!" '5!r('(!": 3obrecarga de operador. JJeader file para classe (etor: (et. Ginclude Hiostream.I Ginclude Hstdlib.I JJe)it6:7 const int inicioMNF JJinicio do (etor class (etorK pri(ate: floatU (F JJpode ser +ual+uer tipo +ue atenda as operacoes H I M int tamanoF public: (etor 6int tamano7 F floatj operatorhi 6int i7F float ma)imo67F JJaca o (alor ma)imo do (etor int primeiro6(oid7F int ultimo6(oid7F LF (etor::(etor 6int tam7 K(Mne\ floathtamiF tamanoMtamFL int (etor::primeiro 6(oid7 Kreturn inicioFL int (etor::ultimo 6(oid7 Kreturn tamano2:FL floatj (etor::operatorhi6int i7 K if 6iHN kk iIMtamano7 Kcout HH =Fora dos limitesS ")it program=F e)it6:7FL return (hiiF L float (etor:: ma)imo6(oid7 Kint candidatoMinicioF for 6int iMinicioFiHtamanoFi''7 if 6(hiiI(hcandidatoi7 candidatoMiF return (hcandidatoiFL Ex)%c'3=! ('" !)er'34e"; ('" 1$,3=! +e+5r!" (! &er'(!r De&!r: iteradorvetor(vetor H v); :Construtor* &- cria o iterador de (etor iniciali0ando2o para apontar para o come$o do (etor. virtual int coeca();: 9niciali0a o iterador para o come$o do (etor. virtual int operatorN(); : .erifica se a itera$%o n%o cegou no fim do (etor: : indica +ue n%o cegou* N indica +ue cegou no fim do (etor. virtual int operator ** ();: Fa0 o iterador mo(er adiante uma posi$%o. virtual float operator() (); :!etorna o elemento da+uela posi$%o do (etor. virtual void operator# (float entra); : Atribui a posi$%o atual do (etor. int pos(); : !etorna a posi$%o 6ndice7 do (etor em +ue o iterador se encontra* n%o (irtual por+ue n%o fa0 sentido para um iterador de -r(ore por e)emplo. JJit. * ar+ui(o com definicoes do iterador. class iterador(etor K pri(ate: (etor (etorrefF int posicaoF public: iterador(etor6(etor j (7F int comeca67F int operatorS67F int operator '' 67F float operator67 67F (oid operatorM 6float entra7F int pos67F JJretorna posicao* n` (irtual p+ n` fa0 sentido pJ ar(ore por e). LF int iterador(etor::pos67 K return posicaoF L int iterador(etor::operatorS67 K return posicaoHM(etorref.ultimo67F L iterador(etor::iterador(etor6(etor j (et7:(etorref6(et7 K comeca67F L int iterador(etor::comeca67 K posicaoM(etorref.primeiro67F return operatorS67F L int iterador(etor::operator ''67 K posicao''F return operatorS67F L (oid iterador(etor::operatorM6float entra7 K (etorrefhposicaoiMentraF L float iterador(etor::operator67 67 K float copiaF copiaM(etorrefhposicaoiF return copiaF L Pr!*r'+' )r,c)'%; &e"&e": Ginclude Hiostream.I Ginclude =(et.= Ginclude =it.= main67 K int repeteMNF int indF float itemF (etor meu6X7F iterador(etor itmeu6meu7F for 6itmeu.comeca67FSitmeuF''itmeu7 K cout HH ="ntre com (alor da posicao:= HH itmeu.pos67 HH =Pn=F cin II itemF itmeuMitemF L for 6itmeu.comeca67FSitmeuF''itmeu7 coutHH itmeu67HH = =F cout HH =Pn"ntre com o indice da posicao a atuali0ar:Pn=F cin II indF cout HH ="ntre com o (alor a incluir:=F cin II itemF meuhindiMitemF for 6int cMmeu.primeiro67FcHMmeu.ultimo67Fc''7 coutHH meuhciHH = =F cout HHendl HH =Ma)imo:= HH meu.ma)imo67F return NF L C!+e,&-r!": O significado do operador (oc/ +ue define* mas recomend-(el dar ao operador um significado pr4)imo ao &- definido na linguagem. Por e)emplo: o operador ' seria 4timo para representar a concatena$%o de dois ob&etos do tipo string. A sinta)e de cada operador fi)a: nBmero de operandos* preced/ncia... O leitor pode aprender melor tais regras gra(ando ou relendo os e)emplos de sobrecarga de cada operador e modificando2 os +uando necess-rio. Exercc!": :79mplemente sobrecarga do operador de adi$%o para o e)emplo WAD fra$%o apresentado em :.;.:.D ;7Crie um WAD string e sobrecarregue o operador ' com o significado de concatena$%o. <7?eia os trecos onde - sobrecarga de operador* mas sem uso de friends em :.;.:. 6.#. CLASSES ABSTRATAS E CONCRETAS 6.#.1. CLASSE ABSTRATA ITERADOR 1este t4pico (oc/ (er- +ue podem e)istir classes +ue apenas definem protocolos ou interfaces para o uso e n%o podem ser instanciadas* as classes filas +ue erdam sua interface +ue s%o instanci-(eis. 1este e)emplo (amos repetir o programa de <.:.Y* s4 +ue iremos incluir uma classe base abstrata para o iterador. O iterador de (etor definido por eran$a pu)lic da classe base abstrata de iteradores. "sta classe define o protocolo* a interface de iteradores para listas e outras estruturas. Perceba +ue algumas fun$#es membro da classe base s%o despro(idas de implementa$%o* porm nada impede +ue (oc/ colo+ue como c4digo dessas fun$#es membro uma mensagem de erro do tipo 4Orro, classe )ase nPo deve ser instanciadaN4 * como foi feito em alguns casos. JJe)(etitY * ar+ui(o com definicoes do iterador. class iteradorK JJclasse base abstrata public: int comeca6(oid7 Kcout HH ="rro* classe abstrataS=FL float operator6767 Kcout HH ="rro* classe abstrataS=F return NFL int operatorS6(oid7 Kreturn NFL int operator ''67 Kreturn NFL (oid operatorM6float entra7 KFL LF class iterador(etor:public iterador K pri(ate: (etor (etorrefF int posicaoF JJclasse fila acrescentando dados membro public: iterador(etor6(etor j (7F int comeca67F int operatorS67F int operator '' 67F float operator67 67F (oid operatorM 6float entra7F int pos67F JJretorna posicao* n` (irtual p+ n` fa0 sentido pJ ar(ore por e). JJesta eR uma funcao membro acrescentada pela classe fila LF int iterador(etor::pos67 K return posicaoF L int iterador(etor::operatorS67 K return posicaoHM(etorref.ultimo67F L iterador(etor::iterador(etor6(etor j (et7:(etorref6(et7 K comeca67F L int iterador(etor::comeca67 K posicaoM(etorref.primeiro67F return operatorS67F L int iterador(etor::operator ''67 K posicao''F return operatorS67F L (oid iterador(etor::operatorM6float entra7 K (etorrefhposicaoiMentraF L float iterador(etor::operator67 67 K float copiaF copiaM(etorrefhposicaoiF return copiaF L Os demais ar+ui(os s%o identicos aos do e)emplo sobre (etores de <.:.Y. JJeader file para classe (etor Ginclude Hiostream.I Ginclude Hstdlib.I JJe)it6:7 const int inicioMNF JJinicio do (etor class (etorK pri(ate: floatU (F JJpode ser +ual+uer tipo +ue atenda as operacoes H I M int tamanoF public: (etor 6int tamano7 F floatj operatorhi 6int i7F float ma)imo67F JJaca o (alor ma)imo do (etor int primeiro6(oid7F int ultimo6(oid7F LF (etor::(etor 6int tam7 K(Mne\ floathtamiF tamanoMtamFL int (etor::primeiro 6(oid7 Kreturn inicioFL int (etor::ultimo 6(oid7 Kreturn tamano2:FL floatj (etor::operatorhi6int i7 K if 6iHN kk iIMtamano7 Kcout HH =Fora dos limitesS ")it program=F e)it6:7FL return (hiiF L float (etor:: ma)imo6(oid7 Kint candidatoMinicioF for 6int iMinicioFiHtamanoFi''7 if 6(hiiI(hcandidatoi7 candidatoMiF return (hcandidatoiFL Ginclude Hiostream.I Ginclude =e)(etY.= Ginclude =e)(etitY.= main67 K int repeteMNF int indF float itemF (etor meu6X7F iterador(etor itmeu6meu7F for 6itmeu.comeca67FSitmeuF''itmeu7 K cout HH ="ntre com (alor da posicao:= HH itmeu.pos67 HH =Pn=F cin II itemF itmeuMitemF L for 6itmeu.comeca67FSitmeuF''itmeu7 coutHH itmeu67HH = =F cout HH =Pn"ntre com o indice da posicao a atuali0ar:Pn=F cin II indF cout HH ="ntre com o (alor a incluir:=F cin II itemF meuhindiMitemF for 6int cMmeu.primeiro67FcHMmeu.ultimo67Fc''7 coutHH meuhciHH = =F cout HHendl HH =Ma)imo:= HH meu.ma)imo67F return NF L Re"$%&'(! (! )r!*r'+': "ntre com (alor da posicao:N ; "ntre com (alor da posicao:: <X "ntre com (alor da posicao:; E; "ntre com (alor da posicao:< ; "ntre com (alor da posicao:D < ; <X E; ; < "ntre com o indice da posicao a atuali0ar: N "ntre com o (alor a incluir:: : <X E; ; < Ma)imo:E; 6.#.#. ACOPLAMENTO DE MENSAGENS a- dissemos +ue um ob&eto de uma classe fila garante no mnimo o comportamento =bea(iour= de seu pai. Por este moti(o podemos atribuir um ob&eto da classe fila a uma (ari-(el da classe pai* mas n%o o contr-rio. Acoplamento dinAmico mostrar- +ue poss(el fa0er com +ue o compilador e)ecute a implementa$%o dese&ada de uma fun$%o membro redefinida para classes erdeiras* mesmo no caso de camada de fun$%o membro para uma (ari-(el de um supertipo 6classe pai7 contendo um ob&eto de um subtipo 6classe fila7. 9sto nos permitir- construir listas etorog/neas <.;.D. 6.#.#.1. CASO ESTHTICO Ginclude Hiostream.I class pai K public: (oid print6(oid7 Kcout HH =3ou da classe pai=HHendlFL LF class filo:public pai K pri(ate: public: (oid print6(oid7 Kcout HH =3ou da classe fila= HH endlFL LF (oid main67 K filo ef:F JJestatica filo numero : pai ep:F JJestatica pai numero : ef:.print67F JJ(aria(el estatica contendo filo ep:.print67F JJ(aria(el estatica contendo pai ep:Mef:F JJ(aria(el estatica do tipo pai contendo filo con(ertido no pai ep:.print67F L D'*r'+' ('" c%'""e": A classe fila garante no mnimo o mesmo comportamento* =bea(iour= +ue a classe pai* podendo acrescentar ou redefinir parte do +ue foi erdado. Por este moti(o* uma (ari-(el da classe pai pode receber um ob&eto da classe fila* o comportamento da classe pai fica garantido e o restante 6o +ue a classe fila acrescentou7 perdido. a- uma (ari-(el da classe fila n%o pode receber um ob&eto da classe pai* por+ue as fun$#es membro acrescentadas passam a n%o fa0er sentido. Re"$%&'(! (! )r!*r'+': 3ou da classe fila 3ou da classe pai 3ou da classe pai Ex)%c'3=! (! )r!*r'+'; )'""! ' )'""!: filho ef1; Declara$%o de uma (ari-(el da classe fila. pai ep:F Declara$%o de uma (ari-(el da classe pai* menor ou igual +uantidade de membros +ue a fila. ef:.print67F Mostra a fun$%o da classe fila* a +ual pertence ef1 e seu conteBdo. ep:.print67F Mostra a fun$%o da classe de ep1 +ue a classe pai. ep:Mef:F Atribui o conteBdo de ef1 a ep1* ou se&a atribui um filo a um pai. O filo tem os dados membros e fun$#es membros acrescentados* descartados e se torna do tipo pai. "ssa con(ers%o irre(ers(el no caso. ep:.print67F Mostra a fun$%o da classe de ep: +ue a classe pai* a mesma de seu conteBdo. 6.#.#.#. DINJMICO SEM 8IRTUAL Ginclude Hiostream.I class pai K public: (oid print6(oid7 Kcout HH =3ou da classe pai=HHendlFL LF class filo:public pai K pri(ate: public: (oid print6(oid7 Kcout HH =3ou da classe fila= HH endlFL LF (oid main67 K filo ef:F JJestatica filo numero : pai ep:F JJestatica pai numero : paiU pp:F JJponteiro pai numero : ef:.print67F JJ(aria(el estatica contendo filo ep:.print67F JJ(aria(el estatica contendo pai pp:Mjep:F pp:2Iprint67F JJponteiro de pai*apontando para pai pp:Mjef:F pp:2Iprint67F JJponteiro de pai apontando para filo ep:Mef:F JJ(aria(el estatica do tipo pai contendo filo con(ertido no pai ep:.print67F L Re"$%&'(! (! )r!*r'+': 3ou da classe fila 3ou da classe pai 3ou da classe pai 3ou da classe pai 3ou da classe pai C!+e,&-r!": 1ote +ue a fun$%o membro e)ecutada escolida de acordo +ue a (ari-(el e n%o de acordo com o conteBdo desta* da mesma forma +ue no e)emplo anterior. 6.#.#.6. DINJMICO COM 8IRTUAL Ginclude Hiostream.I class pai K public: (irtual (oid print6(oid7 Kcout HH =3ou da classe pai=HHendlFL LF class filo:public pai K pri(ate: public: (irtual (oid print6(oid7 Kcout HH =3ou da classe fila= HH endlFL LF (oid main67 K filo ef:F JJestatica filo numero : pai ep:F JJestatica pai numero : paiU pp:F JJponteiro pai numero : ef:.print67F JJ(aria(el estatica contendo filo ep:.print67F JJ(aria(el estatica contendo pai pp:Mjep:F pp:2Iprint67F JJponteiro de pai*apontando para pai pp:Mjef:F pp:2Iprint67F JJponteiro de pai apontando para filo ep:Mef:F JJ(aria(el estatica do tipo pai contendo filo con(ertido no pai ep:.print67F L Re"$%&'(! (! )r!*r'+': 3ou da classe fila 3ou da classe pai 3ou da classe pai 3ou da classe fila 3ou da classe pai C!+e,&-r!": Perceba +ue virtual fa0 com +ue a fun$%o membro a e)ecutar se&a escolida de acordo com o conteBdo da (ari-(el ou ponteiro e n%o de acordo com o tipo da (ari-(el ou ponteiro 6reposit4rios7. Lirtual n%o tem efeito no uso est-tico de ob&etos* ou se&a a fun$%o membro ser- escolida de arcordo com o tipo da (ari-(el 6reposit4rio7. Exercc!": :79mplemente em suas classes fun$#es membro +ue imprimem uma frase identificando o tipo da classe* por e)emplo: ="u sou a classe conta corrente* especiali0a$%o de conta bancaria.= 6.#.6. CONTAS BANCHRIAS 1este programa e)emplo (amos definir uma classe abstrata camada conta. "sta classe define a interface de contas banc-rias* +ue se constitui das opera$#es: deposita, saca, get_saldo, get_jurosn 6&uros +uando saldo est- negati(o7* get_jurosp 6&uros +uando o saldo est- positi(o7 e coputa 6calcula &uros7. Wodos as fun$#es membro s%o =(irtuais= e)ceto destrutor . Preste aten$%o nas especifica$#es a seguir elas s%o detaladas e importantssimas para o entendimento do programa: Da classe base abstrata descrita acima* criamos duas classes concretas com as seguintes propriedades: :2Conta corrente: 21este tipo de conta as computa$#es dos &uros s%o feitas pelo banco diariamente. 2Permite ta)a de &uros diferente para saldos negati(os e positi(os. 2Possui um atributo menor +ue 0ero camado %+&e. 3a+ues +ue le(em o saldo abai)o deste (alor s%o recusados. "sta defini$%o acima n%o implica +ue o saldo tena +ue estar sempre acima de %+&e. "le s4 (ai para (alores menores +ue se os &uros da d(ida o fi0erem e n%o o cliente. 2O (alor de %+&e definido na cria$%o da conta* instancia$%o. 2Fica claro +ue este tipo de conta permite saldos negati(os. . 2A ta)a de &uros para saldo positi(o 0ero ou se&a* n%o - rendimento. ;2Poupan$a: 2Possui uma data de ani(ers-rio* s4 neste dia +ue se computa &uros ou se&a mensalmente. 2Os &uros acrescentados s%o referentes ao saldo ap4s a Bltima computa$%o* isto significa +ue dep4sitos intermedi-rios n%o rendem &uros. 23e ou(er algum sa+ue +ue n%o se&a no dia da computa$%o os &uros referentes a a+uele m/s s%o cancelados. 234 permitido saldo maior ou igual a 0ero. Outra classe foi criada no programa: a classe data +ue arma0ena datas +uais+uer. Por +uest#es de simplicidade a classe data +ue simplesmente uma classe au)iliar foi implementada com o mnimo necess-rio para o funcionamento e demonstra$%o do programa. A meloria desta classe sugerida como e)erccio. W4picos abordados: Fun$#es membro (irtual e pure (irtual. Ob&etos constantes. JJeader file for conta. JJtodas as funcoes recebem uma data por+ue o e)trato presisa disso. const float &pM.NXF JU&uros padraoUJ const float (a0ioMN.NF const float &nuloMN.NF const float lminM2DNN.NF enum ^ooleanKFA?3"*W!5"LF typedef float dinF float abs6float a7F JJfuncao (alor absoluto class dataK JJdefinir outras operacoes elaborar mais pri(ate: int diaF int mesF int anoF public: data67 KdiaM:FmesM:FanoMCXFL JJdefault constructor* importante para agregacao data6int d*int m*int a7 KdiaMdFmesMmFanoMaFL int get@dia6(oid7 Kreturn diaFL int get@mes6(oid7 Kreturn mesFL int get@ano6(oid7 Kreturn anoFL LF const data ddef6:*:*CN7F JJob&eto constanteF class contaK JJpure (irtual functions in abstract base class protected: din saldoF JJesse eR o dineiro na conta. float &urospF JJ&uros pJ saldo positi(o float &urosnF JJ&uros pJ saldo negati(o public: JJpure (irtual functions in abstract base class conta 6din +uantiaM(a0io*float ta)apM&p*float ta)anM&p*data ddMddef7F (irtual ^oolean computa6data dd7MNF JJcomputa &uros da conta (irtual din get@saldo6data dd7constMNF JJretorna conteudo da conta (irtual float get@&urosn6data dd7constMNF JJcriar as respecti(as funcoes set: set@&uros (irtual float get@&urosp6data dd7constMNF (irtual ^oolean deposita6din +uantia*data dd7MNF (irtual din saca6din +uantia*data dd7MNF `conta67KLF LF class contacorrente:public contaK pri(ate: din limF JJsa+ues +ue le(am saldo para bai)o deste limite sao blo+ueados. public: contacorrente6din +uantiaM(a0io*float ta)anM&p*din minMlmin*data ddMddef7F JJso computa +do neg. ^oolean computa6data dd7F JJpara esse tipo de conta eR diario. 6poupanca mensal7 din get@saldo6data dd7constF JJretorna conteudo da conta float get@&urosn6data dd7constF JJcriar as respecti(as funcoes set: set@&uros float get@&urosp6data dd7constF ^oolean deposita6din +uantia*data dd7F din saca6din +uantia*data dd7F `contacorrente67KLF JJpode deletar de+ue com operacoes sobre conta 6e)trato7 LF class poupanca:public contaK pri(ate: data ani(ersarioF JJdia do mes +ue a poupanca fa0 ani(ersario. ^oolean computarF JJ::computar sobre ultimo* N:rendimento perdido* sa+ue din ultimoF JJos &uros sao sobre o (alor depois da ultima computacao. JJo +ue depositou nao importa* se sacou perdeu rendimento public: poupanca6din +uantiaM(a0io*float ta)apM&p*data ddMddef7F JJmensalmente ^oolean computa6data dd7F JJ ^oolean: !endimento nao foi perdido> din get@saldo6data dd7constF JJretorna conteudo da conta float get@&urosn6data dd7constF JJcriar as respecti(as funcoes set: set@&uros float get@&urosp6data dd7constF ^oolean deposita6din +uantia*data dd7F din saca6din +uantia*data dd7F `poupanca67KLF JJpode deletar de+ue com operacoes sobre conta 6e)trato7 LF JJfile conta.cpp Ginclude =conta;.= float abs6float a7 K if 6aHN.N7 aM2aF return aF L conta::conta6din +uantia*float ta)ap*float ta)an*data dd7 K saldoMabs6+uantia7F &urospMabs6ta)ap7F &urosnMabs6ta)an7F L poupanca::poupanca6din +uantia*float ta)ap*data dd7: conta6+uantia*ta)ap*&nulo*dd7 Kani(ersarioMddF computarMW!5"F ultimoMabs6+uantia7FLF ^oolean poupanca::computa6data dd7 K if 6ani([email protected]@dia677 if 6computar7 KsaldoMultimoU&urosp'saldoFreturn W!5"FL else K computarMW!5"F ultimoMabs6saldo7F L return FA?3"F L din poupanca::get@saldo6data dd7const Kreturn saldoFL float poupanca::get@&urosp6data dd7const K return &urospF L float poupanca::get@&urosn6data dd7const K return &urosnF L ^oolean poupanca::deposita6din +uantia*data dd7 K saldo'Mabs6+uantia7F return W!5"FL din poupanca::saca6din +uantia*data dd7 K if 66saldo2abs6+uantia77I(a0io7 Ksaldo2Mabs6+uantia7F computarMFA?3"F return +uantiaFL else return (a0ioF L contacorrente::contacorrente6din +uantia*float ta)an*din min*data dd7: conta6+uantia*&nulo*ta)an*dd7 Kif 6minH(a0io7 limMminF else limM2minFL ^oolean contacorrente::computa6data dd7 JJso computo &uros negati(os. K if 6saldoH(a0io7 saldoMsaldoU&urosn'saldoF else saldoMsaldoU&urosp'saldoF return W!5"F L din contacorrente::get@saldo6data dd7 const Kreturn saldoFL float contacorrente::get@&urosn6data dd7 const Kreturn &urosnFL float contacorrente::get@&urosp6data dd7 const Kreturn &urospFL ^oolean contacorrente::deposita6din +uantia*data dd7 K saldo'M+uantiaF return W!5"F L din contacorrente::saca6din +uantia*data dd7 K +uantiaMabs6+uantia7F if 66saldo2+uantia7Ilim7 K saldo2M+uantiaF return +uantiaFL else return (a0ioF L JJmain file. Ginclude Hiostream.I Ginclude =conta;.= main67 K data o&e6Y*:N*CX7F contacorrente minacc6:<DN.<D*N.:*2XNN.N*o&e7F poupanca minap6:XNN.NN*N.:*o&e7F cout HH =3aldo:= HHminacc.get@saldo6o&e7HHendlF minacc.deposita6:N.NN*o&e7F cout HH =3aldo apos depositar :N.NN:=HHminacc.get@saldo6o&e7HHendlF minacc.computa6o&e7F cout HH =3aldo apos computar:= HHminacc.get@saldo6o&e7HHendlF minacc.saca6:XNN.NN*o&e7F cout HH =3aldo apos sacar:= HH minacc.get@saldo6o&e7HHendlF minacc.computa6o&e7F cout HH =3aldo apos computar:= HH minacc.get@saldo6o&e7 HHendlF cout HH =Wa)a de &uros:= HH minacc.get@&urosn6o&e7HHendlF cout HH endlF cout HH =Agora a poupanca:=F cout HH =3aldo apos criacao:= HH minap.get@saldo6o&e7 HH endlF cout HH =auros de saldo positi(o:= HH minap.get@&urosp6o&e7HH endlF cout HH =Computando:= HH endlF minap.computa6o&e7 F cout HH =3aldo apos computa:= HH minap.get@saldo6o&e7 HH endlF cout HH =!etirando XNN.NN:= HHendlF minap.saca6XNN.NN*o&e7 F cout HH =3aldo apos retirada:= HH minap.get@saldo6o&e7 HH endlF cout HH =Computando:=HHendlF minap.computa6o&e7F cout HH =3aldo apos computa:= HH minap.get@saldo6o&e7 HH endlF cout HH =Depositando:NN e Computando:=HHendlF minap.deposita6:NN.NN*o&e7F minap.computa6o&e7F cout HH =3aldo apos computa:= HH minap.get@saldo6o&e7 HH endlF cout HH =!etirando mais do +ue pode:;NNN.NN= HH endlF minap.saca6;NNN.NN*o&e7F cout HH =3aldo apos saca ;NNN.NN:= HH minap.get@saldo6o&e7 HH endlF return NF L Re"$%&'(! (e &e"&e (! )r!*r'+': 3aldo::<DN.<D 3aldo apos depositar :N.NN::<XN.<D 3aldo apos computar::<XN.<D 3aldo apos sacar:2:DC.YY 3aldo apos computar:2:YD.Y;Y Wa)a de &uros:N.: Agora a poupanca:3aldo apos criacao::XNN auros de saldo positi(o:N.: Computando: 3aldo apos computa::YXN !etirando XNN.NN: 3aldo apos retirada:::XN Computando: 3aldo apos computa:::XN Depositando:NN e Computando: 3aldo apos computa::<YX !etirando mais do +ue pode:;NNN.NN 3aldo apos saca ;NNN.NN::<YX C!+e,&-r!": Obser(e +ue ob&etos da classe base n%o podem ser criados* (oc/ n%o pode ter um ob&eto instanciado* mas ela pode ser usada. Declarar um ponteiro: conta' * n%o significa criar um ob&eto. "sse ponteiro pode referenciar +ual+uer ob&eto da ierar+uia 6conta corrente * poupan$a7 * (eremos seu uso mais tarde. C$r!"('(e: .e&a a importAncia da cria$%o de componentes de soft\are seguros* de f-cil modifica$%o e reutili0-(eis: Muitos programas +ue tinam +ue fa0er uma representa$%o de datas est%o sendo re(istos de(ido a mudan$a do sculo e outros pro(a(elmente falar%o de(ido a esta mudan$a. 3e&a pela restri$%o da fai)a de (alores de anos com m-)imo em ;NNN ou mesmo por outros moti(os +ue n%o le(assem este fator em conta* como a subtra$%o entre dois anos distintos e)emplo ;NN: e :CCC arma0enados na forma N: e CC. O e)erccio X pede +ue (oc/ melore a classe data apresentada neste e)emplo. Com um pou+uino de pes+uisa (oc/ pode criar meios de cecar anos bisse)tos 6dD7* meses com nBmeros de dias diferentes e =(iradas= de sculo. Exercc!": :7.oc/ seria capa0 de usando princpios de agrega$%o implementar uma estrutura de arma0enamento 6lista* (etor7 na classe conta e us-2la para sal(ar as opera$#es de modo +ue esta estrutura representasse o e)trato> De +ue modo esta idia pode ser adaptada para criar estruturas +ue fa0em um ist4rico das fun$#es membro camadas para classes +uais+uer> .oc/ pode usar este tipo de informa$%o da classe de arma0enagem para debugar seus programas> U;7Por+ue n%o ou(e preocupa$%o de esconder fun$#es membro como coputa> Algum poderia computar &uros infinitamente em sua pr4pria conta..... Para responder pense no seguinte: 5ma pessoa cliente de uma conta ou de um banco> 5m banco mantm uma conta ou uma pessoa mantm uma conta> Monte um diagrama de ob&etos contendo um banco* (-rias contas * (-rias pessoas e as respecti(as associa$#es. <7Modifi+ue este programa* implemente outros tipos de contas +ue (oc/ conece. D7Ap4s ler o t4pico de tratamento de e)ce$#es* adicione =e)ception andling= para argumentos in(-lidos tipo inhaconta"deposita(+1$"F) S X7Modifi+ue a classe data* crie restri$#es para datas in(-lidas e outras fun$#es membro +ue &ulgar importantes como/ print_data()" .e&a coment-rio neste e)emplo. 6.#.9. LISTA <ETEROGLNEA DE CONTAS BANCHRIAS. ?ista eterog/nea de contas banc-rias de e)emplo anterior* obten$%o do saldo total das contas corrente e poupan$as da lista 6no caso (etor7. TI)c!" '5!r('(!": "Dynamic binding=* n%o aborda type casting* (ai ser abordado num programa mais completo: a simula$%o dirigida a e(entos de D.Y.; . JJprograma principal Ginclude Hiostream.I Ginclude =conta;.= JJJ const int tamanoM<F main67 K din somaMN.NF contacorrente cc:6XNN.NN*N.:*2DNN7F JJ3A?DO*a5!O3*?9M9W" 1"] contacorrente cc;6XNN.NN*N.:X*2DNN7F poupanca p:6XNN.NN*N.:7F JJ3A?DO* a5!O3 contaU leterogeneahtamanoiMKjcc:*jcc;*jp:LF JJlista eterogenea for 6int iMNFiHtamanoFi''7 soma'Mleterogeneahii2Iget@saldo6ddef7F cout HH =Wotal arma0enado nas contas:= HH soma HHendlF return NF L Exercc!": :7Melore o e)emplo de lista eterog/nea dado usando uma lista com =templates= de D.<..oc/ de(e definir a lista para trabalar com ponteiros de contas. ;7 Considere as seguintes declara$#es em C'': class W K public: (irtual (oid f6(oid7 Kcout HH ="stou em W=FL LF class 3:public W K public: (irtual (oid f6(oid7 Kcout HH ="stou em 3=FL LF W )F JJ(aria(el est-tica 3 yF JJ(aria(el estatica* s de subclasse WU pF JJapontador para tipo base t. e as seguintes in(oca$#es de opera$#es: pMj) F p2If67F JJprimeira pMjyF p2If67F JJsegunda ).f67F JJterceira y.f67F JJ+uarta )MyF ).f67 JJ+uinta !esponda +ual o resultado na tela de cada uma destas camadas. 9. TQPICOS A8ANADOS W4picos a(an$ados apresenta recursos e)tremamente Bteis para programa$%o orientada a ob&etos* por isso con(m ler este t4pico somente +uando (oc/ ti(er uma boa base de programa$%o C''. Ad+uira pr-tica. A ordem em +ue os e)emplos s%o apresentados semelante a ordem de t4picos inicial. Como t4pico a(an$ado de "ncapsulamento temos friends* como t4pico a(an$ado de eran$a temos eran$a mBltipla* como t4pico a(an$ado de polimorfismo* temos polimorfismo paramtrico. Os demais t4picos n%o est%o diretamente relacionados com os anteriores. 9.1. FRIENDS 9riends permite +ue uma classe toda ou uma fun$%o membro acesse atributos encapsulados de outra classe. Por este moti(o* friends representa uma +uebra do encapsulamento e de(e portanto ser usado com muita cautela. 1%o raro programadores descobrem +ue o uso de certos princpios de orienta$%o a ob&etos e(ita programar usando demasiadamente friends. 3e (oc/ (ai aplicar este recurso* analise bem as outras possibilidades* ce+ue outras abordagens antes. 1o(amente nos deparamos com um +ualificador ou =specifier=* mas este tem uma diferen$a* n%o basta di0er +ue uma classe ou fun$%o membro amiga* 4friend4, preciso di0er de +ue classe ela amiga 9riends muito usado em con&unto com operadores. Operadores s%o fre+uentemente usados para implementar opera$#es entre tipos en+uanto +ue fun$#es membro comuns s%o mais usadas para passagem de mensagens alterando o estado de um Bnico ob&eto* segundo alguns parAmetros* normalmente tipos simples. 9.1.1. UMA CLASSE PERMITINDO ACESSO A OUTRA 3upona +ue (oc/ est- trabalando em con&unto com um colega no desen(ol(imento de um soft\are. .oc/ fa0 a interface gr-fica en+uanto +ue seu colega est- implementado as classes estritamente usu-rias da interface gr-fica. Como seu colega n%o sabe usar sua interface gr-fica ainda* ele define algumas classes dele como friends de suas classes de cai)as de di-logos e &anelas. Assim (oc/ gana acesso as defini$#es private e pu)lic dele nas suas classes. "le s4 precisa perguntar a (oc/ +uais os nomes das suas classes. Como (oc/ desconece a implementa$%o das classes de seu colega* ele define pensando em (oc/ e tambm por ra0#es de portabilidade* fun$#es membro +ue retornam os dados membros mais Bteis aos usu-rios das classes. Porm estas fun$#es n%o retornam todos os dados membros por+ue alguns ob&etos +ue ele est- definindo s%o estruturas de aloca$%o dinAmica como -r(ores e muito difcil pre(er +ue tipo de acesso ser- feito nas estruturas. "ste o tema do e)emplo seguinte* s4 +ue n%o iremos definir nenuma interface gr-fica* (amos apenas usar cout simulando uma sada de tela mais complicada* como por e)emplo numa cai)a de dialogo. 1osso ob&eto n%o define estruturas de aloca$%o dinAmica nenuma* afinal o e)emplo tem +ue ser simples e ob&eti(o. Ginclude Hiostream.I class relogio K friend class cai)a@de@mensagemF JJpermitiu acesso as definicoes pri(ate e public pri(ate: int oraF int minutoF int segundoF JJatributos pri(ate* encapsulados public: relogio6int *int m*int s7 KoraMF minutoMmF segundoMsFL L F class cai)a@de@mensagemK public: (oid imprime6relogio a7 K cout HH a.ora HH =:= HH a.minuto HH =:= HH a.segundo HH endlF L L F (oid main67 K relogio meurole)6::*<N*:N7F cai)a@de@mensagem ati(aF ati(a.imprime6meurole)7F L Re"$%&'(! (! )r!*r'+': :::<N::N C$r!"('(e: ")istem =libraries= em C'' +ue permitem programar em ambientes gr-ficos como o [indo\s sem saber muitos detales. "stas =libraries= definem ob&etos como cai)as de dialogo* gerenciadores de e(entos* etc. O uso agora diferente do descrito no e)emplo: O programador s4 (ai utili0ar os recursos gr-ficos padr%o definidos pela =libraries=. Os ob&etos definidos para uso na interface gr-fica s%o agregados ao seu programa e podem ser camados de dentro das implementa$#es das fun$#es membro das suas classes. Exercc!": U:7Defina um iterador para a classe lista* assim como foi definido para a classe (etor em <.:.Y. .oc/ pro(al(elmente ter- +ue usar no$#es de classes friends. Como e(itar corromper o estado da lista entre acessos a posi$#es e incrementos do iterador alternados> 5ma sugest%o proibir as fun$#es membro insere incio* insere Bltimo* en+uanto se fa0 uso do iterador. "ste um e)erccio a(an$ado. Outra sugest%o deri(ar uma classe a partir da base da ierar+uia* e para esta classe definir o iterador. ;75m bom e)emplo de uso de friends o seguinte: supona uma classe +ue representa uma reta em tr/s dimens#es* e outra +ue representa um plano. 5se friends para criar em uma dessas classes* ou em ambas* um a fun$%o membro +ue determina o ponto de interse$%o entre uma reta e um plano. 3e (oc/ gosta de computa$%o gr-fica* ent%o e)iste uma srie de tipos abstratos de dados +ue (oc/ pode definir para construir seus programas em C''. Algum pode argumentar +ue a interse$%o descrita acima poderia ser obtida sem o uso de friends* isto por+ue os dados membros das classes usados para calcular a interse$%o poderiam ser lidos* obtidos atra(s de fun$#es membro do tipo / get_x();. 9sto (erdade* mas em termos de efici/ncia* tal(e0 n%o de encapsulamento friends melor. ")pli+ue por+ue. <7 .oc/ se lembra do e)emplo das contas banc-rias> Melore este programa implementado a fun$%o de transfer/ncia de +uantias entre contas* (oc/ aca melor defini2la como friend> Por+ue> 8uantas contas ela afeta> D7Defina a classe banco como friend de todas as classes conta banc-ria. Muito bem* dei)e como private todos os mtodos +ue o dono da conta so0ino n%o pode camar* tais como coputa. O banco de(e conter refer/ncias para todas suas contas* as contas de(em ter um nBmero identificador de conta. As opera$#es sobre contas de(em ser feitas agora (ia banco* isto n%o impede +ue as contas atendam a opera$#es usuais como deposita* mas elas tem +uer ser pri(ate agora.. .e&a <.;.<. 9.1.#. OPERADORES E FRIENDS .amos tomar o e)emplo do tipo abstrato de dados fra$%o de :.D.: e acrescentar sobrecarga de operador e fun$#es friends. Fica faltando somente tratamento de e)ce$#es +ue sugerido como e)erccio no captulo respecti(o. TI)c!" '5!r('(!": 3obrecarga de operador* =copy constructor= *fun$#es friends. , uma implementa$%o bastante completa e port-(el de um WAD* use como refer/ncia para sinta)e de sobrecarga de operadores. JJ"ste programa implementa o tipo fracao. Gifndef OF@Z JJdireti(as do compilador Gdefine OF@Z long mdc6long n*long d7 JJma)imo di(isor comum JJmetodo de "uclides K if 6nHN7 nM2nF if 6dHN7 dM2dF \ile 6dSMN7 K long rMn d dF JJ dMMOD nMdF dMrF L return nF LF class fracao K pri(ate: long numF long denF public: (oid simplifica6(oid7F JJsimplificacao fracao6fracao jt7F JJcopy constructor fracao67 KnumMNF denM:FL JJconstrutor (a0io. fracao6const long t*const long m7F fracao6const long t7 KnumMtFdenM:FL `fracao67 KLF JJ1ao precisa fa0er nada long get@num6(oid7 Kreturn numFL long get@den6(oid7 Kreturn denFL JJoperacoes matematicas basicas friend fracao operator' 6const fracaoj f*const fracaoj &7F friend fracao operator2 6const fracaoj f*const fracaoj &7F friend fracao operatorU 6const fracaoj f*const fracaoj &7F friend fracao operatorJ 6const fracaoj f*const fracaoj &7F JJoperadores de comparacao friend int operatorMM 6const fracaoj s*const fracaoj t7F friend int operatorSM 6const fracaoj s*const fracaoj t7F friend int operatorIM 6const fracaoj s*const fracaoj t7F friend int operatorHM 6const fracaoj s*const fracaoj t7F friend int operatorI 6const fracaoj s*const fracaoj t7F friend int operatorH 6const fracaoj s*const fracaoj t7F JJoperadores de atribuicao fracaoj operatorM 6const fracaoj t7F fracaoj operator'M 6const fracaoj t7F fracaoj operator2M 6const fracaoj t7F fracaoj operatorUM 6const fracaoj t7F fracaoj operatorJM 6const fracaoj t7F JJoperadores de input output friend istreamj operatorII 6istreamj ci*fracaoj f7F friend ostreamj operatorHH 6ostreamj co*const fracaoj f7F JJoperadores de con(ersao de tipos operator double67 constF operator float67 constF operator long67 constF operator int67 constF LF Gendif JJcodigo para a classe fracao Ginclude Hiostream.I Ginclude Hmat.I Ginclude Hiomanip.I Ginclude Hstdio.I Ginclude =of.= fracao::fracao6fracao jt7 JJcopy constructor K numMt.numF denMt.denF L (oid fracao::simplifica6(oid7 K long commdF commdMmdc6num*den7F JJdi(isor comum numMnumJcommdF denMdenJcommdF if 6denHN7 K denM2denF numM2numFLF JJmo(e o sinal pJ cima L fracaoj fracao::operator'M 6const fracaoj t7 K numMnumUt.den'denUt.numF denMdenUt.denF simplifica67F return UtisF L fracao::fracao6const long t*const long m7 K numMtF denMmF simplifica67F JJtis2Isimplifica L fracao operatorJ 6const fracaoj f*const fracaoj &7 K fracao g6f.numU&.den*f.denU&.num7F g.simplifica67F JJesse metodo nao pertence a g* mas ela cama JJg.simplifica67F isto eR permitido a+ui mesmo com simplifica JJcomo pri(ate. return gF L fracao operator' 6const fracaoj f*const fracaoj &7 K fracao g66f.numU&.den7'6f.denU&.num7*&.denUf.den7F JJretorna (aria(el g.simplifica67F return gF L fracao operator2 6const fracaoj f*const fracaoj &7 K fracao g66f.numU&.den726f.denU&.num7*&.denUf.den7F JJretorna (aria(el g.simplifica67F return gF L fracao operatorU 6const fracaoj f*const fracaoj &7 K fracao g6f.numU&.num*f.denU&.den7F JJ6f.numU&.num7J6f.denU&.den7 g.simplifica67F return gF L ostreamj operatorHH 6ostreamj co*const fracaoj f7 K co HH =6= HH f.num HH =J= HH f.den HH =7=F return coF L istreamj operatorII 6istreamj ci* fracaoj f7 K long gcdi(F JJmelorar* ler mais sobre cin. ci II f.num II f.denF gcdi(Mmdc6f.num*f.den7F f.numMf.numJgcdi(F f.denMf.denJgcdi(F return ciF L int operatorMM 6const fracaoj s*const fracaoj t7 K return 66s.numUt.den7MM6s.denUt.num77F JJ(e&a operacoes matematicas com fracao L int operatorSM 6const fracaoj s*const fracaoj t7 K return 66s.numUt.den7SM6s.denUt.num77F L int operatorHM 6const fracaoj s*const fracaoj t7 K return 66s.numUt.den7HM6s.denUt.num77F L int operatorH 6const fracaoj s*const fracaoj t7 K return 66s.numUt.den7H6s.denUt.num77F L int operatorI 6const fracaoj s*const fracaoj t7 K return 66s.numUt.den7I6s.denUt.num77F L int operatorIM 6const fracaoj s*const fracaoj t7 K return 66s.numUt.den7IM6s.denUt.num77F L fracaoj fracao::operatorM 6const fracaoj t7 JJe+ui(ale a copy constructor K numMt.numF denMt.denF return UtisF L fracaoj fracao::operator2M 6const fracaoj t7 K numMnumUt.den2denUt.numF denMdenUt.denF simplifica67F return UtisF JJponteiro para o proprio ob&eto 6o apontado por tis7 L fracaoj fracao::operatorUM 6const fracaoj t7 K numMnumUt.numF denMdenUt.denF simplifica67F return UtisF L fracaoj fracao::operatorJM 6const fracaoj t7 K numMnumUt.denF denMdenUt.numF simplifica67F return UtisF L fracao::operator double67 const K double dblF dblM6double6num7Jdouble6den77F return dblF L fracao::operator float67 const K float fltF fltM6float6num7Jfloat6den77F return fltF L fracao::operator long67 const K long lngF lngMnumJdenF return lngF L JJcon(erte fracao para long fracao::operator int67 const K int ntgrF ntgrMint6numJden7F return ntgrF L JJprograma principal* testes e demonstracao Ginclude Hiostream.I Ginclude =of.= JJdefinicao da fracao Ginclude Hstdio.I main67 K car gF cout HH = "ntre com fracao a: =F fracao a*bF cin II aF coutHH =a=HH a HH =Pn=F cout HH = "ntre fracao b:=F cin II bF cout HH =b= HH b HH =Pn=F fracao cF cMa'bF cout HH =cMa'b = HH c HH =Pn=F fracao d6c7F cout HH =fracao d6c7=HH d HH endlF JJeR o +ue camamos de copy constructor cout HH =aUb = HH 6aUb7HH =Pn=F cout HH =a2b = HH 6a2b7HH =Pn=F cout HH =aJb = HH 6aJb7HH =Pn=F cout HH =aIb = HH 6aIb7HH =Pn=F cout HH =aHb = HH 6aHb7HH =Pn=F cout HH =aHMb = HH 6aHMb7HH =Pn=F cout HH =aIMb = HH 6aIMb7HH =Pn=F cout HH =aMMb = HH 6aMMb7HH =Pn=F cout HH =aSMb = HH 6aSMb7HH =Pn=F cMaF aUMbF cout HH =aUMb = HH aHH =Pn=F aMcF aJMbF cout HH =aJMb = HH aHH =Pn=F aMcF a'MbF cout HH =a'Mb = HH a HH =Pn=F aMcF a2MbF cout HH =a2Mb = HH aHH =Pn=F aMcF cout HH =long6a7 = HH long6a7 HH =Pn=F cout HH =double6a7 = HH double6a7 HH =Pn=F cout HH =int6a7 = HH int6a7 HH =Pn=F cout HH =float6a7 = HH float6a7 HH =Pn=F cin II gF return NF L Re"$%&'(! (! )r!*r'+': "ntre fracao a:C E a6CJE7 "ntre fracao b:C D b6CJD7 cMa'b 6;_JE7 fraction d6c76;_JE7 aUb 6E:J<;7 a2b 62CJE7 aJb 6:J;7 aIb N aHb : aHMb : aIMb N aMMb N aSMb : aUMb 6E:J<;7 aJMb 6:J;7 a'Mb 6;_JE7 a2Mb 62CJE7 long6a7 : double6a7 :.:;X int6a7 : float6a7 :.:;X Re"$%&'(! (! )r!*r'+': "ntre fracao a:: ; a6:J;7 "ntre fracao b:X < b6XJ<7 cMa'b 6:<JY7 fraction d6c76:<JY7 aUb 6XJY7 a2b 62_JY7 aJb 6<J:N7 aIb N aHb : aHMb : aIMb N aMMb N aSMb : aUMb 6XJY7 aJMb 6<J:N7 a'Mb 6:<JY7 a2Mb 62_JY7 long6a7 N double6a7 N.X int6a7 N float6a7 N.X Exercc!": :7Defina um tipo abstrato de dados matri0 6do campo da matem-tica7 com sobrecarga de operadores +ue permita acessar (ia ndice linear ou linaJcoluna +ual+uer elemento da matri0. Defina outras fun$#es membro +ue acar importantes. Por eran$a* construa a classe matri0 +uadrada* defina a fun$%o membro transposta para esta matri0. Dependendo doas fun$#es membro +ue (oc/ implementar a(er- bastante trabalo referente a tratamento de e)ce$#es* por e)emplo: matri0es singulares n%o s%o in(ers(eis* e)istem restri$#es para a multiplica$%o e at mesmo para a soma e subtra$%o (isto +ue as dimens#es nas duas Bltimas opera$#es tem +ue ser iguais. 9.#. <ERANA MRLTIPLA =Zeran$a:mBltipla=3e nos e)emplos anteriores tnamos uma ierar+uia +ue se comporta(a da seguinte maneira: Agora teremos algo como:
ou entPo/ Wendo o seguinte significado: A classe erdeira tem comportamento* =bea(iour=* semelante ao das duas classes pais. 9.#.1. UM E:EMPLO SIMPLES. "ste e)emplo seria sobre como implementar uma ierar+uia semelante a ierar+uia :* mas n%o est- pronto ainda . Precisamos de sugest#es sobre e)emplos mais claros +ue um r-dio rel4gio ou um "stagi-rio !emunerado. O e)emplo seguinte supre a falta deste* mas o apredi0ado mas abrupto. 9.#.#. 8IRTUAL PUBLIC E RESOLUO DE CONFLITOS. !eferente ao diagrama ierar+uia de (eculos apresentado neste t4pico. O +ue este caso tem de no(o com rela$%o ao anterior +ue (eculo utilit-rio pode erdar as caractersticas de (eculo por dois ramos da =ierar+uia= de eran$a* como pre(enir os poss(eis conflitos decorrentes deste fato> 3imples* os pais de (eculo utilit-rio de(em receber (eculo 6a classe comum7 atra(s do +ualificador virtual pu)lic. "ste e)emplo tambm apresenta a estratgia para resolu$%o de conflitos de nomes em eran$a mBltipla* lembre2se +ue agora as classes pai podem ter nomes* identificadores em comum. 1esse caso usamos o operador de resolu$%o de escopo // * (e&a os coment-rios. TI)c!" '5!r('(!": !esolu$%o de conflitos +uando e)iste mais de um camino de eran$a para uma classe pai 6(eculo7* camada do construtor para essa classe pai nas classes filas. !esolu$%o de conflitos entre identificadores comuns. JJeader file class (eiculo K pri(ate: carU nomeF JJ+ualificacao do (eiculo int pesoF JJmassa do (eiculo int pF JJpotencia em p. public: (eiculo6carU n*int p*int 7F (oid altera@p6int en7F int retorna@p6(oid7F (oid altera@peso6int en7F int retorna@peso6(oid7F LF class (@passeio:(irtual public (eiculo K pri(ate: int (ol@intF JJ(olume interno. public: (@passeio6carU n*int p*int p*int (i7F (oid altera@(i6int en7F int retorna@(i6(oid7F float peso@pot6(oid7F JJrelacao peso potencia. LF class (@carga:(irtual public (eiculo K pri(ate: int cargaF JJcarga do (eiculo. public: (@carga6carU n*int p*int p*int c7F (oid altera@carga6int en7F int retorna@carga6(oid7F float peso@pot6(oid7F JJrelacao peso potencia* (eiculo carregado LF class (@utilitario:public (@passeio*public (@carga K pri(ate: JJ+ual+uer outro atributo unico de (@utilitario. public: (@utilitario6carU n*int p*int p*int (i*int c7F float peso@pot6(oid7F LF JJimplementation file Ginclude =multiple.= (eiculo::(eiculo6carU n*int p*int 7 K nomeMnF pesoMpF pMF L (oid (eiculo::altera@peso6int en7 K pesoMenFL int (eiculo::retorna@peso6(oid7 K return pesoF L (oid (eiculo::altera@p6int en7 K pMenF L int (eiculo::retorna@p6(oid7 K return pFL (@passeio::(@passeio6carU n*int p*int p*int (i7:(eiculo6n*p*p7 K (ol@intM(iF L (oid (@passeio::altera@(i6int en7 K (ol@intMenF L int (@passeio::retorna@(i6(oid7 K return (ol@intF L float (@passeio::peso@pot6(oid7 K return float6retorna@peso677Jfloat6retorna@p677F L (@carga::(@carga6carU n*int p*int p*int c7:(eiculo6n*p*p7 K cargaMcF L (oid (@carga::altera@carga6int en7 K cargaMenF L int (@carga::retorna@carga6(oid7 K return cargaF L float (@carga::peso@pot6(oid7 K return float6retorna@peso67'carga7Jfloat6retorna@p677F L (@utilitario::(@utilitario6carU m*int p*int p*int (i*int c7:(@carga6m*p*p*c7*(@passeio6m*p*p*(i7*(eiculo6m*p*p7 K JJo construtor (eiculo6m*p*p7 declarado a+ui e +ue (ale* JJos construtores (eiculo6m*p*p7 ierar+uia acima sao descartados L float (@utilitario::peso@pot6(oid7 K return (@carga::peso@pot67F L JJmain file Ginclude =multiple.= Ginclude Hiostream.I (oid main67 K (@passeio (:6=Woyota Corolla=*<NN*:<N*<7F cout HH (:.peso@pot67HHendlF (@utilitario (;6=Picc2up A=*DNN*:EN*;*DNN7F cout HH (;.peso@pot67HHendlF cout HH (;.retorna@peso67F L C!+e,&-r!": float (@utilitario::peso@pot6(oid7 K return (@carga::peso@pot67F L A fun$%o membro peso_pot est- presente em todas as classes da =ierar+uia=. 1a classe veiculo utilitario ela n%o precisa ser reimplementada* basta escoler se em termos de peso pot/ncia* veiculo utilitario de(e se comportar como veiculo de carga ou como veiculo de passeio. A escola do comportamento foi a de veiculo de carga* agora o +ue temos a fa0er camar a fun$%o membro peso_pot de veiculo de carga +ue &- est- implementada* o +ue fa0er para distinguir entre a fun$%o membro de mesmo nome da classe base veiculo de passeio> 5sa2se o operador de resolu$%o de escopo* mas agora acompanado do nome da classe base +ue se dese&a acessar: v_carga//peso_pot();. A mesma estratgia adotada para dados membros em conflito: noe_classe_pai//dado_e)ro_e_conflito; * neste caso os atributos em comum est%o na classe veiculo* topo da =ierar+uia=. Re"$%&'(! (! )r!*r'+': ;.<N_YC D.DDDDD DNN Exercc!": :7 Modifi+ue este e)emplo para +ue em (eculos com capacidade de carga (v_carga e v_utilitario) peso pot/ncia imprima a pot/ncia do (eculo carregado e tambm a pot/ncia do (eculo descarregado* bem como a categoria 6classe7 do (eculo. 9.6. POLIMORFISMO PARAM/TRICO STEMPLATET Polimorfismo paramtrico um recurso bastante Btil para e(itar redundAncia de c4digo* portanto se trata de um meio de reuso deste. , importante para criar famlias de classes ou fun$#es relacionadas. "ste recurso permite por e)emplo definir uma classe matri0 6do campo da matem-tica7 uma Bnica (e0 num =eader file= e utili0ar esta classe matri0 para matri0es de tipo float* tipo int ou long *etc. , muito importante e e)ist/ncia de um comportamento uniforme entre os tipos +ue ser%o instanciados* por e)emplo se na sua classe matri0 (oc/ usa o operador d* todos os tipos a serem instanciados 6susbtitudos como tipo usado na matri07 de(em atender da maneira dese&ada a esse operador. "m linguagens orientadas a ob&etos +ue n%o definem sobrecarga de operador 6M4dula2 <7 surge um problema: supona +ue (oc/ definiu o tipo fra$%o e +uer usar em sua matri0 de tipos parametri0ados tanto o tipo fra$%o +uanto o tipo inteiro. Como uniformi0ar o comportamento desses tipos no +ue se refere a opera$%o de soa usada na classe matri0> 5ma solu$%o redefinir o tipo inteiro oferecido pela linguagem de modo +ue ele atenda a fun$%o membro de mesmo nome usada no tipo fra$%o* e)emplo a fun$%o soa(novo_inteiro a);" 9.6.1. TAD 8ETOR Modifica$%o do programa (etor de :.X.<.Y para suportar polimorfismo paramtrico (teplate)" 5ma condi$%o para +ue o polimorfismo paramtrico funcione bem : Os tipos +ue s%o substitudos no teplate de(em se comportar de maneira uniforme para e)emplificar isso (amos substituir no template da classe (etor o tipo fra$%o com sobrecarga de operadores de D.:.; e o tipo float. Foi proposta a implementa$%o do tipo abstrato de dados string* uma boa indica$%o da +ualidade de sua implementa$%o uma substitui$%o no template deste e)emplo sem acarretar modifica$#es* isto s4 (ale se nessa implementa$%o &- foi feita sobrecarga de operadores 6compara$%o entre strings7. Dica de implementa$%o: 3e (oc/ dese&a fa0er um programa +ue use =templates= seguir os passos indicados abai)o normalmente le poupar- tempo: 2Defina os tipos +ue (oc/ +uer parametri0ar um termos de camadas de fun$#es membro e operadores de nomes e sinta)e iguais 6uniformidade7. Os tipos dos argumentos (%o (ariar. 2Construa seu programa para operar em um s4 destes tipos. 2Wermine incluindo as defini$#es dos templates no programa e testando para os demais tipos. 2Corri&a as e(entuais falas de substitui$%o. JJtemp(et. definicao da classe (etor com template. Ginclude Hstdlib.I JJeader file para classe (etor const int inicioMNF templateHclass WI class (etorK JJW eR o tipo do elemento do (etor pri(ate: WU (F JJpode ser +ual+uer tipo +ue atenda as operacoes H I M int tamanoF public: (etor 6int tamano7 F Wj operatorhi 6int i7F W ma)imo67F int primeiro6(oid7F int ultimo6(oid7F LF templateHclass WI (etorHWI::(etor 6int tam7 K(Mne\ WhtamiF tamanoMtamFL templateHclass WI int (etorHWI::primeiro 6(oid7 Kreturn inicioFL templateHclass WI int (etorHWI::ultimo 6(oid7 K return tamano2:F L templateHclass WI Wj (etorHWI::operatorhi6int i7 K if 6iHN kk iIMtamano7 Kcout HH =Fora dos limitesS=F e)it6:7FL JJuse e)ception andling to mace it cecc bounds for you. return (hiiF L templateHclass WI W (etorHWI:: ma)imo6(oid7 Kint candidatoMinicioF for 6int iMinicioFiHtamanoFi''7 if 6(hiiI(hcandidatoi7 candidatoMiF return (hcandidatoiFL Ginclude Hiostream.I Ginclude =e)(et<.= main67 K (etorHfloatI meu6X7F for 6int iMmeu.primeiro67FiHMmeu.ultimo67Fi''7 K cout HH ="ntre com (alor da posicao:= HH i HH =Pn=F cin II meuhiiF L for 6int &Mmeu.primeiro67F&HMmeu.ultimo67F&''7 coutHH meuh&iHH = =F cout HH endl HH =Ma)imo:= HH meu.ma)imo67F return NF L JJmain file* programa principal Ginclude Hiostream.I Ginclude =e)(et<.= Ginclude =fractio;.= Ginclude =fractio;.cpp= main67 K (etorHfractionI meu6X7F for 6int iMmeu.primeiro67FiHMmeu.ultimo67Fi''7 K cout HH ="ntre com (alor da posicao:= HH i HH =Pn=F cin II meuhiiF L for 6int &Mmeu.primeiro67F&HMmeu.ultimo67F&''7 coutHH meuh&iHH = =F cout HH endl HH =Ma)imo:= HH meu.ma)imo67F return NF L C!+e,&-r!": 3e (oc/ substitusse no template do (etor o tipo fra$%o +ue (amos definido em D.:.;* o resultado seria igual ao apresentado no sub2t4pico resultado do programa em coment-rios. 9sto s4 a ttulo de curiosidade. .oc/ n%o precisa tentar implementar um tipo fra$%o para uso neste teplate ainda. Re"$%&'(! (e &e"&e (! )r!*r'+' e+ c!+e,&-r!": "ntre com (alor da posicao:N : ; "ntre com (alor da posicao:: X D "ntre com (alor da posicao:; Y : "ntre com (alor da posicao:< ; E "ntre com (alor da posicao:D D ; 6:J;7 6XJD7 6YJ:7 6:JD7 6;J:7 Ma)imo: 6YJ:7 Re"$%&'(! (! )r!*r'+' c!+ ! &)! 1%!'& )'r'+e&rN'(!: "ntre com (alor da posicao:N :.; "ntre com (alor da posicao:: ;.: "ntre com (alor da posicao:; X.< "ntre com (alor da posicao:< :.X "ntre com (alor da posicao:D :.C :.; ;.: X.< :.X :.C Ma)imo:X.< Exercc!": :7Crie uma fun$%o membro troca +ue recebe como argumentos dois ndices do (etor e fa0 a troca deles. 9.6.#. TEMPLATE DE FUNO Wemplate de fun$%o * introdu0iremos tipos parametri0ados na fun$%o mdc +ue calcula o m-)imo di(isor comum tanto para long +uanto para int e outros tipos +ue definam o operador d: JJe)emplo facil de templates de funcao Ginclude Hiostream.I templateHclass WI W mdc6W n*W d7 JJma)imo di(isor comum JJmetodo de "uclides K if 6nHN7 nM2nF if 6dHN7 dM2dF \ile 6dSMN7 K W rMn d dF JJtemplate W dMMOD nMdF dMrF L return nF L (oid main6(oid7 K int aMXF long bMYF long cM_F int dM:DF cout HH =mdc6X*Y7M= HH mdc6a*Y7 HH =Pn=F JJint int cout HH =mdc6;*<7M= HH mdc6;*<7 HH =Pn=F JJint int kk long long cout HH =mdc6Y*_7M= HH mdc6b*c7 HH =Pn=FJJlong long cout HH =mdc6_*:D7M= HH mdc6c*d7 HH =Pn=F JJlong int JJerroSSSS L JJ.ersao +ue nao produ0 erro. JJe)emplo facil de templates de funcao Ginclude Hiostream.I templateHclass WI W mdc6W n*W d7 JJma)imo di(isor comum JJmetodo de "uclides K if 6nHN7 nM2nF if 6dHN7 dM2dF \ile 6dSMN7 K W rMn d dF JJtemplate W dMMOD nMdF dMrF L return nF L long mdc6long m*long n7F JJdefinicao e)ata* long pre(alece sobre int em termos de con(ersao JJnao acrescente int mdc6int a*int b7F (oce tera ambiguidades e o compilador nao fara a JJcon(ersao (oid main6(oid7 K int aMXF long bMYF long cM_F int dM:DF cout HH =mdc6X*Y7M= HH mdc6a*Y7 HH =Pn=F JJint int cout HH =mdc6;*<7M= HH mdc6;*<7 HH =Pn=F JJint int kk long long cout HH =mdc6Y*_7M= HH mdc6b*c7 HH =Pn=FJJlong long cout HH =mdc6_*:D7M= HH mdc6c*d7 HH =Pn=F JJlong int Om* con(ersao. L C!+e,&-r!": 1a primeira (ers%o do programa tudo funciona bem* com e)ce$%o da Bltima lina* ela produ0 um erro +ue corrigido na segunda (ers%o do programa. .amos e)plicar esse erro: 8uando o compilador resol(e* decide* uma camada de fun$%o ele primeiro tentar acar uma defini$%o e)ata dela 6tipos &- definidos7 e)emplo long dc (int a,long ));" 3e n%o ou(er nenuma (ers%o e)ata o compilador tenta acar uma (ers%o com tipos paramtricos +ue aceite os tipos da camada da fun$%o* no caso uma defini$%o de template +ue aceitaria seria: teplate-class 31,class 316 31 ax(31 n,31 d) * +ue um tanto perigosa em termos de opera$#es entre tipos* por isso tambm n%o foi fornecida. 3e esta tentati(a tambm falar o compilador tenta fa0er a con(ers%o implcita do argumento de modo a satisfa0er uma defini$%o e)ata* essa con(ers%o n%o pode resultar numa ambiguidade. 1a segunda (ers%o fornecemos uma (ers%o e)ata: long dc (long a, long ));" somente* n%o dei)ando margens para ambiguidades. Exercc!": :7 5se um programa antigo feito em outra linguagem* ou mesmo em C. Wente identificar as poss(eis substitui$#es por tipos paramtricos +ue poderiam ser feitas com sucesso e seguran$a. "m +ue casos outras solu$#es seriam melores e mais seguras> 8ue solu$#es> ;7Perceba +ue nada impede +ue (oc/ came a fun$%o dc para dois argumentos float* o compilador e)ecuta de fato a camada e (ai acusar erro na opera$%o Q +ue n%o definida para este tipo. Por isso +ue se di0 +ue os tipos parametri0ados de(em se comportar de maneira uniforme* com opera$#es semelantes. Defina uma fun$%o de ordena$%o de (etor* com tipos paramtricos e +ue se baseie na e)ist/ncia em alguns dos operadores - , 6 , -# , 6# , ## nos tipos usados. Obser(e +ue se +uisssemos usar nosso tipo fracao nesta fun$%o teramos +ue definir o6s7 operador6es7 relacional6is7 usado6s7* . Para fa0er esta defini$%o (oc/ ter- ler D.:.;. <7"scre(a uma fun$%o troca com tipos parametri0ados. .oc/ de(e usar passagem por refer/ncia para trocar os dois argumentos do mesmo tipo parametri0ado +ue s%o passados: void troca (3 a,3 )); D7Mesmo +uando (oc/ n%o tem um moti(o imediato para utili0ar tipos parametri0ados em uma aplica$%o fa0 sentido fa0/2lo> 3e sim em +ue casos> 9.6.6. <ERANA E TEMPLATES. Modifica$%o do programa de listas ligadas de ;.:.D para suportar templates. "sta (ers%o usada em muitos outros e)emplos do tutorial. Gifndef M?93WZ@Z Gdefine M?93WZ@Z Ginclude Hstdlib.I Ginclude Hiostream.I JJCriacao de uma ierar+uia de listas ligadas. JJO elemento da lista eR um inteiro enum ^ooleanKFA?3"*W!5"LF template Hclass WIclass noK JJeste eR o no da lista ligada* so eR usado por ela pri(ate: W infoF JJinformacao noU pro)F JJponteiro para o pro)imo public: no67F no6W i*noU p7F noU get@pro)6(oid7F (oid set@pro)6noU p7F W get@info6(oid7F (oid set@info6W a7F noU dobra6(oid7F `no6(oid7F L F template Hclass WIclass listaK JJesta eR a lista ligada comum. protected: JJ=(isi(el ierar+uia abai)o= noHWIU primeiroF JJprimeiro no da lista* a+ui eu insiro e remo(o. public: lista6(oid7F lista6const listaHWIj lc7F JJcopy constructor. ^oolean (a0ia6(oid7constF ^oolean contem6W el7constF (oid insere@primeiro6W elem7F WU remo(e@primeiro67F (oid mostra67constF `lista6(oid7F LF JJfim classe lista template Hclass WIclass listaultimo:public listaHWI K JJessa e a lista util para JJimplementar pilas e filas. protected: JJprotected e uma opcao outra eR get@ultimo67 e set@... noHWIU ultimoF public: listaultimo6(oid7F listaultimo6const listaultimoHWIj lc7F JJredefinicao (oid insere@ultimo6W elem7F JJno(a (oid insere@primeiro6W elem7F JJredefinicao WU remo(e@primeiro67FJJredefinicao `listaultimo6(oid7F JJas operacoes nao redefinidas sao (alidas. LF template Hclass WIclass listaordenada:public listaHWI K JJessa eR a lista comum com aprimoramentos. public: listaordenada6(oid7F JJnao definimos copy constructor ^oolean contem6W el7constF (oid insere@primeiro6W elem7F JJinsere em ordem WU remo(e@elemento6W el7F `listaordenada6(oid7F LF templateHclass WInoHWI::no67 Kpro)M15??Fcout HH =Zi=FL templateHclass WInoHWI::no6W i*noU p7 KinfoMiFpro)MpFcout HH =Zi=FL templateHclass WI noHWIU noHWI::get@pro)6(oid7 Kreturn pro)FL templateHclass WI (oid noHWI::set@pro)6noU p7 Kpro)MpFL templateHclass WI W noHWI::get@info6(oid7 Kreturn infoFL templateHclass WI (oid noHWI::set@info6W i7 KinfoMiFL templateHclass WI noHWIU noHWI::dobra6(oid7 K if 6get@pro)67MM15??7 return ne\ noHWI6get@info67*15??7F else return ne\ noHWI6get@info67*tis2Iget@pro)672Idobra677F JJrecursi(idade para duplicacao da lista L templateHclass WI noHWI::`no6(oid7 Kcout HH =bye=FL JJbye e so para debugar* retire depois de compilado. templateHclass WI listaHWI::lista6(oid7:primeiro615??7 KL JJbloco de codigo (a0io templateHclass WI listaHWI::lista6const listaHWIj lc7 K primeiroMlc.primeiro2Idobra67F L templateHclass WI ^oolean listaHWI::(a0ia6(oid7const K return ^oolean6primeiroMM15??7F L templateHclass WI ^oolean listaHWI::contem6W el7 constJJmais rapido +ue iterador K noHWIU currF currMprimeiroF \ile 66currSM15??7 jj 6curr2Iget@info67SMel77 K currMcurr2Iget@pro)67F LF return ^oolean6curr2Iget@info67MMel7F L templateHclass WI (oid listaHWI::insere@primeiro6W elem7 K noHWIU insirameF if 6primeiroMM15??7 JJlista (a0ia primeiroMne\ noHWI6elem*15??7F else K insirameMne\ noHWI6elem*primeiro7F primeiroMinsirameF LF LF templateHclass WI WU listaHWI::remo(e@primeiro6(oid7 K WU de(ol(ameF JJreturn noHWIU tempF JJto delete if 6primeiroMM15??7 return 15??F JJlista (a0ia else K 6Ude(ol(ame7Mprimeiro2Iget@info67F tempMprimeiroF primeiroMprimeiro2Iget@pro)67F delete tempF return de(ol(ameF LF LF templateHclass WI(oid listaHWI::mostra67 const K noHWIU currF cout HH =M=F currMprimeiroF \ile 6currSM15??7 K cout HH=6=HHcurr2Iget@info67HH=7=HH=2=F currMcurr2Iget@pro)67F LF L templateHclass WIlistaHWI::`lista6(oid7 K noHWIU tempF \ile 6primeiroSM15??7 K tempMprimeiroF primeiroMprimeiro2Iget@pro)67F delete tempF LF L templateHclass WIlistaordenadaHWI::listaordenada6(oid7:listaHWI67 KLF templateHclass WI ^oolean listaordenadaHWI::contem6W el7const K noHWIU currF ^oolean contiMW!5"F currMprimeiroF \ile 66currSM15??7 jj conti7 K if 6curr2Iget@info67Hel7 currMcurr2Iget@pro)67F else contiMFA?3"F LF if 6currMM15??7 return FA?3"F else return ^oolean6curr2Iget@info67MMel7F L templateHclass WI(oid listaordenadaHWI::insere@primeiro6W elem7 K noHWIU currMprimeiroF noHWIU pre(M15??F noHWIU insirameF ^oolean contiMW!5"F \ile 66currSM15??7 jj conti7 K if 6curr2Iget@info67Helem7 Kpre(McurrF currMcurr2Iget@pro)67FL else contiMFA?3"F LF insirameMne\ noHWI6elem*curr7F if 6pre(MM15??7 primeiroMinsirameF else pre(2Iset@pro)6insirame7F L templateHclass WI WU listaordenadaHWI::remo(e@elemento6W el7 K WU de(ol(ameF noHWIU currMprimeiroF noHWIU pre(M15??F noHWIU deletemeF ^oolean contiMW!5"F \ile 66currSM15??7 jj conti7 JJaca lugar onde pode estar el K if 6curr2Iget@info67Hel7 Kpre(McurrF currMcurr2Iget@pro)67FL JJanda else contiMFA?3"F LF if 6currMM15??7 return FA?3"F JJfim de lista ou (a0ia else JJpode ser o elemento ou ele nao e)iste K if 6curr2Iget@info67MMel7 K deletemeMcurrF if 6pre(MM15??7 JJlista so com um elemento ou primeiro el primeiroMcurr2Iget@pro)67F else K pre(2Iset@pro)6curr2Iget@pro)677F L cout HH deleteme2Iget@info67HHendlF JJso para (erificar 6Ude(ol(ame7Mdelete2Iget@info67F delete deletemeF return de(ol(ameF L else return 15??F L L templateHclass WIlistaordenadaHWI::`listaordenada6(oid7 Kcout HH =?ista destruida.=FLF templateHclass WIlistaultimoHWI::listaultimo6(oid7:listaHWI67 K ultimoM15??F L templateHclass WIlistaultimoHWI::listaultimo6const listaultimoHWIj lc7 K noHWIU currF primeiroMultimoM15??F JJiniciali0a lista if 6Slc.(a0ia677 K currMlc.primeiroF \ile 6currSM15??7 K insere@ultimo6curr2Iget@info677F currMcurr2Iget@pro)67F L L L templateHclass WI(oid listaultimoHWI::insere@ultimo6W elem7 K noHWIU insirameF insirameMne\ noHWI6elem*15??7F if 6ultimoMM15??7 ultimoMinsirameF JJlista (a0ia else K ultimo2Iset@pro)6insirame7F ultimoMinsirameF LF if 6primeiroMM15??7 primeiroMultimoF JJlista (a0ia L templateHclass WI (oid listaultimoHWI::insere@primeiro6W elem7 JJredefinicao K noHWIU insirameF if 6primeiroMM15??7 JJlista (a0ia K primeiroMne\ noHWI6elem*ultimo7F ultimoMprimeiroF LJJlista (a0ia else K insirameMne\ noHWI6elem*primeiro7F primeiroMinsirameF LF L templateHclass WI WU listaultimoHWI::remo(e@primeiro67JJredefinicao K WU de(ol(ameF JJreturn noHWIU tempF JJto delete if 6primeiroMM15??7 return NF JJlista (a0ia else K 6Ude(ol(ame7Mprimeiro2Iget@info67F tempMprimeiroF primeiroMprimeiro2Iget@pro)67F delete tempF if 6primeiroMM15??7 ultimoM15??F JJ(olta lista (a0ia return de(ol(ameF LF L templateHclass WIlistaultimoHWI::`listaultimo6(oid7 K noHWIU tempF \ile 6primeiroSM15??7 K tempMprimeiroF primeiroMprimeiro2Iget@pro)67F delete tempF LF delete ultimoF L Gendif Ginclude =mlistt.= main67 K listaultimoHintI minaF listaultimoHintIU copiaF car optionF JJuse in menu as option (ariable car cpyoptF JJcopy option para copia int elF JJelemento a inserir do K cout HH=Pn=F JJmenu options display cout HH=P:9nsere no primeiro.Pn=F cout HH=!:!emo(e no primeiro.Pn=F cout HH=5:9nsere no ultimo.Pn=F cout HH=":")iste elemento>Pn=F cout HH=.:.a0ia>Pn=F cout HH=M:Mostra lista.Pn=F cout HH=C:Copia lista e mostra.Pn=F cout HH=8:8uit teste lista.Pn=F cout HH="ntre comando:=F cin II optionF JJreads user option s\itc6option7 JJe)ecutes user option K case RPR: case RpR: cout HH ="ntre elemento:=F cin IIelF mina.insere@primeiro6el7F breacF case R!R: case RrR: if 6Smina.(a0ia677 cout HH 6Umina.remo(e@primeiro677HHendlF else cout HH =15??* ?ista (a0ia.= HHendlF breacF case R5R: case RuR: cout HH ="ntre elemento:=F cin II elF mina.insere@ultimo6el7F breacF case RMR: case RmR: mina.mostra67F breacF case R"R: case ReR: cout HH ="ntre elemento:=F cin IIelF cout HH mina.contem6el7F breacF case R.R: case R(R: cout HH mina.(a0ia67F breacF case RCR: case RcR: copiaMne\ listaultimoHintI6mina7F copia2Imostra67F cout HH =Agora trabalando na lista copia.= HH endlF do K cout HH=Pn=F JJmenu options display cout HH=P:9nsere no primeiro.Pn=F cout HH=!:!emo(e no primeiro.Pn=F cout HH=5:9nsere no ultimo.Pn=F cout HH=":")iste elemento>Pn=F cout HH=.:.a0ia>Pn=F cout HH=M:Mostra lista.Pn=F cout HH=8:8uit teste lista copia>.olta lista anterior>.Pn=F cout HH="ntre comando:=F cin II cpyoptF JJreads user option s\itc6cpyopt7 JJe)ecutes user option K case RPR: case RpR: cout HH ="ntre elemento:=F cin IIelF copia2Iinsere@primeiro6el7F breacF case R!R: case RrR: if 6Scopia2I(a0ia677 cout HH 6Ucopia2Iremo(e@primeiro677HHendlF else cout HH =15??* ?ista (a0ia.= HHendlF breacF case R5R: case RuR: cout HH ="ntre elemento:=F cin IIelF copia2Iinsere@ultimo6el7F breacF case RMR: case RmR: copia2Imostra67F breacF case R"R: case ReR: cout HH ="ntre elemento:=F cin IIelF cout HH copia2Icontem6el7F breacF case R.R: case R(R: cout HH copia2I(a0ia67F breacF case R8R: case R+R: delete copiaF breacF default: F L JJs\itc2case code blocc L \ile 66cpyoptSMR8R7 jj 6cpyoptSMR+R77F breacF default: F L JJs\itc2case code blocc L \ile 66optionSMR8R7 jj 6optionSMR+R77F JJmenu loop code blocc return NF L JJmain code blocc Exercc!": :7Compare esta lista com 4teplates4 com outras listas implementadas sem tipos paramtricos. 8ue (antagens (oc/ pode apontar a n(el de independ/ncia entre as partes de um programa> Por+ue importante ma)imi0ar esta independ/ncia entre as partes de um programa> Outro e)erccio: Modifi+ue o programa lista-36 para trabalar com ponteiros -3'6 e(itando a copia de ob&etos grandes (isando assim maior efici/ncia. 9.6.9. TEMPLATES E AGREGAO 5sando o template definido no e)emplo dois criaremos uma classe pila e a testaremos de modo an-logo ao +ue foi feito em ;.; s4 +ue agora com templates e com uma pila e n%o fila. listh"h n%o ser- copiada* id/ntica a do e)emplo anterior de =templates=. Ginclude =mlistt.= templateHclass WIclass pila K JJagregacao de uma lista pri(ate: listaHWI alF JJa lista public: pila67F ^oolean (a0ia67F ^oolean contem6W el7F (oid insere6W el7F WU remo(e67F (oid mostra67F LF templateHclass WI pilaHWI::pila67KLF templateHclass WI ^oolean pilaHWI::(a0ia67 Kreturn al.(a0ia67FL templateHclass WI ^oolean pilaHWI::contem6W el7 Kreturn al.contem6el7FL templateHclass WI (oid pilaHWI::insere6W el7 Kal.insere@primeiro6el7FL templateHclass WI WU pilaHWI::remo(e67 Kreturn al.remo(e@primeiro67FL templateHclass WI (oid pilaHWI::mostra67 Kal.mostra67FL Ginclude =mpilat.= main67 K pilaHintI minaF car optionF JJuse in menu as option (ariable int elF JJelemento a inserir do K cout HH=Pn=F JJmenu options display cout HH=9:9nsere.Pn=F cout HH=!:!emo(e.Pn=F cout HH=M:Mostra pila.Pn=F cout HH=8:8uit pila test.Pn=F cout HH=.:.a0ia>Pn=F cout HH=C:Contem>Pn=F cout HH="ntre comando:=F cin II optionF JJreads user option s\itc6option7 JJe)ecutes user option K case R9R: case RiR: cout HH ="ntre elemento:=F cin IIelF mina.insere6el7F breacF case R!R: case RrR: if 6Smina.(a0ia677 cout HH 6U6mina.remo(e6777HHendlF else cout HH =15??* pila (a0ia.= HHendlF breacF case RCR: case RcR: cout HH ="ntre elemento:=F cin IIelF cout HH mina.contem6el7F breacF case RMR: case RmR: mina.mostra67F breacF case R.R: case R(R: cout HH =!esultado:= HH mina.(a0ia67 HHendlF breacF default: F L JJs\itc2case code blocc L \ile 66optionSMR8R7 jj 6optionSMR+R77F JJmenu loop code blocc return NF L JJmain code blocc Exercc!": :7Defina outras classes apresentadas em termos de templates* por e)emplo a classe conta . 3upona +ue (oc/ tem +ue fa0er um programa +ue usa a classe conta* mas n%o sabe ao certo se (ai usar o tipo float para representar o dineiro ou (ai usar algum outro tipo (dou)le) . 5se templates e defina este tipo somente +uanto as opera$#es. 9.9. METACLASSES Metaclasses arma0enam informa$#es sobre classes definidas pelo usu-rio e s%o comuns em algumas linguagens de programa$%o orientadas a ob&etos. "ssa informa$%o arma0enada a camada metainforma$%o. C'' n%o possui metaclasses* porm e)istem meios de arma0enar alguma metainforma$%o* um deles o uso de (ari-(eis do tipo static +ue guardam informa$#es sobre os (-rios ob&etos de uma mesma classe. A utilidade da metainforma$%o (asta. Por e)emplo um ar+ui(o +ue arma0ena uma imagem contm geralmente um cabe$alo sobre a imagem 6nBmero de =pi)els=* largura* altura* etc7. 1uma classe lista* pode ser considerado como meta2informa$%o: o nBmero de elementos* o estado: ordenado ou n%o* etc. "m bancos de dados muito comum se arma0enar meta2informa$%o nos ar+ui(os. 9.9.1. UM TIPO SIMPLES COMO STATIC 8uando se declara um atributo static em uma classe* todos os ob&etos instanciados tem uma refer/ncia para ele 6o mesmo atributo7* ou se&a ele pode ser modificado ou lido por fun$#es membro de todos os ob&etos desta classe. 1o e)emplo a seguir declaramos um atributo static inteiro +ue incrementado +uando o ob&eto criado 6construtor7 e decrementado +uando o ob&eto destrudo. "sse atributo static pode ser de +ual+uer tipo* pode ser at um ob&eto. .ari-(eis static ser(em para fa0er estatsticas sobre uma classe* tambm s%o ade+uadas para tornar informa$#es de um ob&eto dispon(eis para outros da mesma classe* elas continuam e)istindo 6conser(am seu (alor7 mesmo +ue n%o a&a nenum ob&eto instanciado e n%o destrudo 6(i(o7. O programa abai)o mostra como fa0/2lo* alive representa o nBmero de ob&etos da classe robot criados. .e&a +ue a declara$%o de ali(e segue a pala(ra static. Diagrama do atributo static ali(e* compartilado por (-rios robns: Ginclude Hiostream.I class robo K pri(ate: float )*yF static int (i(osF JJguarda numero de robos (i(os. public: robo6float )*float y7 K(i(os''FL JJcria robo (oid mo(e6float d)*float dy7 K)'Md)Fy'MdyFL static int get@(i(os6(oid7 Kreturn (i(osFL JJ+uantos (i(os `robo6(oid7 K(i(os22FL JJmata robo LF int robo::(i(osMNF JJiniciali0acao da (aria(el static. main67 K cout HH robo::get@(i(os67 HH endlF robo Ur:Mne\ robo6:.<*:.D7F JJcria robo : robo Ur;F cout HH r:2Iget@(i(os67 HH =Pn= F JJ: (i(o r;Mne\ robo6N.N*N.N7F JJcri robo ; cout HH r:2Iget@(i(os67 HH =Pn= F JJ; (i(os delete r:F JJcill robo : cout HH robo::get@(i(os67 HH =Pn= F JJ: (i(o r;2Imo(e6:;.D*;<.;7F JJmo(endo robo certa distancia. delete r;F JJmata robo ;. JJnenum robo (i(o cout HH robo::get@(i(os67 HH endlF return NF L Re"$%&'(! (! )r!*r'+': N : ; : N C!+e,&-r!": Obser(e o treco de c4digo: int ro)ot//alive#$; perceba +ue (oc/ de(e iniciali0ar o atributo antes da cria$%o de +ual+uer ob&eto. "sse tipo de acesso n%o permitido em ain(), mantendo assim o encapsulamento. 8uando os ob&etos s%o criados eles incrementam alive atra(s de seus construtores* e decrementam +uando s%o destrudos. ")iste uma fun$%o membro declarada como static: static int get_vivos(void) %return vivos;( esta fun$%o membro tem um tipo de acesso diferente dos outros * o seguinte treco de c4digo usado em nosso programa permitido: cout -- ro)o//get_vivos() -- endl;" Perceba +ue get_vivos camado sem o operador . ou +6* isto permitido por+ue get_vivos um fun$%o membro static* opera portanto sobre (ari-(eis static +ue podem e)istir antes da cria$%o do primeiro ob&eto da classe ou +uando nenum ob&eto est- ati(o. Exercc!": :7 1o lugar da (ari-(el inteira declarada como static faca a seguinte declara$%o: static ara2enage vivos; &&guarda nuero de ro)os vivos"" 9niciali0e tambm o ob&eto static camando seu construtor fora de main. 5ma poss(el defini$%o para a classe arma0enagem seria: class ara2enage % pri(ate: int numeroF public: arma0enagem67 KnumeroMNFL (oid arma0enagempp67 Knumero''FL (oid arma0enagemmm67 Knumero22FL int get@numero67 Kreturn numeroFL LF 1%o se es+ue$a de camar os fun$%o membros de arma0enagem nos construtores dos robos. ;75se (ari-(eis static em seus programas para +ue fa0em aloca$%o dinAmica para controlar o nBmero de ob&etos criados e n%o deletados. 5se por e)emplo o ob&eto lista de ;.:.D e (erifi+ue a importAncia desta tcnica para o desen(ol(imento de programas +ue se&am corretos no uso da mem4ria dinAmica 6eap7* principalmente em C'' +ue n%o fornece coleta autom-tica de li)o. 5sar tcnicas deste tipo em M4dula2< imposs(el por+ue a linguagem n%o suporta construtores e destrutores* porm a coleta autom-tica de li)o* =]arbage Collection= * &- fa0 grande parte do trabalo para o programador. "m C'' e)istem tcnicas a(an$adas de programa$%o para conseguir coleta autom-tica de li)o para alguns tipos* essas tcnicas se baseiam na camada de autom-tica de um destrutor +uando um ob&eto sai de escopo* e tambm no uso de =templates=. <7 ")iste uma linguagem de programa$%o camada ?ogo +ue muito usada no ^rasil em escolas de primeiro e segundo grau. 1esta linguagem (oc/ pode programar os mo(imentos na tela de uma tartarugina ou cursor. "ste cursor descre(e mo(imentos riscando ou n%o a tela* dentre os mo(imentos descritos est%o crculos* +uadrados e se+u/ncias repetiti(as 6loops7. Modifi+ue seu ob&eto robo para apresentar alguns desses recursos. Crie ent%o um programa +ue l/ de um ar+ui(o te)to instru$#es para este ob&eto robo e)ecutar mo(imentos na tela. ?ogo foi criada por um cientista de computa$%o do M9W. 9.9.#. UM TIPO DEFINIDO PELO USUHRIO USADO COMO STATIC Wrecos de um programa com um ob&eto static representando uma lista parametri0ada 6templates7. A estrutura poderia ser parametri0ada de modo a arma0enar informa$#es sobre os estados dos demais ob&etos* permitindo +ue eles reali0em algum tipo de intera$%o. 1este e)emplo (amos s4 arma0enar os m4dulos das distAncia +ue os robos se mo(eram 6fun$%o membro ove()7 Fa$a a inclus%o do ar+ui(o +ue define sua estrutura de arma0enamento* =storage=* no seu pro&eto: =include 4listht"h4 Crie o atributo static com o encapsulamento dese&ado na defini$%o da classe ro)o. 3e preciso indi+ue o tipo parametri0ado: class faca@estatisticas@sobre@mim K pri(ate: static listaHfloatI registroF JJstorage class public: ... Acesse o atributo static aonde seu encapsulamento permite atra(s de camadas de fun$#es membro como: registro.insere@ultimo6a7F Wente fa0er este e)emplo so0ino* depois confira com o programa a seguir: Ginclude Hiostream.I Ginclude Hmat.I Ginclude =mlistt.= class robot K pri(ate: float )*yF JJposicoes static listaHfloatI deltasFJJguarda os passos dados public: robot6float a*float b7 K )MaF yMbF L JJcria robo (oid mo(e6float d)*float dy7 K )'Md)F y'MdyF deltas.insere@primeiro6s+rt6)U)'yUy77F L static (oid mostra@lista6(oid7 K deltas.mostra67F cout HH endlF L `robot6(oid7 KL JJmata robo LF listaHfloatI robot::deltasF JJcama o construtor. main67 K robot Ur:Mne\ robot6N.N*N.N7F JJcria robo : r:2Imo(e6:*:7F robot Ur;F robot::mostra@lista67F JJmostra lista. r;Mne\ robot6:.N*:.N7F JJcria robo ; robot::mostra@lista67F JJmostra lista. r;2Imo(e6:N*:N7F robot::mostra@lista67F JJmostra lista. delete r:F delete r;F return NF L Re"$%&'(! (! )r!*r'+': M6:.D:D;:72 M6:.D:D;:72 M6:X.XXY<726:.D:D;:72 S&'&c e 1$,34e" c!+$,": Fun$#es comuns tambm podem ter (ari-(eis static e n%o s4 ob&etos. 1este caso as (ari-(eis permanecem ati(as durante camadas da fun$%o. Exercc!": :7Defina uma estrutura de dados mais eficiente para busca +ue uma lista* use2a como static no e)emplo acima. Faca com +ue os robos atendam ao seguinte fun$%o membro: encontra_proxio(void); +ue fa0 com +ue um robo se mo(a at a posi$%o do companeiro mais pr4)imo dele. Perceba +ue agora (oc/ tem +ue arma0enar a posi$%o de cada robn na estrutura* &untamente com um identificador deste robn. ;7Defina de modo an-logo ao e)erccio anterior fun$#es membro como agrupa* +ue fa0 com +ue os robos se mo(am uma unidade de comprimento em dire$%o ao centro de massa do grupo. 3upona +ue todos os robos tenam a mesma massa. <7.oc/ pode dese&ar arma0enar as informa$#es da classe ro)ot em outra classe* +ue computa outros c-lculos* neste caso temos pelo menos duas alternati(as a seguir: a7Crie uma classe au)iliar e)terna de arma0enagem e para todos ob&etos ro)o instanciados passe o ponteiro desta classe au)iliar como argumento do construtor . Assim esses ob&etos poder%o mandar mensagens para esta classe de arma0enagem. "ssas mensagens* camadas de fun$#es membro* podem ter (-rios significados* num sentido figurado podemos ter algo parecido com: =Classe au)iliar* arma0ene essa informa$%o para mim=. =Classe au)iliar* me mande uma mensagem da+ui a cinco segundos* estou passando o ponteiro para mim mesmo (this) = * etc. As mensagens (istas desse modo ficam mais interessantes* (oc/ pode at acar engra$ado* mas muito pr-tico pensar assim. 8uando estudarmos simula$#es dirigidas a e(entos em D.Y.; (eremos a importAncia destas trocas de mensagens entre ob&etos. b75sar friends para +ue a classe de arma0enagem e c-lculo e a classe ro)ot possam interagir. D7 "m alguma classe +ue (oc/ criou anteriormente defina (ari-(eis static com o seguinte ob&eti(o: Contar* fa0er estatsticas das camadas de fun$%o membros de classe. X75se o +ue foi aprendido sobre =static (ariables= no programa contas* o ob&eti(o arma0enar informa$#es sobre os mo(imentos de todas as contas num ob&eto static. Para +ue a modifica$%o fi+ue a contento (oc/ pode precisar tornar o e)emplo mais pr4)imo da realidade* adicionando no construtor de contas um argumento: nBmero de conta. Comente se (oc/ usaria aloca$%o dinAmica para essa classe de arma0enagem agregada em conta* ou n%o. Wena em mente a +uest%o do tamano em bytes do ob&eto. 9.?. TRATAMENTO DE E:CE0ES Adicionando tratamento de e)ce$#es ao programa (etor do item D.<.:. JJeader file para classe (etor e). Ginclude Hiostream.I const int inicioMNF class e)cecoes(etor K JJto be tro\ed public: JJnao teno interesse de encapsular por en+uanto. e)cecoes(etor6carU te)to7F carU mensagemF carU retorna@mensagem6(oid7F LF class e)cecaoalocacao:public e)cecoes(etorK public: e)cecaoalocacao6carU te)to7F LF class e)cecaoinstanciacao:public e)cecoes(etorK public: e)cecaoinstanciacao6carU te)to*int num7F int +uantF JJnumero de elementos com +ue se tentou instanciar (etor LF class e)cecaolimite:public e)cecoes(etorK JJlimite de indice desrespeitado public: e)cecaolimite6carU te)to*int ind*int ma)7F int indiceF JJarma0ena o indice +ue gerou e)cecao int ma)imoF JJarma0ena o indice ma)imo JJindice minimo eR fi)o para este programaMN LF e)cecoes(etor::e)cecoes(etor6carU te)to7 K mensagemMte)toFL carU e)cecoes(etor::retorna@mensagem6(oid7 K return mensagemF L e)cecaolimite::e)cecaolimite6carU te)to*int ind*int ma)7:e)cecoes(etor6te)to7 K indiceMindF ma)imoMma)FL e)cecaoinstanciacao::e)cecaoinstanciacao6carU te)to*int num7:e)cecoes(etor6te)to7 K +uantMnumF L e)cecaoalocacao::e)cecaoalocacao6carU te)to7:e)cecoes(etor6te)to7 KL templateHclass WI class (etorK JJW eR o tipo do elemento do (etor pri(ate: WU (F JJpode ser +ual+uer tipo +ue atenda as operacoes H I M int tamanoF public: (etor 6int tamano7 F Wj operatorhi 6int i7F W ma)imo67F int primeiro6(oid7F int ultimo6(oid7F LF templateHclass WI (etorHWI::(etor 6int tam7 K if 6tamH:7 tro\ e)cecaoinstanciacao6=.etores de tamano H:. 3ao in(alidos.=*tam7F (Mne\ WhtamiF if 6(MM15??7 tro\ e)cecaoinstanciacao6=1ao consegui alocar memoria=*tam7F tamanoMtamF L templateHclass WI int (etorHWI::primeiro 6(oid7 Kreturn inicioFL templateHclass WI int (etorHWI::ultimo 6(oid7 Kreturn tamano2:FL templateHclass WI Wj (etorHWI::operatorhi6int i7 K if 6iHN kk iIMtamano7 tro\ e)cecaolimite6=Fora dos limites.=*i*tamano7F return (hiiF L templateHclass WI W (etorHWI:: ma)imo6(oid7 K int candidatoMinicioF for 6int iMinicioFiHtamanoFi''7 if 6(hiiI(hcandidatoi7 candidatoMiF return (hcandidatoiF L JJmain file Ginclude Hiostream.I Ginclude =e).= main67 K try K int indF JJindice* usado para atuali0acoes float itemF JJitem* usado para insercoes no (etor (etorHfloatIU meuF try K meuMne\ (etorHfloatI6X7F L catc 6e)cecaoinstanciacaoj e7 K cout HH =")cecao geradaS O (etor nao pode ser criado.= HH endlF cout HH e.retorna@mensagem67 HH endlF cout HH =O indice in(alido eR:=HH e.+uant HH endlF cout HH =O programa sera terminado.= HH endlF tro\F JJ`retro\ L catc 6e)cecaoalocacaoj e7 K cout HH =")cecao geradaS O (etor nao pode ser criado.= HH endlF cout HH e.retorna@mensagem67 HH endlF cout HH =O programa sera terminado.= HH endlF tro\F L catc 6e)cecoes(etorj e7 K cout HH ="sta e)cecao nao esta(a pre(ista em nosso codigo.=HHendlF cout HH =Pode ser resultado de uma e)tensao na ierar+uia de e)cecoes.=HHendlF cout HH e.retorna@mensagem67 HH endlF L for 6int iMmeu2Iprimeiro67FiHMmeu2Iultimo67Fi''7 K cout HH ="ntre com (alor da posicao:= HH i HH =Pn=F cin II meu2Ioperatorhi6i7F L for 6int &Mmeu2Iprimeiro67F&HMmeu2Iultimo67F&''7 coutHH 6Umeu7h&iHH = =F cout HH ="ntre com o indice da posicao a atuali0ar:Pn=F cin II indF cout HH ="ntre com o (alor a incluir:=F cin II itemF tryK6Umeu7hindiMitemFL catc 6e)cecaolimitej e7 K cout HH =Pa 3ubscripting desconsiderado.=HHendlF cout HH e.retorna@mensagem67 HH endlF L JJincluir um loop ate obter do teclado (alores (alidos. for 6int cMmeu2Iprimeiro67FcHMmeu2Iultimo67Fc''7 coutHH 6Umeu7hciHH = =F cout HHendl HH =Ma)imo:= HH meu2Ima)imo67F return NF LJJtry catc6...7 K cout HH =")cecoes nao tratadas* fim do programa.=HHendlF L L Re"$%&'(! ,!r+'% (! )r!*r'+': "ntre com (alor da posicao:N X.; "ntre com (alor da posicao:: XY<;.; "ntre com (alor da posicao:; :;.X "ntre com (alor da posicao:< :; "ntre com (alor da posicao:D ;.;: X.; XY<;.; :;.X :; ;.;: "ntre com o indice da posicao a atuali0ar: N "ntre com o (alor a incluir:; ; XY<;.; :;.X :; ;.;: Ma)imo:XY<;.; Re"$%&'(! ',!r+'% (eD(! ' ,(ce ,D-%(! ('(! '! )r!*r'+': "ntre com (alor da posicao:N ;.; "ntre com (alor da posicao:: X.C "ntre com (alor da posicao:; D.: "ntre com (alor da posicao:< YX.X "ntre com (alor da posicao:D ;.< ;.; X.C D.: YX.X ;.< "ntre com o indice da posicao a atuali0ar: Y "ntre com o (alor a incluir:D.X 3ubscripting desconsiderado. Fora dos limites. ;.; X.C D.: YX.X ;.< Ma)imo:YX.X Re"$%&'(! ',!r+'% (eD(! ' 1'%2' (e '%!c'3=! (e +e+Ir': ")cecao geradaS O (etor nao pode ser criado. 1ao consegui alocar memoria O indice in(alido eR:X O programa sera terminado. ")cecoes nao tratadas* fim do programa. Re"$%&'(! ',!r+'% (eD(! ' ,$+er! (e e%e+e,&!" (! De&!r U 1: ")cecao geradaS O (etor nao pode ser criado. .etores de tamano H:. 3ao in(alidos. O indice in(alido eR:2X O programa sera terminado. ")cecoes nao tratadas* fim do programa. Exercc!": :7 9mplemente* adicione tratamento de e)ce$#es para o e)emplo de D.:.;. Antes fa$a um le(antamento das e)ce$#es +ue podem ser geradas* lembre das restri$#es matem-ticas para o denominador em uma di(is%o. ?e(e em conta tambm o o(erflo\ de (ari-(eis long +ue s%o uma representa$%o com nBmero de bits finito da se+uencia dos nBmeros inteiros 6con&unto e da matem-tica7. Compare este tratamento com o de outros programas por e)emplo na di(is%o por 0ero* +uais as (antagens +ue (oc/ pode apontar e des(antagens> 9.A. CONCLUS0ES 1este t4pico apresentaremos programas mais elaborados dentre eles uma simula$%o dirigida a e(entos e uma implementa$%o de uma -r(ore bin-ria. 9.A.1. HR8ORE BINHRIA. "ste programa implementa uma -r(ore bin-ria e testa2a: GincludeHiostream.I const W!5"M:F const FA?3"MNF class no JJno agregado na classe ar(ore* por ra0oes de encapsulamento K pri(ate: int infoF JJatributo informacao* use template depois... noU es+F JJsubar(ore es+uerda noU dirF JJsubar(ore direita int busca@maises+6(oid7F public: no6int a7F JJsem filos no6int a*noU b*noU c7F JJcom filos int retorna@+uant6(oid7F noU insere6int a*intj res7F noU remo(e6int b*intj res7FJJres M resultado 6sucesso>7 int busca6int c7F JJbusca binaria (oid in@order67F JJparentisada `no6(oid7F JJdestrutor da ar(oreJsubar(ore static int +uantF JJso para testes* pode ser public. LF class ar(@bin K JJencapsula no e redireciona camadas de metodos pri(ate: noU arF public: ar(@bin6(oid7F ar(@bin6int a7F (oid insere6int a*intj result7F (oid remo(e6int b*intj result7F int busca6int c7F JJbusca binaria (oid in@order67F JJparentisada `ar(@bin6(oid7F LF GincludeHiostream.I GincludeHstdlib.I Ginclude=binatree.= int no::+uantMNF JJa+ui eu uso uma (aria(el static no::no6int a7 KinfoMaF es+M15??F dirM15??F+uant''FL no::no6int a*noU b*noU c7 JJconstructor KinfoMaFes+MbFdirMcF+uant''FL int no::retorna@+uant6(oid7 K return +uantF L int no:: busca@maises+6(oid7 K if 66Utis7.es+MMN7 return infoF else return 66Utis7.es+2Ibusca@maises+677F JJcamada recursi(a. L noU no::insere6int a*intj res7 K resM:F if 6tisMM15??7 return ne\ no6a*15??*15??7F if 6aIMinfo7 if 6dirMM15??7 dirMne\ no6a*15??*15??7F else dirM6Udir7.insere6a*res7F else if 6aHinfo7 if 6es+MM15??7 es+Mne\ no6a*15??*15??7F else es+M6Ues+7.insere6a*res7F return tisF JJnao e necessario. LF noU no::remo(e6int b*intj res7 K int copyF noU delete@au)F noU return@au)F JJusado para deletar um no if 6tisMM15??7 K resMFA?3"F return 15??F JJar(ore ou subar(ore (a0ia L else JJnot a nill pointer if 6bI6Utis7.info7 6Utis7.dirM6Utis7.dir2Iremo(e6b*res7F if 6bH6Utis7.info7 6Utis7.es+M6Utis7.es+2Iremo(e6b*res7F if 6bMM6Utis7.info7 JJpreciso deletar a+ui K resMW!5"F if 666Utis7.dirMM15??7 jj 66Utis7.es+MM15??77 JJsem filos K delete tisF return 15??F L else if 66Utis7.es+MM15??7 JJcomo remo(er de lista linear K delete@au)MtisF return@au)M66Utis7.dir7F 6Udelete@au)7.dirM15??F JJe(ita deletar subar(ore delete delete@au)F return return@au)F L else if 66Utis7.dirMM15??7 JJcomo lista linear K delete@au)MtisF return@au)M6Utis7.es+F 6Udelete@au)7.es+M15??F delete delete@au)F JJnao es+ueca return return@au)F L else JJo caso mais complicado K copyM6Utis7.dir2Ibusca@maises+67F infoMcopyF 6Utis7.dirM6Utis7.dir2Iremo(e6copy*res7F L L return tisF JJpara muitos casos. L int no::busca6int c7 K if 6tisSM15??7 if 6cMMinfo7 return cF else if 6cIinfo7 return 66Udir7.busca6c77F else return 66Ues+7.busca6c77F else return 2cF L (oid no::in@order6(oid7 JJpercurso in@order K if 6tisSM15??7 K cout HH =6= F 6Ues+7.in@order67F cout HH infoF 6Udir7.in@order67F cout HH =7=F LF L no::`no6(oid7 K if 6tisSM15??7 K +uant22F if 6dirSM15??7 delete dirF JJprimeiro cama destrutor depois deleta no if 6es+SM15??7 delete es+F JJo destrutor e camado para toda a ar(ore e entao L JJela (olta deletando os nos L ar(@bin::ar(@bin6(oid7 K arM15??FL ar(@bin::ar(@bin6int a7 K arMne\ no6a7FL JJinline (oid ar(@bin::insere6int a*intj result7 K arMar2Iinsere6a*result7F L JJinline (oid ar(@bin::remo(e6int a*intj result7 K arMar2Iremo(e6a*result7FL JJinline int ar(@bin::busca6int a7 K return ar2Ibusca6a7F L JJinline (oid ar(@bin::in@order6(oid7 K ar2Iin@order67F L ar(@bin::`ar(@bin67 K delete arF L Ginclude Hiostream.I Ginclude =binatree.= main67 JJtesta a ar(ore com menu. K int nF JJlido para ser inserido ou remo(ido. int flagF ar(@bin my@treeF car optionMR\RF do K cout HH endlF cout HH = 929nserePn=F cout HH = !2!emo(ePn=F cout HH = 129n Order 6Percurso7Pn=F cout HH_ = ^2^uscaPn=F cout HH = 323airPn=F cout HH = "ntre opcao:=F cout HH = Pn=F cin IIoptionF JJentre a opcao do menu s\itc6option7 JJe)ecutes user option K case R9R: case RiR: cout HH =Pn Digite numero a inserir:=F cin II nF cout HH =Pn=F flagMFA?3"F [email protected]*flag7F cout HH =flag:=HHflag HH endlF breacF case R!R: case RrR: cout HH =Pn Digite numero a remo(er:=F cin II nF cout HH =Pn=F flagMFA?3"F [email protected](e6n*flag7F cout HH =flag:=HHflag HH endlF breacF case R1R: case RnR: cout HH =Pn=F [email protected]@order67F cout HH = = HH no::+uant HH =:1osPn=F cout HH =Pn=F breacF case R^R: case RbR: cout HH =Pn Digite numero a acar:=F cin II nF cout HH =Pn=F cout HH = = HH [email protected] cout HH =Pn=F breacF case R3R: case RsR: cout HH =Pn ^Q" Pn=F breacF default: F L JJs\itc2case code blocc L \ile 66optionSMRsR7jj6optionSMR3R77F cout HH = 1odes:= HH no::+uant HH endlF return NF L Re"$%&'(! (! )r!*r'+': 1%o pode ser e)ibido por ser muito e)tenso. 9.A.#. SIMULAO DIRIGIDA A E8ENTOS. "ste t4pico o Bltimo e o Bnico +ue ainda est- sendo editado. "ste e)emplo apresenta uma simula$%o dirigida a e(entos. 3imulamos um banco* as (ari-(eis da simula$%o s%o: tempo mdio de entrada de clientes no banco* tempo mdio de atendimento* nBmero de atendentes. A linguagem precursora das atuais linguagens orientadas a ob&etos* 3imula* n%o por acaso foi criada para programar simula$#es. "m programa$%o orientada a ob&etos estamos fre+uentemente preocupados em modelar entidades* ob&etos* do mundo real* &ustamente esta a tarefa de uma simula$%o. .oc/ notar- +ue nosso programa principal bastante pe+ueno. Ocorre +ue ain usado para apenas iniciali0ar os ob&etos e a simula$%o* a maioria das a$#es ocorre atra(s de camadas de fun$#es membro entre os ob&etos* isto muito bom* e(itamos ao m-)imo a presen$a de (ari-(eis locais e passagem por refer/ncia. Clicc ere for Picture O diagrama mostra o cen-rio de nossa simula$%o: 1este diagrama est%o presentes as classes com +ue iremos trabalar: costuer, clerR, scheduler* anager, front_door, geoetric" Costuer e clerR s%o subclasses de active* uma classe base abstrata. 0anager, costuer, clerR s%o ob&etos reais* e)istiriam no mundo real. 8cheduler e front_door, geoetric n%o s%o ob&etos reis* s%o criados para au)iliar na simula$%o. 1ossa simula$%o do tipo discreta* dirigida a e(entos* em contraposi$%o com o tipo contnuo. Ou se&a estaremos atentos* monitorando*e(entos tais como o fato de um cliente entrar no banco ou ser atendido e n%o grande0as continuas como a (a0%o de uma bomba idr-ulica ou a (elocidade de um motor eltrico. 1ossa simula$%o dita discreta por+ue os e(entos ocorrem em inter(alos fi)os de tempo e n%o entre eles* o nBmero desses inter(alos escolido pelo usu-rio e de(e ser grande com rela$%o aos tempos usados na simula$%o 6tempo mdio de atendimento* etc7. "stes tempos mdios por serem inteiros de(em ser escolidos de forma a n%o gerar casos degenerados* ou se&a se (oc/ estimou +ue em seu banco o tempo de atendimento em geral tr/s (e0es maior +ue o tempo mdio de entrada de clientes no banco* ent%o prefira uma rela$%o do tipo 6;_JC7 ao en(s de 6CJ<7* esses tempos continuar%o pe+uenos perto do tempo de durac%o da simula$%o: :NNNN* porm n%o t%o pe+uenos +ue possam ser pouco hhdieresisiirepresentati(oshhdieresisii em termos de tempos diferentes +ue podem ocorrer. "ntenda por casos degenerados* casos +ue n%o ser%o capa0es de representar* modelar corretamente o +ue aconteceria em seu banco* fornecendo resultados discrepantes com outras op$#es e+ui(alentes 6em termos de propor$#es7 de (alores iniciais da simula$%o. 5m pouco sobre estatstica e probalilidade. .amos precisar de conceitos de estatstica neste problema. A tempo de atendimento de clientes segue usualmente uma distribui$%o geomtrica 6lembre2se +ue em estatstica e)istem distribui$#es discretas e contnuas7* a nossa discreta. A linguagem s4 oferece a distribui$%o de nBmeros conecida como uniforme *a+uela em +ue todos nBmeros tem a mesma probabilidade de serem sorteados* ela pode ser gerada por camadas a fun$%o rand67 da hhdieresisiilibraryhhdieresisii stdlib.* rand67 gera nBmeros pseudo2aleat4rios na fai)a de N at !A1D@MAO 6n%o se preocupe* !A1D@MAO est- definido na stdlib. e geralmenteMM<;_Y_7. Di0emos +ue rand() gera nBmeros pseudo2aleat4rios por+ue esta fun$%o utili0a uma semente para gerar uma se+u/ncia de nBmeros* esta se+u/ncia de nBmeros pode ser repetida* basta utili0ar a mesma semente. "sta possbilidade de repeti$%o ser- importante para reali0ar testes do programa* fre+uentemente o programador dese&a repetir o resultado da Bltima e)ecu$%o* isto s4 poss(el se for fornecida a mesma semente de gera$%o dos nBmeros atra(s de uma camada a fun$%o void srand(unsigned s) * &- importada com as =libraries= +ue (oc/ utili0ar- na simula$%o. Feli0mente dispomos de uma maneira de construir um gerador de nBmeros +ue obedecem uma distribui$%o geomtrica* a partir de um gerador de nBmeros aleat4rios. A distribui$%o uniforme precisa como parametro um (alor m-)imo* en+uanto +ue a geomtrica precisa de um (alor mdio. 1a distribui$%o geomtrica* se um cliente atendido em um tempo mdio de :N* ent%o podemos di0er +ue se ele ti(er come$ado a ser atendido agora* e)iste em mdia uma cance em de0 de ele terminar de ser atendido no pr4)imo instante. .amos supor +ue o cliente n%o foi atendido logo no primeiro instante* ent%o e)iste uma cance em de0 de ele ser atendido no pr4)imo instante e assim por diante. As probabilidades s%o iguais e independentes uma das outras. A soma das probabilidades de cada instante completa : no tempo mdio de atendimento +ue no caso :N. Porm isto n%o significa +ue :N um limite m-)imo* mas apenas a mdiaS 3e a probabilidade p de o cliente ser atendido no instante atual pMM6:Jmdia7 ent%o a probabilidade de ele n%o ser atendido 6:2p7. 3eguindo o raciocnio anterior* a probabilidade de o cliente ser atendido no primeiro ti+ue do rel4gio p. A probabilidade +ue o mesmo cliente se&a atendido s4 no segundo ti+ue igual a probabilidade de ele n%o ser atendido no primeiro ti+ueMM6:2p7 e SVT a probabilidade de ele ser atendido no segundo ti+ueMMp 6igual a p para todos os instantes isolados7. 3eguindo o mesmo raciocnio* a probabilidade de o cliente (ir a ser atendido s4 no terceiro ti+ue 6:2p7U6:2 p7Up. A formula geral da probabilidade de um cliente esperar t ti+ues en+uanto atendido : pU66:2p7o6t2:77. 3upona +ue tomamos nM:NN bolas* das +uais pintamos 6nJmdia7 de branco e o restante de preto 6mdiaHn7. Camemos de p a probabilidade de se retirar numa Bnica tentati(a uma bola branca de nossas n bolas* p igual a 6:Jmdia7. A probabilidade do e(ento complementar 6:26:Jmdia77MM6:2p7. A probabilidade de se obter uma bola branca s4 na segunda retirada com reposi$%o 6:2p7Up* en+uanto +ue s4 na terceira retirada 6:2p7U6:2p7Up e assim por diante* como no e)emplo anterior. Pois bem* as nossas n bolas podem ser (istas como os nBmeros da distribui$%o uniforme gerada por rand67. Pintar de branco parte das bolas de branco e o restante de preto e+ui(ale a di(idir o inter(alo de N at !A1D@MAO em nBmeros menores +ue (M.S@_0.;*1&Tdia)##?ays_to_occur 6brancos7 e nBmeros maiores +ue isso 6pretos7. 3ortear uma bola e (erificar a cor e+ui(ale a camar rand() e (er em +ue inter(alo o resultado cai. Wemos ent%o o procedimento para obter nBmeros segundo uma distribui$%o geomtrica a partir de um gerador de nBmeros aleat4rios. Construiremos uma classe em nosso programa para obter estes nBmeros* ser- a classe geometric. 3ua implementa$%o est- no ar+ui(o geometric.cpp. Clicc ere for Picture JJFile repair. JJZeader file for costumer2ser(ement simulation Ginclude Hstdlib.I Ginclude Hiostream.I enum ^oolean KFA?3"*W!5"LF JJN ou : class scedulerF JJclasse nao real class managerF JJclasse real JJclass of geometric2distribution random number generators class geometricK int geo@ma)F JJma)imum (alue of random number int \ays@to@occurF JJno. \ays desired e(ent can occur public: geometric6double mean*int ma)7F int dra\67F JJreturn ne)t random number ^oolean e@agora6(oid7F JJ(erifica se e agora +ue entra costumer LF JJAbstract base class of acti(e ob&ects class acti(eK acti(eU ne)tF JJne)t2ob&ect pointer for linced lists public: (oid set@ne)t6acti(eU p7 Kne)tMpFL acti(eU get@ne)t6(oid7 Kreturn ne)tFL (irtual (oid e(ent67MNF JJtrigger sceduled e(ent LF JJClass for costumer ob&ects class costumer:public acti(eK scedulerU spF JJpointer to sceduler managerU mpF JJpointer to ser(ice manager geometric gF JJrandom number generator ^oolean is@upF JJstate@(ariable int tot@up@timeF JJtempo total de pe int up@time@startF JJstart of most recent up2period static double ser(edcostF JJtotal number of ser(ed costumers static double \aitedtimeF JJtotal \aited time for all costumers public: costumer6double mean*int ma)*scedulerU s*managerU m7F (oid e(ent67F JJtime to be ser(ed (oid ser(ed67F JJCome bacc ome costumer. 6milled7 static double g@ser(edcost67 Kreturn ser(edcostFL static double g@\aitedtime67 Kreturn \aitedtimeFL static int (i(osF JJnumero de costumers (i(os* so pJdebugging `costumer67 K(i(os22FL JJso para controle de alocacao dinamica LF JJClass for clerc ob&ects class clerc:public acti(eK scedulerU spF JJpointer to sceduler managerU mpF JJpointer to ser(ice manager geometric gF JJrandom number generator costumerU \orcpF JJpointer to costumer under repair ^oolean is@busyF JJstate (ariable int busy@time@startF JJstart of most recent busy period int tot@busy@timeF JJtotal busy time public: clerc6double mean*int ma)*scedulerU s*managerU m7F (oid e(ent67F JJtime to complete repair (oid ser(e6costumerU p7F JJacept \orc assigment int busy@time67F JJreturn total busy time LF class manager K enum \o KCO3W5M"!3*C?"!m3*1O1"LF \o \aitingF JJcind of ob&ects in +ueue acti(eU firstF JJpoints to first ob&ect in +ueue acti(eU lastF JJpoints to last ob&ect in +ueue double llsumF JJline lengt sum 6sum e(ery ticc* \en \it costumers7 int lengtF JJcomprimento da fila JJPri(ate functions for manipulating +ueue (oid insert@first6acti(eU p7 KfirstMlastMpF p2Iset@ne)t6N7Flengt''FL (oid insert6acti(eU p7 Klast2Iset@ne)t6p7F p2Iset@ne)t6N7F lastMpFlengt''FL (oid remo(e67 KfirstMfirst2Iget@ne)t67Flengt22FL JJ(amos percorrer a lista e sortear clerc desocupado clercU escole@randomico6(oid7 K JJescole randomico int posicaoF posicaoM6rand67 d lengt7':F JJ:..lengt posicao a deletar acti(eU corrMfirstF JJcorrente* itera sobre lista acti(eU pre(M15??F JJainda nao esta sobre a lista for 6int iMNFiH6posicao2:7Fi''7 JJiMlocal do pre(io 6N...lengt2:7 K pre(McorrF corrMcorr2Iget@ne)t67F JJdesloca ponteiros na lista L clercU retorneM6clercU7 corrF JJtype cast if 6lastMMcorr7 lastMpre(F if 6pre(MM15??7 firstMcorr2Iget@ne)t67F else pre(2Iset@ne)t6corr2Iget@ne)t677F lengt22F return retorneF L JJescole@randomico public: manager67 KfirstMlastMNF \aitingM1O1"FlengtMNFllsumMNFL (oid re+uest@ser(ice6costumerU p7F JJser(ice re+uest costumerU re+uest@\orc6clercU p7F JJ\orc re+uest (oid ticc6(oid7 K if 6\aitingMMCO3W5M"!37 llsum'MlengtFL double g@llsum6(oid7 K return llsumFL `manager67 K \ile 6firstSM15??7 Kacti(eU au)MfirstF firstMfirst2Iget@ne)t67F delete au)FL L LF JJClass for sceduler class front@doorK pri(ate: double mediaF int ma)imoF scedulerU spF managerU mpF geometricU gF public: (oid init6double mean*int ma)*scedulerU s*managerU m7 K mediaMmeanF ma)imoMma)F spMsF mpMmF gMne\ geometric6mean*ma)7F L (oid sorteia@cost6(oid7 K costumerU es+uecameF if 6g2Ie@agora677 es+uecameMne\ costumer6media*ma)imo*sp*mp7F JJnao se preocupe com delecao* o costumer se pendura nas listas JJ6tis7 e (ai acabar sendo deletado pelo clerc L `front@door6(oid7 K delete gFL LF class sceduler K int cloccF JJsimulation clocc int calendar@si0eF JJsi0e of calendar@+ueue array acti(eUU calendarF JJpointer to calendar +ueue array int inde)F JJcalendar +ueue array subscript for current time front@doorU fdF managerU mF public: sceduler6int s0*front@doorU fdp*managerU mp7F int time67 Kreturn cloccFL JJreturn time (oid scedule6acti(eU p*int delay7F JJscedule e(ent (oid run6int ticcs7F JJrun simulation `sceduler6(oid7 K for 6int iMNFiHcalendar@si0eFi''7 K \ile 6calendarhiiSM15??7 K acti(eU au)F au)McalendarhiiF calendarhiiMcalendarhii2Iget@ne)t67F delete au)F L L L LF JJFile geometrc.cpp JJ3ource file for class geometric Ginclude Hstdlib.I Ginclude =repair.= Gifndef !A1D@MAO Gdefine !A1D@MAO <;_Y_ Gendif JJ!A1D@CO51W is number of different (alues tat JJrand67 can return const double !A1D@CO51WMdouble6!A1D@MAO7':.NF JJ9nitiali0e geometric2distribution ob&ect geometric::geometric6double mean* int ma)7 K \ays@to@occurMint6!A1D@CO51WJmean'N.X7F geo@ma)Mma)F L JJ!eturn ne)t geometrically distributed random number int geometric::dra\67 K for 6int iM:FiHgeo@ma)Fi''7 if6rand67H\ays@to@occur7 return iF return geo@ma)F L ^oolean geometric::e@agora6(oid7 K return 6rand67H\ays@to@occur7F JJcances de entrar agora pela porta L JJFile acti(e.cpp JJ3ource file for classes costumer and clerc Ginclude Hiostream.I Ginclude =repair.= JJ9nitiali0e costumer ob&ect and scedule first breacdo\n costumer::costumer6double mean*int ma)*scedulerU s*managerU m7:g6mean*ma)7 K spMsF mpMmF (i(os''F JJcontrole de alocacao dinamica. tot@up@timeMNF is@upMW!5"F sp2Iscedule6tis*g.dra\677F JJup@time@start is not initiali0ed ere but \en costumers enter in banc L JJ!e+uest ser(ice for disabled costumer (oid costumer::e(ent67 JJentering in te banc* start counting \ait time K is@upMFA?3"F JJnot outside te banc up@time@startMsp2Itime67F mp2Ire+uest@ser(ice6tis7F JJentrou no banco* fica na fila ou (ai direto ao cai)a L JJ!eturn repaired costumer to ser(ice (oid costumer::ser(ed67 JJmay be cilled* deleted no\. K is@upMW!5"F tot@up@time'Msp2Itime672up@time@startF \aitedtime'Mtot@up@timeF ser(edcost'M:F L JJ9nitiali0e clerc ob&ect and* if possible* get ob&ectRs JJFirst \orc assignment clerc::clerc6double mean*int ma)*scedulerU s*managerU m7:g6mean*ma)7 K spMsF mpMmF tot@busy@timeMNF \orcpMmp2Ire+uest@\orc6tis7F if 6\orcpMMN7 is@busyMFA?3"F else K is@busyMW!5"F busy@time@startMsp2Itime67F sp2Iscedule6tis*g.dra\677F L L JJComplete repair on current costumerF if possible get JJne\ \orc assignment (oid clerc::e(ent67 K tot@busy@time'Msp2Itime672busy@time@startF \orcp2Iser(ed67F JJgra(a estatisticas. delete \orcpF JJmata costumer \orcpMmp2Ire+uest@\orc6tis7F if 6\orcpMMN7 is@busyMFA?3"F else K is@busyMW!5"F busy@time@startMsp2Itime67F sp2Iscedule6tis*g.dra\677F L L JJAcept \orc assignment (oid clerc::ser(e6costumerU p7 K \orcpMpF is@busyMW!5"F busy@time@startMsp2Itime67F JJcomeca contar tempo de ocupado sp2Iscedule6tis*g.dra\677F JJme tire do atendimente da+ui a g.dra\ tempos L JJ!eturn total busy time int clerc::busy@time67 K int tMtot@busy@timeF if 6is@busy7 t'Msp2Itime672busy@time@startF return tF L JJFile manager.cpp JJ3ource file for class manager Ginclude Hiostream.I Ginclude =repair.= JJZandle ser(ice re+uest from disabled costumer (oid manager::re+uest@ser(ice6costumerU p7 K clercU +F s\itc6\aiting7 K case CO3W5M"!3: insert6p7F returnF case C?"!m3: +Mescole@randomico67F JJpega um clerc desocupado +ual+uer* &a con(erte 6clercU7 if 6firstMM15??7 \aitingM1O1"F +2Iser(e6p7F returnF case 1O1": \aitingMCO3W5M"!3F insert@first6p7F returnF L LF JJZandle \orc re+uest from idle clerc costumerU manager::re+uest@\orc6clercU p7 K costumerU +F s\itc 6\aiting7K case CO3W5M"!3: +M6costumerU7 firstF remo(e67F if 6firstMM15??7 \aitingM1O1"F return +F case C?"!m3: insert6p7F return 15??F case 1O1": \aitingMC?"!m3F insert@first6p7F return 15??F L return 15??F L JJFile scedule.cpp JJ3ource file for class sceduler Ginclude Hiostream.I Ginclude =repair.= JJCreate sceduler \it calendar +ueue a(ing s0 elements sceduler::sceduler6int s0*front@doorU fdp*managerU mngrp7 K fdMfdpF JJarma0ena o front@door pointer mMmngrpF JJarma0ena o manager pointer cloccMNF calendar@si0eMs0F calendarMne\ acti(eUhs0iF for 6int iMNFiHs0Fi''7 calendarhiiMNF inde)MNF L JJ3cedule ob&ect Up to recei(e e(ent message JJafter delay ticcs a(e elapsed (oid sceduler::scedule6acti(eU p*int delay7 K int tMinde)'delayF if 6tIMcalendar@si0e7 t2Mcalendar@si0eF p2Iset@ne)t6calendarhti7F calendarhtiMpF L JJ!un simulation for gi(en number of ticcs (oid sceduler::run6int ticcs7 K acti(eU pF for 6int iMNFiHticcsFi''7 K fd2Isorteia@cost67F JJagenda entrada do no(o costumer en+uanto JJnao comecou a me)er em listas ainda* senao corrompe estado m2Iticc67F JJfa0 manager gra(ar estatisticas das listas \ile66pMcalendarhinde)i7SMN7 K calendarhinde)iMp2Iget@ne)t67F p2Ie(ent67F L clocc''F if 6''inde)MMcalendar@si0e7 inde)MNF L L JJFile simula.cpp JJprograma demonstracao para simulacao de cliente2atendente Ginclude Hiostream.I Ginclude Hstdlib.I Ginclude =repair.= JJiniciali0ando os membros static da classe costumer double costumer::ser(edcostMN.NF double costumer::\aitedtimeMN.NF int costumer::(i(osMNF JJpara controle da alocacao dinamica main67 K JJdeclaracao de (aria(eis obtencao de (alores do usuario unsigned sementeF JJseed for rand67 int num@ad&F JJnumero de clercs double m@meanF JJtempo medio entre entradas no estabelecimento double a@meanF JJtempo medio de atendimento cout HH =1umero de atendentes>=F cin II num@ad&F cout HH =Wempo medio de entrada de clientes pela porta>=F cin II m@meanF cout HH =Wempo medio de ser(ico* atendimento>=F cin II a@meanF cout HH =3emente de numeros randomicos>=F cin II sementeF JJ3eed rand67F set ma)@time to ten times ma)imum of JJm@mean and a@mean srand6semente7F int ma)@timeM:NUint6m@meanIa@mean>m@mean:a@mean7F int iF JJCria manager e sceduler manager mngrF front@door criadorF sceduler sc6ma)@time':*jcriador*jmngr7F criador.init6m@mean*ma)@time*jsc*jmngr7F JJiniciali0a criador de costumers JJcom as caracteristicas esperadas dos costumers* como nao e construtor* posso JJmodificar as caracteristicas dos costumers durante programa. JJCria clercs clercUU a@listMne\ clercUhnum@ad&iF for 6iMNFiHnum@ad&Fi''7 a@listhiiMne\ clerc6a@mean*ma)@time*jsc*jmngr7F JJFa0 sucessi(os loops da simulacaoF imprime estatisticas cumulati(as JJdepois de cada con&unto de iteracoes completo car cF do K JJ]et number of ticcs for tis run int durationF cout HH =Pn1umber of time steps>=F cin II durationF JJ!un duration sc.run6duration7F JJCOMP5WA " 9MP!9M" W"MPO M"D9O D" F9?A 6por costumer7 long tempo@medioM6costumer::g@\aitedtime677J6costumer::g@ser(edcost677F cout HH =Wempo medio na fila:= HH tempo@medio HH endlF JJcomputa e imprime utili0acao media dos atendentes double a@factorM:NN.NJdouble6sc.time677Jdouble6num@ad&7F long tot@busy@timeMNF for 6iMNFiHnum@ad&Fi''7 tot@busy@time'Ma@listhii2Ibusy@time67F cout HH =Media da utili0acao dos atendentes:= HH tot@busy@timeUa@factorHH=dPn=F double a(llF JJa(erage costumer line lengt a([email protected] cout HH =Comprimento medio da fila:= HH a(ll HH endlF JJDetermine if user \ants to do more runs cout HH =Clientes ainda nao atendidos:= HH costumer::(i(os HH endlF JJestes ou estao na fila para serem atendidos* ou se penduraram no JJcalendar +ueue* e so para controle da alocacao dinamica. cout HH =Continue 6QJ17>=F cin II cF L \ile 6cMMRyR kk cMMRyR7F delete hia@listF return NF L JJ!"35?WADO3 DO P!O]!AMA* A PA!W9! DO3 .A?O!"3 919C9A93 DO P!9M"9!O W"3W" JJ6W"3W" A 3"]59!7 F59 .A!9A1DO 5M PA!AM"W!O PO! ."e " ."1DO 3" O JJ!"35?WADO "!A CO"!"1W". JJ1umero de atendentes>: JJWempo medio de entrada de clientes pela porta>E JJWempo medio de ser(ico* atendimento>< JJ3emente de numeros randomicos><:D:Y JJ JJ1umber of time steps>XNNN JJWempo medio na fila:< JJMedia da utili0acao dos atendentes:<Y.:Dd JJComprimento medio da fila:N.:<ED JJClientes ainda nao atendidos:: JJContinue 6QJ17>y JJ JJ1umber of time steps>:NNNN JJWempo medio na fila:D JJMedia da utili0acao dos atendentes:<_._C<<d JJComprimento medio da fila:N.:X<YY_ JJClientes ainda nao atendidos:D JJContinue 6QJ17>n JJ JJ1umero de atendentes>; JJWempo medio de entrada de clientes pela porta>E JJWempo medio de ser(ico* atendimento>< JJ3emente de numeros randomicos><:D:Y JJ JJ1umber of time steps>XNNN JJWempo medio na fila:; JJMedia da utili0acao dos atendentes::E.<d JJComprimento medio da fila:N.NNEE JJClientes ainda nao atendidos:N JJContinue 6QJ17>y JJ JJ1umber of time steps>:NNNN JJWempo medio na fila:< JJMedia da utili0acao dos atendentes::E.DN<<d JJComprimento medio da fila:N.NNYE JJClientes ainda nao atendidos:; JJContinue 6QJ17> JJ JJ1umero de atendentes>: JJWempo medio de entrada de clientes pela porta>Y JJWempo medio de ser(ico* atendimento>< JJ3emente de numeros randomicos><:D:Y JJ JJ1umber of time steps>XNNN JJWempo medio na fila:D JJMedia da utili0acao dos atendentes:XN.NYd JJComprimento medio da fila:N.<:ND JJClientes ainda nao atendidos:N JJContinue 6QJ17>y JJ JJ1umber of time steps>:NNNN JJWempo medio na fila:X JJMedia da utili0acao dos atendentes:X:d JJComprimento medio da fila:N.<XYC<< JJClientes ainda nao atendidos:: JJContinue 6QJ17> JJ JJ1umero de atendentes>: JJWempo medio de entrada de clientes pela porta>E JJWempo medio de ser(ico* atendimento>X JJ3emente de numeros randomicos><:D:Y JJ JJ1umber of time steps>XNNN JJWempo medio na fila::: JJMedia da utili0acao dos atendentes:XC.XDd JJComprimento medio da fila:N._Y:Y JJClientes ainda nao atendidos:: JJContinue 6QJ17>y C!,&eO(!: B5%!*r'1': h:i !umbaug* ^laa M.* Premerlani [.* "ddy F. j ?orensen [. *=Ob&ect2Oriented Modeling and Design=. Prentice Zall* :CC:. h;i ^udd. W *=Classical Data 3tructures 9n C''=. Addison2[esley :CCD. h<i Mitcel M. *=Data Abstraction in C''= hDi ]raam. 1.*=?earning C''=. Mc]!A[2Z9??* :CC:. hXi 3troustrup. ^.* =We C'' Programming ?anguage=. Addison2[esley :CC:. =Wutoriais e e)erccios online sobre C'' e "iffel= Departamento de ci/ncia da computa$%o* !ocester 9nstitute of Wecnology