• Nenhum resultado encontrado

t3DVector* p = new t3DVector;

Noteque

p

n~aoeumobjetodaclasse

t3DVector

,massimumponteiroparaumobjeto da classe

t3DVector

. O objeto propriamente dito,

*p

, esta na area de memoria de alocac~aodin^amica,oheapdosistema. (Ooperador

new

e,sobalgunsaspectos, similar 

a func~ao

malloc

,porem muito superior, como veremosposteriormente.)

O conteudo de um objeto, ou seu estado interno, e de nido por suas variaveis de inst^ancia,declaradasnade nic~aodeclasse. Osvetores

v

e

*p

possuemestadosinternos (distintos) caracterizados pelas variaveis

x

,

y

e

z

(linhas 30-32 do Programa 8.1), as quais representam suas coordenadas Cartesianas. Podemoster, tambem,variaveisque n~ao pertencem a qualquer inst^ancia de uma classe, mas que s~ao compartilhadas por todas as inst^ancias da classe. Em Smalltalk [47], essas variaveispertencem a classe, e n~aoasinst^anciasdaclasse e,porisso, s~aodenominadasvariaveisde classe. EmC++, umavariaveldeclasseedeclaradacomoespeci cadordetipo

static

,comonaslinhas 34-36 do Programa8.1.

8.2.3 Mensagem

Vamos supor que

s

seja uma estrutura talcomo de nida no Programa3.1. Se quis es-semos acessarum dos camposde

s

,porexemplo, a coordenada

x

, escreveramos

s.x

. A mesma regra sintatica vale em C++. Adicionalmente, podemos \acessar" tambem asfunc~oes de nidas na classe:

v.Normalize();

p->SetCoordinates(1,1,1);

Noexemplo acima, estamos\acessando" ometodo

Normalize

dovetor

v

e o metodo

SetCoordinates

do vetor apontado por

p

. Semanticamente, porem, o signi cado e outro. Oqueestamos fazendo,naverdade,eenviando umamensagem paraosobjetos

v

e

*p

,umasolicitac~aoparaqueessesobjetosexecutemalgumaoperac~ao. Oprograma 2

anteriorquer dizer,emC++,\

v

,porfavor,normalize-se"e\

*p

,porfavor,ajustesuas coordenadas para (1;1;1)." Quando enviamos uma mensagem a um objeto, dizemos aoobjetoo que fazer,e n~aocomo fazer.

Uma mensagem e de nida por um receptor, por um seletor e por um conjunto, eventualmente vazio, de par^ametros. Na segunda linha do exemplo acima,

*p

e o receptor da mensagem,

SetCoordinates

e o seletor da mensagem e

1,1,1

s~ao os par^ametros damensagem.

Quando umobjetorecebeuma mensagem,ometodocorrespondenteamensageme executado. Em C++, o \metodo correspondente a uma mensagem"e a func~ao mem-bro, declarada na de nic~ao da classe do objeto, que possui o mesmo nome do seletor da mensagem e o mesmo numero e tipo de par^ametros da mensagem. (Note que po-demos ter metodos com o mesmo nome, desde que com tipos e/ou numero distintos de par^ametros, como nas linhas 8-9 do Programa 8.1.) Chamamos essa operac~ao de acoplamento mensagem/metodo. Portanto, em resposta a mensagem

SetCoordina-tes(1,1,1)

, o vetor

*p

\acopla" e executa o metodo

SetCoordinates

declarado na linha 9 do programa. O valor retornado por um objeto, como resultado do pro-cessamento de uma mensagem, e o proprio valor da func~ao membro correspondente (eventualmente,

void

).

Em um programa orientado a objetos, a computac~ao e realizada por objetos que trocam mensagensentre si. Consideraremos somente omodelopassivode objetos,isto e, um objeto que envia uma mensagem para um outro objeto n~ao executa mais nada enquanto n~aoobtiver, da parte doreceptor, resposta da mensagem enviada.

8.2.4 Construc~ao e Destruic~ao de Objetos em C++

Imediatamenteaposaconstruc~aodeumobjeto,seuestadointernodeveserinicializado. EmC++, issoe feitopelaexecuc~ao de metodos especiais chamadosconstrutores. Um construtoremC++eumafunc~aosem tipoderetorno(nemmesmo

void

)cujonomee id^enticoaonomedaclasse. Aclasse

t3DVector

,comopodemosobservarnaslinhas4-6 doPrograma8.1, possuitr^esconstrutores. Oprimeiron~aotomaquaisquer par^ametros e e chamado de construtor default. O segundo toma como par^ametro uma refer^encia para um objeto constantedaclasse

t3DVector

;esse construtor echamadoconstrutor de copia ee utilizadoparainicializaroestado internodoobjetosendo construdo com uma copia do estado interno do objeto passado como par^ametro. O terceiro toma como par^ametros tr^es numeros reais correspondentes as coordenadas do vetor sendo construdo.

No momento da declarac~ao de um objeto em C++, estatica ou dinamicamente como visto acima, podemos enviar uma mensagem ao novo objeto solicitando sua inicializac~ao. Porexemplo,

t3DVector u(2,2,2);

t3DVector w(u);

Estamosdizendo, acima,\

u

,porfavor,inicialize-secom ascoordenadas(2;2;2)"e\

