Você está na página 1de 246

TUTORIAL:

"C++ COMO UMA LINGUAGEM DE


PROGRAMAO ORIENTADA A OBJETOS."
Copyright 1996
Andr Augusto Cesta.
aacesta@dcc.unicamp.br
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(ersario.get@dia67MMdd.get@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
my@tree.insere6n*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
my@tree.remo(e6n*flag7F
cout HH =flag:=HHflag HH endlF
breacF
case R1R:
case RnR:
cout HH =Pn=F
my@tree.in@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 my@tree.busca6n7F
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(llMmngr.g@llsum67Jsc.time67F
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

Você também pode gostar