w

, por favor, inicialize-se com uma copia de

u

." (Se n~ao enviarmos mensagem alguma naconstruc~ao de um novoobjeto, ocompilador automaticamentechama o construtor defaultda classe,sehouver. Se nenhum construtor default fordeclarado, ocompilador

C++e uma linguagem quen~ao possui \coleta de lixo" automatica. Por isso, todo objeto que utilizar memoria din^amica deve liberar a memoria utilizada antes de ser destrudo. Em C++, ha metodos especiais, chamados de destrutores, que podem ser de nidos para executar essa tarefa. Um destrutor, se declarado em uma classe, e chamadoautomaticaeimediatamenteantes da destruic~aode um objeto daclasse. (Se n~ao ha destrutor, o compilador fornece um.) Um destrutor e de nido em uma classe C++ por uma func~ao com o mesmo nome da classe precedido pelo smbolo

˜

, sem argumentos e sem tipo de retorno. A classe

t3DVector

n~ao possui destrutor (veja a proximaSec~ao).

O tempo de vida de um objeto em um programa C++ e de nido pelas regras de escopo da linguagem, tal como no C.

3

Um objeto criado dentro de um bloco sera destrudoao naldobloco(amensagemeenviadaautomaticamentepelocompilador). A unica excec~ao e para aqueles objetos criados dinamicamente. Nesse caso, devemos explicitamente invocar o destrutor do objeto, utilizando o operador

delete

. Para o vetor

*p

, escrevemos

delete p;

(Ooperador

delete

e, sob alguns aspectos, similar afunc~ao

free

,porem, da mesma formaqueooperador

new

,muitosuperior. Umdosmotivoseque

delete

n~aosomente libera memoria, mas envia uma mensagem ao objeto solicitando, e ao mesmo tempo permitindo, queeste facasua propria \limpeza".)

8.3 Propriedades da Orientac~ao a Objetos

Por que precisamos de uma classe de objetos? Poderamos argumentar que a classe

t3DVector

, por exemplo, nos permite modularizar um pouco mais o codigo, porque estamos de nindo, em uma unica unidade, as estruturas de dados e osprocedimentos que manipulam essas estruturas. Mas, se o benefcio fosse somente esse, poderamos consegu-lo com uma boa pratica de programac~ao em C. Antes de prosseguirmos a discuss~ao, vejamos dois conceitos relacionados aprogramac~aoorientada a objetos:

Abstrac~ao. A abstrac~aoeum dosmecanismos maisimportantesutilizadospela mente humana para compreender o mundo real. Ao analisarmos um problema complexo,naturalmenteseparamosobjetosque,narealidade,nuncaseencontram isolados, caracterizando-os a partir de certas propriedades que de nem aproxi-madamenteseus principaisaspectosestruturais ecomportamentais. Aabstrac~ao sempre deve ter algum proposito, porque e o proposito que permite determinar quais informac~oes ser~ao representadas e que operac~oes ser~ao executadas pelos objetos.

Tipos abstratos de dados. Tipo abstrato de dados e o mecanismo atraves do qualumalinguagemdeprogramac~aoorientadaaobjetosfornecesuportea especi- cac~aodas informac~oes de umobjetoedas operac~oes executadas porumobjeto, de forma similar ao tipo de dados de uma linguagem estruturada. A diferenca e que um tipo abstrato de dados esconde as informac~oes sobre a estrutura do 3

C++ n~aoadmitediretamenteoconceitodepersist^encia, epor isson~aoadiscutiremosaqui. Um objetopersistenteeumobjetoquesobreviveaexecuc~aodeumprograma,sendo,portanto,armazenado

objeto de observadores externos. Com isso, as abstrac~oes de um sistema s~ao de- nidas, napratica, porduas partes: uma interface que descreve quais operac~oes podem ser executadas e uma implementac~ao que determina como as operac~oes s~ao executadas. A classe e a construc~ao de linguagem mais comumente utiliza-dapara implementarum tipoabstrato de dados emlinguagens de programac~ao orientadas a objetos.

De acordo com a de nic~ao de tipo abstrato de dados, as variaveisde inst^ancia decla-radas em uma de nic~ao de classe deveriam ser \escondidas" de um observador exter-no, sendo acessveis somente aos proprios metodos da classe. A nal, as variaveis de inst^ancia de nem o estado interno do objeto. Em C++, porem, somos livres para controlar a visibilidadede qualquer membro de uma classe, seja dado ou func~ao. Ob-serve, na linha 3 doPrograma 8.1, o uso da palavra reservada

public

. Signi caque, daquelepontoemdiante, todososmembrosdeclaradosnaclasses~aopublicos,podendo ser diretamenteacessados. Para um vetor

v

, poderamos escrever, corretamente,

v.x

paraobter (oualterar)ovalordacoordenada

x

de

v

. Para osdefensores \puristas"da orientac~aoa objetos,essa possibilidadee inaceitavel e,mesmo em C++, e fortemente n~ao recomendavel. Vejamos por qu^e.

8.3.1 Encapsulamento

Consideremos a de nic~ao (parcial)da classe

gPrimitive

,Programa 8.2. Essa classe representaum tipogenericode primitivode ummodelogra co,talcomocaracterizado noCaptulo 3.

Documentos relacionados