Sunteți pe pagina 1din 757

Programa c ao Orientada a Objeto com C++ 2 edic ao

Andr e Duarte Bueno, UENF-LENEP-LDSC http://www.lenep.uenf.br/~bueno email: bueno@lenep.uenf.br 25 de setembro de 2007

Copyright(C) 2003-2007 da Novatec Editora Ltda. proibida a reprodu Todos os direitos reservados e protegidos pela Lei 5.988 de 14/12/1973. E ca o desta obra, mesmo parcial, por qualquer processo, sem pr evia autoriza ca o, por escrito, do autor e da Editora.

Editor: RUBENS PRATES Capa: CAMILA MESQUITA Revis ao: PATRIZIA ZAGNI DUARTE BUENO Editora ca o eletr onica: ANDRE Revis ao t ecnica desta edi ca o: TIAGO RIBEIRO SCHAEWER [M.Sc, Doutorando] TIAGO CALIMMAN [Mestrando] IRINEU SILVA [Mestrando] ALLAN GALANTE [M.Sc.] GIOVANNI COLONESE [M.Sc.] ISBN: XX-XXXX-XXX-X

NOVATEC EDITORA LTDA. Rua Cons. Moreira de Barros, 1084 Conj. 01 02018-012 S ao Paulo, SP Brasil Tel.: +55 11 6959-6529 Fax: +55 11 6950-8869 E-mail: novatec@novateceditora.com.br Endere co: www.novateceditora.com.br

Este livro foi desenvolvido no LDSC/LENEP/UENF Laborat orio de Desenvolvimento de Software Cient co - LDSC http://www.lenep.uenf.br/~ldsc do Laborat orio de Engenharia e Explora ca o de Petr oleo - LENEP http://www.lenep.uenf.br da Universidade Estadual do Norte Fluminense - Darcy Ribeiro - UENF http://www.uenf.br

Sum ario
I Filosoa e Modelagem Orientada a Objeto
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

49
51 51 51 52 52 52 54 54 55 55 56 57 58 59 59 61 61 62 63 63 64 66 66 66 69 69 70 72 73 73 74 75 76 79 80

1 Introdu c ao ` a Programa c ao 1.1 Programas e softwares . . . . . . . . . . . . . . . . . . . . 1.1.1 O que e um programa, um software? . . . . . . . . 1.2 Deni ca o de software propriet ario e software livre . . . . . 1.2.1 Deni ca o e caracter sticas do software propriet ario 1.2.2 Deni ca o e caracter sticas do software livre . . . . 1.2.3 Exemplos de softwares livres e propriet arios . . . . 1.3 Tipos de interface de um programa/software . . . . . . . . 1.3.1 Um programa sem interface (kernel num erico) . . . 1.3.2 Um programa com interface via linha de comando 1.3.3 Um programa com interface em modo texto . . . . 1.3.4 Um software com interface em modo gr aco . . . . 1.4 Que tipo de software devo desenvolver? . . . . . . . . . . 1.5 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . 1.6 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 Introdu c ao ` a Programa c ao Orientada a Objeto POO 2.1 Entendendo os objetos . . . . . . . . . . . . . . . . . . . . . 2.2 Exemplo de objeto . . . . . . . . . . . . . . . . . . . . . . . 2.3 O conceito de objeto (ou inst ancia) . . . . . . . . . . . . . . 2.4 Breve hist orico da programa ca o orientada a objeto . . . . . 2.4.1 Vis ao desorganizada e vis ao estruturada versus vis ao 2.4.2 Vantagens da POO . . . . . . . . . . . . . . . . . . . 2.5 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . 2.6 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Conceitos B asicos de Orienta c ao a Objeto OO 3.1 Abstra ca o . . . . . . . . . . . . . . . . . . . . . . . 3.2 Encapsulamento e oculta ca o . . . . . . . . . . . . . 3.3 Classes . . . . . . . . . . . . . . . . . . . . . . . . . 3.4 Atributos (propriedades e vari aveis) . . . . . . . . 3.5 M etodos (fun co es, opera co es e servi cos) . . . . . . 3.6 Heran ca . . . . . . . . . . . . . . . . . . . . . . . . 3.7 Polimorsmo . . . . . . . . . . . . . . . . . . . . . 3.8 Outros conceitos u teis . . . . . . . . . . . . . . . . 3.9 Resumo do cap tulo . . . . . . . . . . . . . . . . . 3.10 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . orientada a objeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4 4 Modelagem Orientada a Objeto 4.1 Introdu ca o ` a modelagem . . . . . . . . . . . . . . . . . . . . . . 4.1.1 O que e um modelo? . . . . . . . . . . . . . . . . . . . . 4.1.2 Tipos e exemplos de modelos . . . . . . . . . . . . . . . 4.1.3 Por que usamos modelos? . . . . . . . . . . . . . . . . . 4.2 Introdu ca o ` a modelagem orientada a objeto . . . . . . . . . . . 4.2.1 O que e a modelagem orientada a objeto? . . . . . . . 4.2.2 Quando surgiu a modelagem orientada a objeto? . . . 4.2.3 Quais as vantagens da modelagem orientada a objeto? . 4.3 O que e a UML? . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.1 As diferentes vis oes da UML e os respectivos diagramas 4.3.2 Os elementos da UML . . . . . . . . . . . . . . . . . . . 4.3.3 Os estere otipos da UML2 . . . . . . . . . . . . . . . . . 4.4 Programas para modelagem orientada a objeto . . . . . . . . . 4.4.1 O programa Dia . . . . . . . . . . . . . . . . . . . . . . 4.4.2 O programa umbrello . . . . . . . . . . . . . . . . . . . 4.4.3 O programa Visual-Paradigm . . . . . . . . . . . . . . . 4.5 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . 4.6 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Engenharia de Software 5.1 O que e e quais s ao os objetivos da engenharia de software? . 5.2 Breve hist orico da engenharia de software . . . . . . . . . . . 5.3 Caracter sticas dos modelos de engenharia de software . . . . 5.3.1 Modelo seq uencial linear . . . . . . . . . . . . . . . . . 5.3.2 Modelo iterativo . . . . . . . . . . . . . . . . . . . . . 5.3.3 Modelo baseado em prototipagem . . . . . . . . . . . 5.3.4 Modelo RAD Rapid Application Development . . . 5.3.5 Modelo incremental . . . . . . . . . . . . . . . . . . . 5.3.6 Modelo espiral . . . . . . . . . . . . . . . . . . . . . . 5.3.7 Modelo TMO Tecnologia de Modelagem de Objetos 5.3.8 Modelo UP Unied Process . . . . . . . . . . . . . . 5.3.9 Modelo XP eXtreme Programming . . . . . . . . . . 5.4 O modelo selecionado . . . . . . . . . . . . . . . . . . . . . . 5.5 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . 5.6 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Etapas para o Desenvolvimento de um Software 6.1 Concep ca o especica ca o . . . . . . . . . . . . . . . . . . . 6.1.1 Casos de uso do software cen arios . . . . . . . . . 6.1.2 Diagrama de casos de uso . . . . . . . . . . . . . . . 6.1.3 Senten cas para casos de uso . . . . . . . . . . . . . . 6.2 Elabora ca o . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2.1 An alise de dom nio . . . . . . . . . . . . . . . . . . . 6.2.2 Identica ca o de pacotes assuntos . . . . . . . . . . 6.2.3 Diagrama de pacotes assuntos, m odulos . . . . . . 6.2.4 Senten cas para pacotes . . . . . . . . . . . . . . . . . 6.2.5 Montagem de prot otipo da interface do software . . 6.2.6 Deni ca o de cronogramas, prazos, custos, contratos 6.3 AOO An alise Orientada a Objeto . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

SUMARIO 81 81 81 82 82 84 84 84 85 85 85 88 89 93 93 94 96 96 97 99 99 100 101 101 102 102 102 102 102 103 103 104 105 106 106 109 110 111 111 113 114 115 116 116 117 117 118 119

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Andr e Duarte Bueno

SUMARIO 6.4 AOO Modelo estrutural . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.1 Identica ca o de classes . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.2 Identica ca o de atributos . . . . . . . . . . . . . . . . . . . . . . . 6.4.3 Identica ca o de m etodos . . . . . . . . . . . . . . . . . . . . . . . . 6.4.4 Diagrama de classes . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.5 Identica ca o de associa co es . . . . . . . . . . . . . . . . . . . . . . 6.4.6 Diagrama de classes com associa co es . . . . . . . . . . . . . . . . . 6.4.7 Classe de associa ca o . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.8 Identica ca o de agrega co es e composi co es . . . . . . . . . . . . . . 6.4.9 Diagrama de classes com agrega co es e composi co es . . . . . . . . . 6.4.10 Identica ca o de heran cas . . . . . . . . . . . . . . . . . . . . . . . 6.4.11 Diagrama de classes com heran cas . . . . . . . . . . . . . . . . . . 6.4.12 Identica ca o de classes abstratas e classes de interface . . . . . . . 6.4.13 Restri co es . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.14 Realiza co es . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.15 Depend encias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.16 Identica ca o de objetos . . . . . . . . . . . . . . . . . . . . . . . . 6.4.17 Diagrama de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.18 Diagrama de estrutura composta . . . . . . . . . . . . . . . . . . . 6.4.19 Resumo dos diagramas do modelo estrutural . . . . . . . . . . . . 6.4.20 Itera ca o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AOO Modelo din amico . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.5.1 Identica ca o de eventos e mensagens . . . . . . . . . . . . . . . . . 6.5.2 Diagrama de seq u encia eventos e mensagens . . . . . . . . . . . . 6.5.3 Diagrama de comunica ca o colabora ca o . . . . . . . . . . . . . . 6.5.4 Identica ca o dos estados assumidos pelo objeto . . . . . . . . . . . 6.5.5 Diagrama de m aquina de estado . . . . . . . . . . . . . . . . . . . 6.5.6 Identica ca o de atividades . . . . . . . . . . . . . . . . . . . . . . . 6.5.7 Diagrama de atividades . . . . . . . . . . . . . . . . . . . . . . . . 6.5.8 Diagrama de tempo . . . . . . . . . . . . . . . . . . . . . . . . . . 6.5.9 Diagrama de intera ca o geral . . . . . . . . . . . . . . . . . . . . . . 6.5.10 Resumo dos diagramas do modelo din amico . . . . . . . . . . . . . 6.5.11 Itera ca o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Projeto do sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.6.1 Deni ca o da interface de programa ca o API . . . . . . . . . . . . 6.6.2 Sele ca o da implementa ca o de controle . . . . . . . . . . . . . . . . 6.6.3 Sele ca o das plataformas a serem suportadas . . . . . . . . . . . . . 6.6.4 Sele ca o das bibliotecas externas . . . . . . . . . . . . . . . . . . . . 6.6.5 Sele ca o da biblioteca gr aca a ser utilizada GDI . . . . . . . . . 6.6.6 Sele ca o do ambiente de desenvolvimento integrado IDE . . . . . Projeto orientado a objeto POO . . . . . . . . . . . . . . . . . . . . . . 6.7.1 Diagrama de componentes . . . . . . . . . . . . . . . . . . . . . . . 6.7.2 Diagrama de implanta ca o execu ca o . . . . . . . . . . . . . . . . . Implementa ca o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.8.1 Antes de iniciar a implementa ca o . . . . . . . . . . . . . . . . . . . 6.8.2 Roteiro para montar o c odigo inicial do programa com o Umbrello 6.8.3 Dicas para implementa ca o da interface gr aca . . . . . . . . . . . Teste de software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.9.1 Por que testar? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5 119 119 120 121 122 123 124 125 125 126 126 128 128 130 130 130 130 131 131 131 132 133 133 134 137 138 139 143 143 146 146 146 146 148 149 150 150 151 152 152 157 159 160 161 161 161 162 162 163

6.5

6.6

6.7

6.8

6.9

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

6 6.9.2 Equipe de teste . . . . . . . . . . . . . . . . . . . . . 6.9.3 Metodologia de teste . . . . . . . . . . . . . . . . . . 6.9.4 Senten cas para teste de software . . . . . . . . . . . Documenta ca o do programa . . . . . . . . . . . . . . . . . . 6.10.1 Itens a serem documentados . . . . . . . . . . . . . . 6.10.2 Cart oes CRC . . . . . . . . . . . . . . . . . . . . . . 6.10.3 Dicion ario de classes . . . . . . . . . . . . . . . . . . Manuten ca o e reuso de software . . . . . . . . . . . . . . . . 6.11.1 Senten cas e dicas para conseguir o reuso de software 6.11.2 Senten cas para aumentar o empacotamento . . . . . 6.11.3 Senten cas para conseguir o reuso de classes . . . . . 6.11.4 Senten cas para conseguir o reuso de m etodos . . . . 6.11.5 Senten cas para montagem de bibliotecas . . . . . . 6.11.6 Senten cas para montagem de framework . . . . . . 6.11.7 Senten cas para facilitar a extens ao de um programa 6.11.8 Senten cas para programa ca o em grande escala . . . Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

SUMARIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 163 166 168 168 172 172 173 173 173 173 174 175 175 176 176 177 177

6.10

6.11

6.12 6.13

II

POO usando C++


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

181
. . . . . . . . . . . . . . . . . . . . . . . . . 183 183 184 185 185 186 186 187 189 189 189 190 191 192 193 193 195 195 198 199 199 199 200 200 201 201 202

7 Introdu c ao ao C++ 7.1 Um pouco de hist oria . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Exemplos de aplica co es em C++ . . . . . . . . . . . . . . . . . . . . 7.3 O que e o Ansi C++? . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4 Quais as novidades e vantagens de C++ em rela ca o a C? . . . . . . 7.5 Quais os tipos de programas em C++ . . . . . . . . . . . . . . . . . 7.6 Diferen cas de nomenclatura POO e C++ . . . . . . . . . . . . . . 7.7 Editar, pr e-processar, compilar, linkar, debugar e otimizar . . . . . . 7.8 Layout de um programa orientado a objeto em C++2 . . . . . . . . 7.8.1 Arquivo de projeto . . . . . . . . . . . . . . . . . . . . . . . . 7.8.2 Arquivo de cabe calho da classe CNomeClasse.h . . . . . . . 7.8.3 Arquivo de implementa ca o da classe CNomeClasse.cpp . . . 7.8.4 Arquivo de implementa ca o da fun ca o main() programa.cpp 7.9 Senten cas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.10 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.11 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Conceitos b asicos de C++ 8.1 Sobre a sintaxe de C++ . . . . . . . . . . . . . . . . . 8.2 Palavras-chave do C++ . . . . . . . . . . . . . . . . . 8.3 Nome dos objetos identicadores . . . . . . . . . . . 8.3.1 Conven ca o para nomes de objetos . . . . . . . 8.4 Declara co es . . . . . . . . . . . . . . . . . . . . . . . . 8.4.1 Exemplos de declara co es e deni co es2 . . . . . 8.5 Deni co es . . . . . . . . . . . . . . . . . . . . . . . . . 8.6 Introdu ca o ` a fun ca o main() . . . . . . . . . . . . . . . 8.7 Introdu ca o ` a entrada e sa da de dados com cin e cout 8.7.1 Usando cout . . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Andr e Duarte Bueno

SUMARIO 8.7.2 Usando cin . . . . . . . . . . . . . . . . Introdu ca o ` as diretrizes de pr e-processador . . 8.8.1 Usando #ifdef..#endif . . . . . . . . Introdu ca o ` as estruturas de controle . . . . . . 8.9.1 Usando for . . . . . . . . . . . . . . . . 8.9.2 Usando while e fun co es da biblioteca de Introdu ca o aos operadores de C++ . . . . . . . 8.10.1 Usando operadores de C++ . . . . . . . Introdu ca o as fun co es . . . . . . . . . . . . . . Declara co es e escopo . . . . . . . . . . . . . . . Senten cas para conceitos b asicos de C++ . . . Resumo do cap tulo . . . . . . . . . . . . . . . Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C/C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 203 205 205 206 206 207 208 208 210 213 214 215 216 217 217 217 221 222 224 225 225 225 228 229 229 230 231 233 235 235 236 236 238 239 239 240 240 243 243 244 244 245 247 248 248 248 248 249

8.8 8.9

8.10 8.11 8.12 8.13 8.14 8.15

9 Tipos 9.1 Introdu ca o ao conceito de tipos . . . . . . . . . . . . 9.2 Uso de tipos predenidos de C++ . . . . . . . . . . 9.2.1 Uso de suxos para os tipos predenidos2 . . 9.2.2 Uso avan cado dos tipos predenidos2 . . . . . 9.2.3 Senten cas para uso de tipos predenidos . . . 9.3 Uso de tipos do usu ario . . . . . . . . . . . . . . . . 9.3.1 Introdu ca o aos vetores no estilo de C . . . . . 9.3.2 Introdu ca o ` as estruturas . . . . . . . . . . . 9.3.3 Introdu ca o ` as uni oes . . . . . . . . . . . . . . 9.3.4 Introdu ca o ` as enumera co es . . . . . . . . . . 9.3.5 Introdu ca o ` as classes . . . . . . . . . . . . . . 9.4 Usando tipos denidos em bibliotecas STL . . . . 9.4.1 Introdu ca o ` a classe <string> . . . . . . . . . 9.4.2 Introdu ca o ` a STL e ` a classe <vector> . . . . 9.5 Manipulando tipos . . . . . . . . . . . . . . . . . . . 9.5.1 Criando apelidos typedef . . . . . . . . . 9.5.2 Obtendo o tipo de tamanho size_t() . . . 9.5.3 Obtendo o tamanho dos objetos sizeof() . 9.5.4 Identicando o tipo do objeto typeid()2 . 9.6 Vantagem da tipica ca o forte do C++ . . . . . . . . 9.7 Senten cas para tipos . . . . . . . . . . . . . . . . . . 9.8 Resumo do cap tulo . . . . . . . . . . . . . . . . . . 9.9 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . .

10 Namespace 10.1 O que e um namespace? . . . . . . . . . . . . . . . . . . . . 10.2 Utilizando o espa co de nomes da biblioteca-padr ao std:: 10.3 Mudando escopo com using . . . . . . . . . . . . . . . . . . 10.4 Prot otipo para declarar e denir um namespace . . . . . . . 10.5 Namespaces an onimos . . . . . . . . . . . . . . . . . . . . . 10.6 Namespaces uso avan cado2 . . . . . . . . . . . . . . . . . 10.6.1 Compondo namespace com using2 . . . . . . . . . . 10.6.2 Namespace aninhado2 . . . . . . . . . . . . . . . . . 10.6.3 Usando vari aveis est aticas em um namespace2 . . . 10.7 Senten cas para namespace . . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

SUMARIO 10.8 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 10.9 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250

11 Classes 11.1 Prot otipo para declarar e denir classes . . . . . . . . 11.2 Encapsulamento em C++ utilizando o especicador de 11.3 Classes e escopo . . . . . . . . . . . . . . . . . . . . . 11.4 Classes e diretrizes de pr e-processador . . . . . . . . . 11.5 Classes Uso avan cado2 . . . . . . . . . . . . . . . . . 11.5.1 Classes abstratas2 . . . . . . . . . . . . . . . . 11.5.2 Classes de interface2 . . . . . . . . . . . . . . . 11.5.3 Classes encapsulamento e robustes de c odigo2 . 3 11.5.4 Classes aninhadas . . . . . . . . . . . . . . . . 11.5.5 Classes do tipo POD3 . . . . . . . . . . . . . . 11.5.6 Classes do tipo trivial3 . . . . . . . . . . . . . . 11.6 Senten cas para classes . . . . . . . . . . . . . . . . . . 11.7 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . 11.8 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . 12 Atributos 12.1 Prot otipo para declarar e denir atributos 12.2 Atributos de objeto . . . . . . . . . . . . . 12.3 Atributos de classe static . . . . . . . 12.4 Atributos constantes const . . . . . . . 12.5 Atributos uso avan cado2 . . . . . . . . . 12.5.1 Atributos mutantes mutable2 . . 12.5.2 Atributos vol ateis volatile3 . . 12.6 Senten cas para atributos . . . . . . . . . . 12.7 Resumo do cap tulo . . . . . . . . . . . . 12.8 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . acesso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

251 251 252 253 253 254 254 255 255 256 257 257 258 259 259 261 261 262 263 265 266 266 267 267 268 268 269 269 270 271 272 273 273 274 274 275 277 278 281 284 286 290 290 292 292

13 M etodos 13.1 Introdu ca o aos m etodos de C++ . . . . . . . . . 13.2 Prot otipo para declarar e denir m etodos . . . . 13.3 Declara ca o de um m etodo . . . . . . . . . . . . . 13.4 Deni ca o de um m etodo . . . . . . . . . . . . . . 13.5 Retorno de um m etodo . . . . . . . . . . . . . . . 13.6 Par ametros dos m etodos . . . . . . . . . . . . . . 13.6.1 Passagem dos par ametros por c opia . . . 13.6.2 Passagem dos par ametros por refer encia 13.6.3 Passagem dos par ametros por ponteiro . . 13.6.4 Par ametros predenidos inicializadores . 13.7 M etodos normais . . . . . . . . . . . . . . . . . . 13.8 M etodos constantes const . . . . . . . . . . . . 13.9 M etodos est aticos static . . . . . . . . . . . . 13.10M etodos em linha inline . . . . . . . . . . . . 13.11M etodos uso avan cado . . . . . . . . . . . . . . 13.12Senten cas para m etodos . . . . . . . . . . . . . . 13.13Resumo do cap tulo . . . . . . . . . . . . . . . . 13.14Exerc cios . . . . . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

SUMARIO 14 Sobrecarga de M etodos 14.1 Prot otipo para sobrecarga de m etodos . . . . . . . 14.2 Como implementar a sobrecarga de m etodos . . . 14.3 Sobrecarga de m etodos conceitos avan cados2 . . 14.3.1 Acessibilidade x visibilidade: como e feita executado . . . . . . . . . . . . . . . . . . . 14.4 Senten ca para sobrecarga de m etodos . . . . . . . . 14.5 Resumo do cap tulo . . . . . . . . . . . . . . . . . 14.6 Exerc cios . . . . . . . . . . . . . . . . . . . . . . .

9 295 . 295 . 295 . 297 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 297 298 298 299 299 300 301 302 302 304 305 305 306 306 306 308 308 308 308 308 310 312 313 314 315 315 316 317 318 319 323 325 326 327 328 329 329 330 331 332 334 335

. . . . . . . . . . . . . . . . . . a sele ca o . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . do . . . . . . . .

. . . . . . . . . . . . . . . . . . m etodo a . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . ser . . . . . . . .

15 Ponteiros, Refer encias e Gerenciamento de Mem oria 15.1 Prot otipo para declarar e denir ponteiros e refer encias . . . . . . . . . . . . . 15.2 Ponteiros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.3 Cria ca o e uso de objetos din amicos com ponteiros . . . . . . . . . . . . . . . . . 15.3.1 O operador new . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.3.2 O operador delete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.4 Ponteiro this . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.5 Ponteiros const e ponteiros para const . . . . . . . . . . . . . . . . . . . . . . 15.5.1 Ponteiro para um objeto constante . . . . . . . . . . . . . . . . . . . . . 15.5.2 Ponteiro constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.5.3 Ponteiro constante para um objeto constante . . . . . . . . . . . . . . . 15.6 Refer encias (&) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.6.1 Diferen cas entre refer encia e ponteiro . . . . . . . . . . . . . . . . . . . . 15.6.2 Refer encias para ponteiros . . . . . . . . . . . . . . . . . . . . . . . . . . 15.7 Conceitos b asicos de gerenciamento de mem oria2 . . . . . . . . . . . . . . . . . 15.7.1 Entendendo o uso de new/delete com vetores . . . . . . . . . . . . . . 15.7.2 Alinhamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.7.3 D uvidas freq uentes no uso de new, delete e gerenciamento de mem oria2 15.8 Senten cas para ponteiros, refer encias e gerenciamento de mem oria . . . . . . . 15.9 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15.10Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 M etodos Construtores e Destrutores 16.1 Introdu ca o aos m etodos construtores e destrutores . 16.2 Prot otipo para construtores e destrutores . . . . . . 16.3 Construtor default T() . . . . . . . . . . . . . . . . . 16.4 Inicializa ca o dos atributos da classe nos contrutores 16.5 Construtor de c opia T(const T& obj) . . . . . . . . 16.5.1 Construtor de c opia e objetos din amicos . . . 16.6 Quando o objeto e constru do/destru do . . . . . . . 16.6.1 Ordem de constru ca o dos atributos . . . . . . 16.6.2 Ordem de destrui ca o dos atributos . . . . . . 16.6.3 Constru ca o de objetos globais est aticos . . . 16.7 Construtor e ambig uidade . . . . . . . . . . . . . . . 16.8 Construtor e destrutor conceitos avan cados2 . . . . 16.8.1 Construtor e ambig uidade . . . . . . . . . . . 16.8.2 Construtor e interface . . . . . . . . . . . . . 16.9 Senten cas para construtores e destrutores . . . . . . 16.10Resumo do cap tulo . . . . . . . . . . . . . . . . . . 16.11Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Andr e Duarte Bueno

10 17 Heran ca 17.1 Prot otipo para heran ca simples . . . . . . . . . . . . . . 17.2 Como implementar a heran ca simples . . . . . . . . . . 17.3 Especicador de heran ca . . . . . . . . . . . . . . . . . . 17.4 Diferen ca entre heran ca p ublica e privada . . . . . . . . 17.5 Mudando a visibilidade em heran cas com using . . . . . 17.6 Chamando construtores da classe-base explicitamente . 17.7 Redeclara ca o de m etodo ou atributo na classe-derivada . 17.8 Senten cas para heran ca . . . . . . . . . . . . . . . . . . 17.9 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . 17.10Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . .

SUMARIO 337 337 338 339 341 341 342 342 344 345 346 347 347 347 349 349 351 352 353 355 357 359 361 361 363 363 365 366 367 369 369 369 370 378 379

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

18 Heran ca M ultipla 18.1 Prot otipo para heran ca m ultipla . . . . . . . . . . . . . . . . . 18.2 Como implementar a heran ca m ultipla . . . . . . . . . . . . . . 18.3 Resolvendo ambig uidade em heran ca m ultipla com using . . . 18.4 Heran ca m ultipla com base comum . . . . . . . . . . . . . . . . 18.5 Ordem de cria ca o e destrui ca o dos objetos em heran cas . . . . 18.6 Heran ca m ultipla virtual . . . . . . . . . . . . . . . . . . . . . 18.7 Ordem de cria ca o e destrui ca o dos objetos em heran ca m ultipla 18.8 Senten cas para heran ca m ultipla . . . . . . . . . . . . . . . . . 18.9 Exemplo de heran ca simples e heran ca m ultipla . . . . . . . . . 18.10An alise dos erros emitidos pelo compilador2 . . . . . . . . . . . 18.11Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . 18.12Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Polimorsmo 19.1 M etodos n ao virtuais . . . . . . . . . . . 19.2 M etodos virtuais . . . . . . . . . . . . . 19.2.1 Senten cas para m etodos virtuais 19.3 Como implementar o polimorsmo . . . 19.3.1 Senten cas para polimorsmo . . 19.4 M etodos virtuais puros . . . . . . . . . 19.5 M etodos virtuais sobrecarregados . . . . 19.6 Exemplo completo com polimorsmo . . 19.7 Resumo do cap tulo . . . . . . . . . . . 19.8 Exerc cios . . . . . . . . . . . . . . . . . 20 Friend 20.1 Introdu ca o ao conceito de friend . 20.2 Prot otipo para friend . . . . . . . 20.3 Classes friend . . . . . . . . . . . 20.4 M etodos friend . . . . . . . . . . 20.5 Fun co es globais friend . . . . . . 20.6 Senten cas para friend . . . . . . . 20.7 Resumo do cap tulo . . . . . . . . 20.8 Exerc cios . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . virtual . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

381 . 381 . 382 . 383 . 383 . 384 . 385 . 386 . 386

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

SUMARIO 21 Sobrecarga de Operador 21.1 Introdu ca o ` a sobrecarga de operador . . . . . . . . . . . 21.2 Operadores que podem ser sobrecarregados . . . . . . . 21.3 Prot otipo para sobrecarga de operador . . . . . . . . . . 21.4 Sobrecarga de operador como fun ca o friend . . . . . . 21.5 Sobrecarga de operador como m etodo membro da classe 21.6 Exemplo pr atico de sobrecarga de operador . . . . . . . 21.7 Como sobrecarregar ++ e -- . . . . . . . . . . . . . . . . 21.8 Como sobrecarregar new2 . . . . . . . . . . . . . . . . . 21.8.1 Como sobrecarregar new dentro de uma classe2 . 21.9 Senten cas para sobrecarga de operador . . . . . . . . . . 21.10Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . 21.11Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Entrada e Sa da 22.1 Introdu ca o ` a entrada e sa da de dados com C++ 22.1.1 Streams buferizadas . . . . . . . . . . . . 22.2 Biblioteca de entrada e sa da . . . . . . . . . . . 22.3 A classe ios_base . . . . . . . . . . . . . . . . . 22.4 A classe <iomanip> . . . . . . . . . . . . . . . . . 22.5 A classe <ostream> . . . . . . . . . . . . . . . . . 22.5.1 Senten cas para <ostream> . . . . . . . . . 22.6 A classe <ios> . . . . . . . . . . . . . . . . . . . 22.6.1 Senten cas para <ios> . . . . . . . . . . . 22.7 A classe <istream> . . . . . . . . . . . . . . . . . 22.7.1 Senten cas para <istream> . . . . . . . . . 22.8 A classe <sstream> . . . . . . . . . . . . . . . . . 22.9 Entrada e sa da uso avan cado . . . . . . . . . . 22.9.1 Como criar e usar um manipulador . . . . 22.9.2 A classe locale2 . . . . . . . . . . . . . . 22.9.3 Usando facets 2 . . . . . . . . . . . . . . . 22.10Senten cas para stream . . . . . . . . . . . . . . . 22.11Resumo do cap tulo . . . . . . . . . . . . . . . . 22.12Exerc cios . . . . . . . . . . . . . . . . . . . . . .

11 387 387 388 388 389 390 391 396 396 397 398 400 401 403 403 404 404 405 411 414 415 415 416 417 421 422 423 423 424 427 428 428 429

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . .

23 Entrada e Sa da com Arquivos de Disco 23.1 Introdu ca o ao acesso a disco . . . . . . . . . . . . . . . . . . . . 23.2 A classe <fstream> . . . . . . . . . . . . . . . . . . . . . . . . . 23.3 Armazenando e lendo objetos . . . . . . . . . . . . . . . . . . . 23.4 Redirecionamento de entrada e sa da . . . . . . . . . . . . . . . 23.5 Entrada e Sa da com Arquivos de Disco - Uso Avan cado . . . 23.5.1 Posicionando ponteiros de arquivos2 . . . . . . . . . . . 23.5.2 Acessando a impressora e a sa da auxiliar2 . . . . . . . . 23.5.3 Arquivos de disco bin arios2 . . . . . . . . . . . . . . . . 23.5.4 Executando e enviando comandos para outro programa2 23.6 Senten cas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23.7 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . 23.8 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

431 . 431 . 431 . 436 . 439 . 441 . 441 . 443 . 444 . 444 . 446 . 446 . 447

Andr e Duarte Bueno

12 24 A Classe <string> 24.1 Introdu ca o ` as strings . . . . . . . . . . . . . 24.2 M etodos de <string> . . . . . . . . . . . . . 24.2.1 Construtores e destrutor . . . . . . . . 24.2.2 Iteradores . . . . . . . . . . . . . . . . 24.2.3 Manipula ca o do tamanho da string . 24.2.4 Operadores de acesso . . . . . . . . . 24.2.5 Atribui ca o e concatena ca o . . . . . . . 24.2.6 Inser ca o, remo ca o, substitui ca o, c opia 24.2.7 Compara ca o . . . . . . . . . . . . . . 24.2.8 Substrings . . . . . . . . . . . . . . . . 24.2.9 Pesquisa . . . . . . . . . . . . . . . . . 24.3 Exemplos de uso de <string> . . . . . . . . . 24.4 Senten cas para strings de C++ . . . . . . . . 24.5 Resumo do cap tulo . . . . . . . . . . . . . . 24.6 Exerc cios . . . . . . . . . . . . . . . . . . . .

SUMARIO 449 449 450 450 451 451 452 452 453 453 454 454 455 459 460 460 461 461 462 463 464 465 466 466 468 468 468 469 470 470 473 473 474 475 476 476 477 478 478 479 479 479 482 483 483 484 486 486

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25 Convers oes 25.1 Prot otipo para convers oes . . . . . . . . . . . . . . . 25.2 Necessidade de convers ao . . . . . . . . . . . . . . . 25.3 Construtor de convers ao . . . . . . . . . . . . . . . . 25.4 Operador de convers ao - cast . . . . . . . . . . . . . 25.5 Convers ao explicita nos construtores com explicit . 25.6 Convers ao est atica com static_cast<> . . . . . . . 25.7 Convers ao din amica com dynamic_cast<> . . . . . . 25.7.1 dynamic_cast<> e refer encias . . . . . . . . . 25.8 Convers ao com const_cast<> . . . . . . . . . . . . . 25.9 Convers ao com reinterpret_cast<> . . . . . . . . 25.10Senten cas para convers oes . . . . . . . . . . . . . . . 25.11Resumo do cap tulo . . . . . . . . . . . . . . . . . . 25.12Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . 26 Exce co es 26.1 Introdu ca o ` as exce co es . . . . . . . . . . . . . . . . . 26.2 Prot otipo para exce co es . . . . . . . . . . . . . . . . 26.3 Conceitos b asicos de exce co es . . . . . . . . . . . . . 26.3.1 try . . . . . . . . . . . . . . . . . . . . . . . 26.3.2 throw . . . . . . . . . . . . . . . . . . . . . . 26.3.3 catch . . . . . . . . . . . . . . . . . . . . . . 26.4 Exce co es-padr ao . . . . . . . . . . . . . . . . . . . . 26.5 Seq uencia de execu ca o . . . . . . . . . . . . . . . . . 26.5.1 Seq uencia de execu ca o sem exce ca o . . . . . . 26.5.2 Seq uencia de execu ca o com exce ca o . . . . . 26.6 Como ca a pilha (heap ) . . . . . . . . . . . . . . . . 26.7 Exce co es n ao tratadas . . . . . . . . . . . . . . . . . 26.8 Exce co es - Uso avan cado . . . . . . . . . . . . . . . . 26.8.1 Exce ca o para new2 . . . . . . . . . . . . . . . 26.8.2 Controlando entrada com exce co es2 . . . . . 26.8.3 Adotando uma pol tica para uso de exce co es2 26.9 Senten cas para exce co es . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

SUMARIO

13

26.10Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 26.11Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 27 Templates ou Gabaritos 27.1 Introdu ca o aos templates (gabaritos) . . . . . . . . . . . . . . . . 27.2 Fun co es templates . . . . . . . . . . . . . . . . . . . . . . . . . . 27.2.1 Prot otipo para fun co es templates . . . . . . . . . . . . . . 27.2.2 Inst ancias de fun co es template e dedu ca o de argumentos 27.2.3 Declara ca o expl cita de fun ca o template . . . . . . . . . . 27.2.4 Resolvendo problemas de convers oes . . . . . . . . . . . . 27.2.5 Sobrecarga de fun ca o template . . . . . . . . . . . . . . . 27.2.6 Fun ca o template com objeto est atico . . . . . . . . . . . 27.3 Classes templates ou tipos param etricos . . . . . . . . . . . . . . 27.3.1 Prot otipo para classes template . . . . . . . . . . . . . . 27.3.2 Regras gerais para classes template . . . . . . . . . . . . . 27.3.3 Argumentos pr e-denidos em classes templates . . . . . . 27.4 Senten cas para templates . . . . . . . . . . . . . . . . . . . . . . 27.5 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . . 27.6 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Templates - Uso Avan cado 28.1 Fun co es template uso avan cado . . . . . . . . . . . . . . . . 28.1.1 Especializa ca o de fun co es template . . . . . . . . . . 28.1.2 Fun co es expandidas em tempo de compila ca o . . . . . 28.1.3 Usando typename com templates . . . . . . . . . . . . 28.1.4 Mapeando fun co es template utilizando especializa co es 28.1.5 Fun co es template e friend . . . . . . . . . . . . . . . 28.2 Classes template uso avan cado . . . . . . . . . . . . . . . . . 28.2.1 Templates dentro de uma classe template . . . . . . . 28.2.2 Especializa ca o de classes templates . . . . . . . . . . . 28.2.3 Instanciando fun co es e classes template2 . . . . . . . . 28.3 Uso de export com templates3 . . . . . . . . . . . . . . . . . 28.4 Senten cas para uso avan cado de templates . . . . . . . . . . . 28.5 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . 28.6 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 Implementando Associa co es em C++ 29.1 Introdu ca o ` as associa co es em C++ . . 29.2 Associa ca o sem atributo . . . . . . . . 29.3 Associa ca o com atributo . . . . . . . . 29.4 Resumo do cap tulo . . . . . . . . . . 29.5 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 492 492 492 493 494 495 495 496 496 496 497 500 503 505 505 507 507 507 509 510 511 513 513 513 517 518 520 520 522 522 523 523 523 524 525 525 527 527 527 529 530 530 532

30 As Classes <complex>, <bitset> e as Fun co es Matem aticas de <cmath> 30.1 Introdu ca o ` a biblioteca <cmath> de C . . . . . . . . . . . . . . . . . . . . 30.1.1 Fun coes de <cmath> . . . . . . . . . . . . . . . . . . . . . . . . . . 30.1.2 Exemplos de uso de <cmath> . . . . . . . . . . . . . . . . . . . . . 30.2 Introdu ca o ` a classe <complex> . . . . . . . . . . . . . . . . . . . . . . . . 30.2.1 M etodos de <complex> . . . . . . . . . . . . . . . . . . . . . . . . 30.2.2 Exemplo de uso de <complex> . . . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

14 30.2.3 Resumo da classe <complex> fornecida pela biblioteca padr ao 30.3 Introdu ca o ` a classe <bitset> . . . . . . . . . . . . . . . . . . . . . . 30.3.1 M etodos de <bitset> . . . . . . . . . . . . . . . . . . . . . 30.3.2 Exemplos de uso da classe <bitset> . . . . . . . . . . . . . 30.3.3 Exemplo de uso de <bitset> com <vector>2 . . . . . . . . . 30.4 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . . . . 30.5 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

SUMARIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532 534 535 535 537 539 539

III

Introdu c ao a STL
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

541
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543 543 544 544 545 545 546 547 547 547 548 549 549 550 552 552 554 555 555 555 557 557 558 559 560 561 561 561 562 562 564 565 565 566 566 566 567 568

31 Introdu c ao a Biblioteca Padr ao de Gabaritos de C++ - STL 31.1 O que e a STL? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.1.1 Caracter sticas da STL . . . . . . . . . . . . . . . . . . . . 31.1.2 Componentes da STL . . . . . . . . . . . . . . . . . . . . 31.2 Introdu ca o aos containers . . . . . . . . . . . . . . . . . . . . . . 31.2.1 Containers seq uencias . . . . . . . . . . . . . . . . . . . . 31.2.2 Containers associativos . . . . . . . . . . . . . . . . . . . 31.2.3 Containers adaptativos . . . . . . . . . . . . . . . . . . . 31.2.4 M etodos e operadores comuns aos diversos containers . . 31.2.5 M etodos v alidos apenas para os containers seq uenciais . 31.2.6 Typedefs comuns aos diversos containers2 . . . . . . . . 31.3 Introdu ca o aos iteradores - iterators . . . . . . . . . . . . . . . 31.3.1 Tipos de iteradores . . . . . . . . . . . . . . . . . . . . . . 31.3.2 Opera co es comuns com iteradores2 . . . . . . . . . . . . . 31.4 Iteradores - Uso avan cado2 . . . . . . . . . . . . . . . . . . . . . 31.4.1 Iteradores de inser ca o . . . . . . . . . . . . . . . . . . . . 31.5 Senten cas para STL e iteradores . . . . . . . . . . . . . . . . . . 31.6 Fun ca o predicado . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.7 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . . 31.8 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Os Containers Sequ enciais <vector>, <list>, <deque> 32.1 A classe container <vector> . . . . . . . . . . . . . . . 32.1.1 Construtores e destrutor . . . . . . . . . . . . . 32.1.2 Iteradores de <vector> . . . . . . . . . . . . . 32.1.3 Refer encias e acesso . . . . . . . . . . . . . . . 32.1.4 Operadores . . . . . . . . . . . . . . . . . . . . 32.1.5 Capacidade e redimensionamento . . . . . . . . 32.1.6 Inser ca o, dele ca o e atribui ca o . . . . . . . . . . 32.1.7 Operadores sobrecarregados . . . . . . . . . . . 32.1.8 Exemplo de <vector> . . . . . . . . . . . . . . 32.1.9 Senten cas para <vector> . . . . . . . . . . . . 32.2 A classe container <list> . . . . . . . . . . . . . . . . 32.2.1 Construtores e destrutor . . . . . . . . . . . . . 32.2.2 Operadores . . . . . . . . . . . . . . . . . . . . 32.2.3 Refer encia e acesso . . . . . . . . . . . . . . . . 32.2.4 Inser ca o, mistura e ordena ca o . . . . . . . . . . 32.2.5 Remo ca o e c opia u nica . . . . . . . . . . . . . . 32.2.6 Exemplo de <list> . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Andr e Duarte Bueno

SUMARIO 32.2.7 Senten cas para <list> . 32.3 A classe container <deque> . . 32.3.1 Construtores e destrutor 32.3.2 Exemplo de <deque> . . 32.4 Resumo do cap tulo . . . . . . 32.5 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15 571 571 572 572 573 574 577 577 578 578 579 580 581 581 582 582 583 583 585 585 585 586 586 586 587 587 587 588 589 589 589 590 590 590 590 591 593 594 594 594 597 598 598 598 598 599 600

33 Os Containers Adaptativos <stack>, <queue> e <priority_queue> 33.1 A classe container <stack> . . . . . . . . . . . . . . . . . . . . . . 33.1.1 M etodos de <stack> . . . . . . . . . . . . . . . . . . . . . . 33.1.2 A listagem da classe <stack> . . . . . . . . . . . . . . . . . 33.1.3 Exemplo de <stack> . . . . . . . . . . . . . . . . . . . . . . 33.2 A classe container <queue> . . . . . . . . . . . . . . . . . . . . . . 33.2.1 M etodos de <queue> . . . . . . . . . . . . . . . . . . . . . . 33.2.2 A listagem da classe <queue> . . . . . . . . . . . . . . . . . 33.2.3 Exemplo de <queue> . . . . . . . . . . . . . . . . . . . . . . 33.3 A classe container <priority_queue> . . . . . . . . . . . . . . . . 33.4 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . . . 33.5 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 Os Containers Associativos <set>, 34.1 A classe <pair> . . . . . . . . . . 34.2 A classe container <set> . . . . . 34.2.1 Contrutores e destrutor . 34.2.2 Trocas . . . . . . . . . . . 34.2.3 Inser ca o e dele ca o . . . . 34.2.4 Pesquisa e contagem . . . 34.2.5 Operadores . . . . . . . . 34.2.6 Exemplo de <set> . . . . 34.3 A classe container <multiset> . 34.3.1 Contrutores e destrutor . 34.3.2 Operadores . . . . . . . . 34.4 A classe container <map> . . . . . 34.4.1 Construtores e destrutor . 34.4.2 Operadores . . . . . . . . 34.4.3 Inser ca o e dele ca o . . . . 34.4.4 Pesquisa e contagem . . . 34.4.5 Exemplo de <map> . . . . 34.4.6 Senten cas para <map> . . 34.5 A classe container <multimap> . 34.6 Resumo do cap tulo . . . . . . . 34.7 Exerc cios . . . . . . . . . . . . .

<multiset>, <map> e <multimap> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

35 Programa c ao Gen erica 35.1 Introdu ca o ` a programa ca o gen erica . . . . . . . . . . . 35.2 Classica ca o das fun co es gen ericas . . . . . . . . . . . 35.2.1 Classica ca o quanto ` a modica ca o do container 35.2.2 Classica ca o quanto ` a categoria dos iteradores 35.2.3 Classica ca o quanto ` as opera co es realizadas . . 35.3 Fun co es gen ericas . . . . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

16 35.3.1 Preenchimento . . . . . . . . . . . . . 35.3.2 Compara ca o . . . . . . . . . . . . . . 35.3.3 Remo ca o . . . . . . . . . . . . . . . . 35.3.4 Troca . . . . . . . . . . . . . . . . . . 35.3.5 Misturar/Mesclar/Inverter . . . . . . . 35.3.6 Pesquisa . . . . . . . . . . . . . . . . . 35.3.7 Ordena ca o . . . . . . . . . . . . . . . 35.3.8 Classica ca o . . . . . . . . . . . . . . 35.3.9 Transforma ca o . . . . . . . . . . . . . 35.3.10 Matem aticos . . . . . . . . . . . . . . 35.3.11 Opera co es matem aticas com conjuntos 35.3.12 Ordena ca o de pilhas - heapsort . . . . Exemplos de uso das fun co es gen ericas . . . . Senten cas para c odigo gen erico . . . . . . . . Resumo do cap tulo . . . . . . . . . . . . . . Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

SUMARIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600 600 601 601 602 602 603 604 604 605 606 606 607 612 612 613 615 615 615 616 616 616 617 618 629 629 629 629 630 630 631

35.4 35.5 35.6 35.7

36 Objetos Fun co es da STL 36.1 Introdu ca o aos objetos fun co es da STL . . . . . . . . . . . . . . . . . . . 36.1.1 Fun co es un arias . . . . . . . . . . . . . . . . . . . . . . . . . . . 36.1.2 Fun co es bin arias . . . . . . . . . . . . . . . . . . . . . . . . . . . 36.2 Objetos fun co es fornecidos pela STL . . . . . . . . . . . . . . . . . . . . 36.2.1 Fun co es aritm eticas . . . . . . . . . . . . . . . . . . . . . . . . . 36.2.2 Fun co es de compara ca o . . . . . . . . . . . . . . . . . . . . . . . 36.2.3 Fun co es l ogicas . . . . . . . . . . . . . . . . . . . . . . . . . . . 36.3 STL - Uso Avan cado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36.3.1 O adaptador bin2nd() . . . . . . . . . . . . . . . . . . . . . . . . 36.3.2 Os adaptadores not1(),not2() . . . . . . . . . . . . . . . . . . . 36.3.3 Os adaptadores - men_fun(), men_fun_ptr() e men_fun_ref() . 36.3.4 Extendendo a STL - especializa ca o para std::swap . . . . . . . 36.4 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36.5 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

IV

Ap endices
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

637
. . . . . . . . . . . . . 639 639 639 640 640 640 641 641 641 642 642 643 643 643

A Diretrizes de Pr e-Processador A.1 Fase de pr e-processamento . . . . . . . . . A.2 Inclus ao de arquivos . . . . . . . . . . . . A.3 Compila ca o condicional . . . . . . . . . . A.3.1 #define . . . . . . . . . . . . . . . A.3.2 #ifdef . . . . . . . . . . . . . . . A.3.3 #ifndef . . . . . . . . . . . . . . . A.3.4 #undef . . . . . . . . . . . . . . . A.3.5 #if . . . . . . . . . . . . . . . . . A.3.6 #ifdef...else . . . . . . . . . . . A.3.7 #if...else . . . . . . . . . . . . . A.3.8 #if...#elif...#elif...#endif . A.4 Macros . . . . . . . . . . . . . . . . . . . . A.4.1 Macros pr e-denidas . . . . . . . .

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

SUMARIO A.5 A.6 A.7 A.8 Instru co es de guarda . . Senten cas para diretrizes Resumo do cap tulo . . Exerc cios . . . . . . . . . . . . . . . . . . . de pr e-processador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17 644 645 645 645 647 647 648 649 652 653 654 655 655 657 658 658 659 659 659 660 661 662 662 663 663 664 664 664 664 664 664 665 665 665 667 667 668 668 668 669 669 671 671 671 672 673 673

B Conceitos Uteis Para Programa c ao em C B.1 Especicador de classe de armazenamento - tempo de vida . B.2 Especicador de linkagem . . . . . . . . . . . . . . . . . . . B.2.1 Uso de extern . . . . . . . . . . . . . . . . . . . . . B.3 Modicadores de acesso . . . . . . . . . . . . . . . . . . . . B.4 Escopo das vari aveis . . . . . . . . . . . . . . . . . . . . . . B.5 Senten cas . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.6 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . . . B.7 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . C Operadores C.1 Introdu ca o aos operadores . . . . . . . . . . . . . . . . . C.1.1 Operadores aritm eticos (+,-,*,/,%) . . . . . . . C.1.2 Operadores de atribui ca o (=) . . . . . . . . . . . C.1.3 Operadores compostos (+=, -=, *=, /=) . . . . C.1.4 Operadores relacionais (>, >=, <, <=, ==, !=) C.1.5 Operadores l ogicos (&&, ||, !, ==, !=) . . . . C.1.6 Operadores de bits (&, |) . . . . . . . . . . . . . C.1.7 Operador condicional (?) . . . . . . . . . . . . . C.1.8 Operador incremento (++) e decremento (--) . . C.1.9 Operador v rgula (a,b) . . . . . . . . . . . . . . C.1.10 Operador m odulo (%) . . . . . . . . . . . . . . . C.1.11 Operador new . . . . . . . . . . . . . . . . . . . . C.1.12 Operador delete . . . . . . . . . . . . . . . . . . C.1.13 Operador typedef . . . . . . . . . . . . . . . . . C.1.14 Operador sizeof . . . . . . . . . . . . . . . . . C.1.15 Operador size_t . . . . . . . . . . . . . . . . . . C.1.16 Operador de resolu ca o de escopo (::) . . . . . . C.2 Senten cas para operadores . . . . . . . . . . . . . . . . . C.3 Resumo do cap tulo . . . . . . . . . . . . . . . . . . . . C.4 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

D Estruturas de Controle D.1 Introdu ca o ` as estruturas de controle . . . . . . . . . . . . . . . . . . . . D.2 Estruturas condicionais . . . . . . . . . . . . . . . . . . . . . . . . . . . D.2.1 if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D.2.2 if.....else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . D.2.3 if......else if......else if......else . . . . . . . . . . . D.2.4 switch....case . . . . . . . . . . . . . . . . . . . . . . . . . . . D.2.5 express~ ao_condicional? a c~ ao_verdadeira : a c~ ao_falsa; D.3 Estruturas de repeti ca o . . . . . . . . . . . . . . . . . . . . . . . . . . . D.3.1 for ( in cializa c~ ao ; condi c~ ao ; a c~ ao2 ) a c~ ao1; . . . . . D.3.2 while (condi c~ ao) {a c~ ao;}; . . . . . . . . . . . . . . . . . . . . D.3.3 do {a c~ ao} while (condi c~ ao); . . . . . . . . . . . . . . . . . . D.3.4 break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

18 D.3.5 continue . . . . . . . . . . . . D.4 Senten cas para estruturas de controle . D.5 Resumo do cap tulo . . . . . . . . . . D.6 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

SUMARIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 674 675 675 676 677 677 678 679 680 681 682 682 685 685 686 687 688 688 691 692 693 694 695 695 697 697 697 698 699 699 700 700 701 701 704 705 705 707 707 707 708 708 713 713 715 Andr e Duarte Bueno

E Fun co es - Uso Avan cado E.1 A fun ca o main() e a entrada na linha de comando E.2 Processando par ametros de main() com getopt() E.3 Fun co es recursivas . . . . . . . . . . . . . . . . . . E.4 Uso de elipse ... em fun co es . . . . . . . . . . . . E.5 Senten cas para fun co es . . . . . . . . . . . . . . . . E.6 Resumo do cap tulo . . . . . . . . . . . . . . . . . E.7 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . F Ponteiros - Uso Avan cado F.1 Opera co es com ponteiros (+/-) . . F.2 Ponteiro void* . . . . . . . . . . . F.3 Ponteiro para ponteiro . . . . . . . F.4 Convers ao de ponteiros . . . . . . . F.5 Utilizando auto_ptr . . . . . . . . F.6 Ponteiro de fun ca o . . . . . . . . . F.7 Ponteiros para m etodos e atributos F.8 Ponteiros em hierarquias . . . . . . F.9 Senten cas para ponteiros . . . . . . F.10 Resumo do cap tulo . . . . . . . . F.11 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . da classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

G Estruturas, Uni oes, e Enumera co es G.1 Estruturas - struct . . . . . . . . . . . . . . . . . . G.1.1 Prot otipo para declarar e denir estruturas . G.1.2 Estruturas e fun co es . . . . . . . . . . . . . . G.1.3 Estruturas aninhadas . . . . . . . . . . . . . G.1.4 Senten cas para estruturas . . . . . . . . . . . G.2 Uni oes - union . . . . . . . . . . . . . . . . . . . . . G.2.1 Prot otipo para declarar e denir uni oes . . . G.3 Enumera co es - enum . . . . . . . . . . . . . . . . . . G.3.1 Prot otipo para declarar e denir enumera co es G.3.2 Senten cas para enumera co es . . . . . . . . . . G.4 Resumo do cap tulo . . . . . . . . . . . . . . . . . . G.5 Exerc cios . . . . . . . . . . . . . . . . . . . . . . . . H Vetores e Matrizes - Arrays H.1 Introdu ca o aos vetores e matrizes de C . . H.2 Como criar e usar vetores unidimensionais H.3 Como criar e usar matrizes bidimensionais H.4 Exemplo de uso de vetores e matrizes . . H.5 Resumo do cap tulo . . . . . . . . . . . . H.6 Exerc cios . . . . . . . . . . . . . . . . . . I Gloss ario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Novatec - Programa ca o Orientada a Objeto com C++

SUMARIO J Links Para Sites em C++ J.1 Bookmark . . . . . . . . . . . . . . . . . . . . . . . J.2 HOWTO - Como fazer . . . . . . . . . . . . . . . . J.3 Sites UML . . . . . . . . . . . . . . . . . . . . . . J.4 Sites C++ . . . . . . . . . . . . . . . . . . . . . . J.4.1 Ambientes de desenvolvimento . . . . . . . J.4.2 Compiladores . . . . . . . . . . . . . . . . . J.4.3 Exemplos . . . . . . . . . . . . . . . . . . . J.4.4 Tutoriais . . . . . . . . . . . . . . . . . . . J.4.5 FAQ . . . . . . . . . . . . . . . . . . . . . . J.4.6 Usu arios avan cados de C++ . . . . . . . . J.5 Sites STL - Standart Template Library . . . . . . . J.6 Sites Programa ca o multiplataforma (GNU/Linux) J.6.1 Software Livre . . . . . . . . . . . . . . . . J.6.2 Portabilidade . . . . . . . . . . . . . . . . . J.6.3 Software multiplataforma . . . . . . . . . . J.6.4 Auditoria e proler . . . . . . . . . . . . . . J.6.5 CVS . . . . . . . . . . . . . . . . . . . . . . J.6.6 Documenta ca o . . . . . . . . . . . . . . . . J.7 Sites Cluster e Programa ca o Paralela . . . . . . . J.8 Sites Bibliotecas . . . . . . . . . . . . . . . . . . . J.8.1 Bibliotecas e ferramentas . . . . . . . . . . J.8.2 Programa ca o cient ca . . . . . . . . . . . . J.9 Sites Grupos . . . . . . . . . . . . . . . . . . . . . J.10 Sites Revistas . . . . . . . . . . . . . . . . . . . . . J.11 Livros de C++ . . . . . . . . . . . . . . . . . . . . J.12 Fedora . . . . . . . . . . . . . . . . . . . . . . . . . K Arquivos de Cabe calho K.1 Introdu ca o aos arquivos de cabe calho . . . . . K.2 Entrada e sa da (streams) . . . . . . . . . . . K.3 Strings de C++ . . . . . . . . . . . . . . . . . K.4 STL . . . . . . . . . . . . . . . . . . . . . . . K.4.1 Containers da STL . . . . . . . . . . . K.4.2 Objetos fun co es e algoritmos gen ericos K.4.3 Matem aticos, num ericos . . . . . . . . K.5 Tratamento de erro, exce co es . . . . . . . . . K.6 Utilit arios . . . . . . . . . . . . . . . . . . . . K.7 Bibliotecas de C . . . . . . . . . . . . . . . . K.7.1 <cstdlib> . . . . . . . . . . . . . . . K.7.2 <cstdio> . . . . . . . . . . . . . . . . K.7.3 <ctime> . . . . . . . . . . . . . . . . K.7.4 <cstring> . . . . . . . . . . . . . . . K.7.5 Diversos . . . . . . . . . . . . . . . . K.8 Unix, GNU/Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

19 727 727 727 728 729 729 729 730 730 730 730 731 731 731 732 732 732 733 733 733 734 734 735 735 736 736 736 737 737 737 738 738 738 739 739 739 739 739 740 741 742 742 743 744

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

L Licen ca P ublica Geral GNU 745 L.1 Introdu ca o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745 L.2 Licen ca p ublica geral GNU condi co es para c opia, distribui ca o e modica ca o . . . 746 L.3 Como aplicar estes termos aos seus novos programas . . . . . . . . . . . . . . . . 750 Novatec - Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

20

SUMARIO

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Lista de Figuras
1 1.1 1.2 1.3 3.1 3.2 3.3 3.4 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.1 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 6.10 6.11 6.12 6.13 6.14 6.15 6.16 Por onde come car? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Em (a) programa de reconstru ca o tridimensional, em (b) o programa Octave. . . 56 Programa com interface em modo texto e mecanismos de recupera ca o. . . . . . . 57 Programas com interface gr aca. . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 O processo de abstra ca o. . . O que voc e v e? . . . . . . . Um rel oogio e um cachorro. Uma hierarquia de rel ogios. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 71 72 75 83 87 88 89 89 94 95 95 96

Modelos da realidade a planta de uma casa. . . . . . . . . . . . . . . . . . . . . Relacionamento dos diagramas estruturais da UML. . . . . . . . . . . . . . . . . Relacionamento dos diagramas din amicos da UML. . . . . . . . . . . . . . . . . . Elementos da UML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Outros elementos da UML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . O programa dia manipulando uma estrutura UML com representa co es de classes. A tela do programa Umbrello: Um diagrama de componentes. . . . . . . . . . . . A tela do programa umbrello um diagrama de classes. . . . . . . . . . . . . . . A tela do programa Visual-Paradigm um diagrama de caso de uso. . . . . . . .

Etapas de desenvolvimento de um software e os documentos gerados. . . . . . . . 107 Diagrama de caso de uso um caso de uso geral. . . . . . . . . . . . . Diagrama de caso de uso calcular area fun ca o. . . . . . . . . . . . . Diagrama de caso de uso: analisar resultados (uso de generaliza ca o). . Diagrama de caso de uso Analisar v arias fun co es (uso de inclus ao). . Diagrama de caso de uso entrada de dados errada (uso de extens ao). Elabora ca o e an alise de dom nio (adaptado de [Pressman, 2002]). . . . Interface gr aca e eventos. . . . . . . . . . . . . . . . . . . . . . . . . . Diagrama de classes representando classes. . . . . . . . . . . . . . . . Diagrama de classes representando associa co es. . . . . . . . . . . . . Diagrama de classes representando classes de associa ca o. . . . . . . . Diagrama de classes representando agrega co es. . . . . . . . . . . . . Diagrama de classes representando heran cas. . . . . . . . . . . . . . Classe de interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diagrama de objetos representando objetos e inst ancias. . . . . . . . Diagrama de seq u encia elementos. . . . . . . . . . . . . . . . . . . . Diagrama de seq u encia montando uma prova. . . . . . . . . . . . . . 21 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 112 113 113 114 116 118 122 124 126 127 128 129 131 135 136

22 6.17 6.18 6.19 6.20 6.21 6.22 6.23 6.24 6.25 6.26 6.27 6.28 6.29 6.30 6.31 6.32 6.33 7.1 8.1 8.2 9.1

LISTA DE FIGURAS Diagrama de seq u encia seq u encia para c alculo da area de uma fun ca o. . . . . Diagrama de comunica ca o montando uma prova. . . . . . . . . . . . . . . . . Diagrama de comunica ca o seq u encia para c alculo da area de uma fun ca o. . . Diagrama de m aquina de estado um aluno. . . . . . . . . . . . . . . . . . . . Diagrama de m aquina de estado estados do objeto simulador. . . . . . . . . . Diagrama de m aquina de estado: Estados compostos do objeto simulador. . . . Diagrama de m aquina de estado estados concorrentes do objeto simulador. . Em (a) o prot otipo de um diagrama de atividades. Em (b) o diagrama de atividades de um m etodo de binariza ca o. . . . . . . . . . . . . . . . . . . . . . . . . Diagrama de atividades m etodo do Trap ezio para c alculo da area. . . . . . . Diagrama de atividades uso de raios de nata ca o. . . . . . . . . . . . . . . . . A tela do programa Dev C++. . . . . . . . . . . . . . . . . . . . . . . . . . . . A tela do programa kdevelop. . . . . . . . . . . . . . . . . . . . . . . . . . . . . A tela do programa qt-designer. . . . . . . . . . . . . . . . . . . . . . . . . . . . Diagrama de componentes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Diagrama de implanta ca o. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Cart oes CRC: cClasse, responsabilidade, colabora ca o. . . . . . . . . . . . . . Exerc cio modelagem sistema aeroporto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 137 138 140 140 140 141 144 145 145 154 155 156 159 160 172 179

Seq u encia de montagem de um programa. . . . . . . . . . . . . . . . . . . . . . . 188 Diagrama mostrando entrada e sa da de dados em C++. . . . . . . . . . . . . . . 203 Compilando e executando programas no shell. . . . . . . . . . . . . . . . . . . . . 205 Tipos predenidos de C++ e suas dimens oes (32 bits). . . . . . . . . . . . . . . . 218

12.1 Como cam os objetos do tipo CTeste e CEndereco na mem oria. . . . . . . . . . 263 12.2 Como cam os objetos na mem oria quando a classe tem atributos est aticos. . . . 265 13.1 A classe CPessoa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 13.2 Como cam os m etodos inline. . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 13.3 A classe CPonto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 15.1 15.2 15.3 15.4 Ilustra ca o da cria ca o e uso de ponteiros. . . . . . . . Como declarar e usar um ponteiro. . . . . . . . . . . Consumo real de mem oria de um vetor de inteiros. . Desperd cio de mem oria em fun ca o do alinhamento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 301 309 310

16.1 Por que devemos criar um construtor de c opia. . . . . . . . . . . . . . . . . . . . 323 17.1 Heran ca simples: CPonto e CCirculo. . . . . . . . . . . . . . . . . . . . . . . . . 338 18.1 18.2 18.3 18.4 18.5 18.6 18.7 18.8 18.9 Heran ca m ultipla. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 Como cam os objetos b1, b2 e d em uma heran ca m ultipla. . . . . . . . . . . . . 348 Heran ca m ultipla com classe base comum. . . . . . . . . . . . . . . . . . . . . . . 350 Como cam os objetos b0, b1, b2 e d em uma heran ca m ultipla com base comum.351 Seq u encia de constru ca o e destrui ca o dos objetos em uma heran ca. . . . . . . . . 351 Heran ca m ultipla virtual. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 Como cam os objetos b0, b1, B2 e d em uma heran ca m ultipla com base virtual.353 Heran ca m ultipla normal e virtual. . . . . . . . . . . . . . . . . . . . . . . . . . 354 Hierarquia de classes CPonto, CCirculo, CElipse, CCirculoElipse. . . . . . . . . 357 Andr e Duarte Bueno

Novatec - Programa ca o Orientada a Objeto com C++

Lista de Figuras

23

19.1 Ilustra ca o do funcionamento da liga ca o din amica. . . . . . . . . . . . . . . . . . . 366 19.2 Hierarquia CPessoa, CAluno, CFuncionario, CAlunoFuncionario. . . . . . . . . 371 22.1 Diagrama UML da biblioteca de manipula ca o de entrada e sa da. . . . . . . . . . 406 23.1 Sa da gerada pelo programa gnuplot. . . . . . . . . . . . . . . . . . . . . . . . . . 445 26.1 Hierarquia de exce co es-padrao. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 26.2 Seq u encia de execu ca o sem exce ca o (a) e com exce ca o (b). . . . . . . . . . . . . . 480 30.1 Pequena hierarquia de m etodos num ericos (solver e integral num erica de fun co es do tipo polin omios). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 540 31.1 31.2 31.3 31.4 32.1 32.2 32.3 32.4 Diagrama UML da biblioteca padr ao de C++. . . . . . . . . . . . Containers seq uenciais - <vector>, <list>, <deque>. . . . . . . . Containers associativos - <set>, <multiset>, <map>, <multimap>. Exemplos de m etodos presentes em alguns containers. . . . . . . . M etodos M etodos M etodos M etodos disponibilizados para <vector>. que retornam iteradores. . . . . . disponibilizados para <list>. . . disponibilizados para <deque>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544 545 546 549 558 560 566 572

33.1 M etodos disponibilizados para <stack>. . . . . . . . . . . . . . . . . . . . . . . . 577 33.2 A classe <stack> funciona como uma interface de acesso a <deque>, <list> ou <vector>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 578 33.3 M etodos disponibilizados para <queue>. . . . . . . . . . . . . . . . . . . . . . . . 580 34.1 M etodos disponibilizados para <set>. . . . . . . . . . . . . . . . . . . . . . . . . 586 34.2 M etodos disponibilizados para <multiset>. . . . . . . . . . . . . . . . . . . . . . 588 34.3 M etodos disponibilizados para <map>. . . . . . . . . . . . . . . . . . . . . . . . . 589 H.1 As sa das do programa de binariza ca o. . . . . . . . . . . . . . . . . . . . . . . . . 714

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

24

Lista de Figuras

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Lista de Tabelas
6.1 7.1 7.2 8.1 8.2 8.3 9.1 Exemplo de caso de uso. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Diferen cas na nomenclatura da POO e de C++. . . . . . . . . . . . . . . . . . . 186 Extens oes usuais dos arquivos nas diferentes plataformas. . . . . . . . . . . . . . 188 Palavras chaves do ANSI C++. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Conven ca o para nomes de objetos. . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Exemplos de declara co es e deni co es. . . . . . . . . . . . . . . . . . . . . . . . . . 200 Tipos predenidos e intervalos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

17.1 Acesso herdado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340 19.1 M etodos com liga ca o est atica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 19.2 M etodos com liga ca o din amica . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 21.1 Operadores que podem ser sobrecarregados. . . . . . . . . . . . . . . . . . . . . . 388 22.1 22.2 22.3 22.4 Flags para o m etodo setf(). . . . . . . . . . . . . . Manipuladores da classe <iomanip>. . . . . . . . . . Caracteres de escape. . . . . . . . . . . . . . . . . . . Informa co es fornecidas pelo m etodo locale.name(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407 412 414 425

23.1 Modos de abertura do m etodo open(). . . . . . . . . . . . . . . . . . . . . . . . . 432 23.2 Modos de prote ca o do m etodo open() (atributos de arquivo). . . . . . . . . . . . 432 23.3 Manipuladores seekdir para os m etodos seekp() e seekg(). . . . . . . . . . . . . 433 31.1 M etodos e operadores comuns a todos os containers. . . . . . . . . . . . . . . . . 548 31.2 Iteradores e m etodos dos containers sequenciais. . . . . . . . . . . . . . . . . . . 550 31.3 Typedefs comuns aos diversos containers. . . . . . . . . . . . . . . . . . . . . . . 551 C.1 Preced encia dos operadores. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 658

F.1 Convers ao de ponteiros. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688

25

26

Lista de Programas

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Listings
1 Exemplo de uma listagem (Listing). . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap00/List1ExemploDeListing.out . . . . . . . . . . . . . . . . . . . 7.1 Exemplo b asico: Arquivo de cabe calho da classe. . . . . . . . . . . . . . . . . . 7.2 Exemplo b asico: Arquivo de implementa ca o da classe. . . . . . . . . . . . . . . 7.3 Exemplo b asico: Arquivo de implementa ca o da fun ca o main(). . . . . . . . . . ../listagens/Cap07/Programa.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1 Usando sa da para tela, nova linha, tabula ca o e beep. . . . . . . . . . . . . . . . ../listagens/Cap08/novaLinhatabbeep.out . . . . . . . . . . . . . . . . . . . . . . 8.2 Declara ca o de objetos e uso de cin e cout. . . . . . . . . . . . . . . . . . . . . 8.3 Usando diretrizes de pr e-processador: #ifdef. . . . . . . . . . . . . . . . . . . . ../listagens/Cap08/UsandoDiretrizesDePreProcessadorifdef.out . . . . . . . . . . 8.4 Usando for. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap08/UsandoFor.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5 Usando for encadeado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap08/UsandoForFor.out . . . . . . . . . . . . . . . . . . . . . . . . . . 8.6 Usando while: Calculando a pot encia. . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap08/UsandoWhile.out . . . . . . . . . . . . . . . . . . . . . . . . . . 8.7 Usando os operadores de compara ca o, incremento, decremento, e os operadores compostos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap08/UsandoOperadoresDeComparacao.out . . . . . . . . . . . . . . . 8.8 Fun ca o cubo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap08/funcao.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.9 Fun ca o com void. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap08/funcaoretornovoid.out . . . . . . . . . . . . . . . . . . . . . . 8.10 Fun ca o em linha: volume esfera. . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap08/funcaoparametroconst.out . . . . . . . . . . . . . . . . . . . . 8.11 Exemplo de uso da biblioteca <cstdlib>. . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap08/funcaorandomico.out . . . . . . . . . . . . . . . . . . . . . . . . 9.1 Usando os tipos pr e-denidos de C++. . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap09/UsandoOsTiposPreDenidos.out . . . . . . . . . . . . . . . . . 9.2 Diferen cas no uso de inteiro com sinal (signed) e sem sinal (unsigned). . . . . ../listagens/Cap09/signedunsigned.out . . . . . . . . . . . . . . . . . . . . . . . . . 9.3 Vericando os limites dos tipos pr e-denidos de C++. . . . . . . . . . . . . . . ../listagens/Cap09/LimitesDosTiposPreDenidos32.out . . . . . . . . . . . . . . 9.4 Usando struct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap09/Struct.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.5 Usando union. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap09/Union.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 45 190 191 192 192 202 203 204 206 206 207 207 207 207 208 208 209 210 210 211 211 211 212 212 212 213 218 219 220 221 222 222 226 227 228 228

28

Lista de Programas 9.6 Exemplo preliminar de deni ca o de classe do usu ario. . . . . . . . . . . . . . . . 229 ../listagens/Cap09/Complex.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 9.7 Exemplo preliminar de uso da classe <string> de C++. . . . . . . . . . . . . . . 232 ../listagens/Cap09/String.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 9.8 Exemplo preliminar de uso da classe <vector> da biblioteca STL. . . . . . . . . 234 ../listagens/Cap09/vector1.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 9.9 Usando sizeof(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 ../listagens/Cap09/sizeof.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 9.10 Usando typeid(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 ../listagens/Cap09/typeid.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 10.1 Denindo e usando um namespace. . . . . . . . . . . . . . . . . . . . . . . . . . . 245 ../listagens/Cap10/namespace.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 10.2 Usando using para colocar fun co es no mesmo escopo. . . . . . . . . . . . . . . . 246 ../listagens/Cap10/using.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 10.3 Usando vari aveis est aticas em um namespace. . . . . . . . . . . . . . . . . . . . . 248 ../listagens/Cap10/namespaceestatic.out . . . . . . . . . . . . . . . . . . . . . . . . 249 12.1 Usando atributos de objeto em uma classe. . . . . . . . . . . . . . . . . . . . . . 262 ../listagens/Cap12/UsandoAtributosDeObjeto.out . . . . . . . . . . . . . . . . . . . . 263 13.1 Passando par ametros por valor, refer encia e ponteiro. . . . . . . . . . . . . . . . . 276 ../listagens/Cap13/PassandoParametrosPorValorReferenciaPonteiro.out . . . . . . . 277 13.2 Classe com atributo e m etodo normal. . . . . . . . . . . . . . . . . . . . . . . . . 279 ../listagens/Cap13/classatributometodonormal.out . . . . . . . . . . . . . . . . . 280 13.3 Classe com m etodo const. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 ../listagens/Cap13/classatributometodoconst.out . . . . . . . . . . . . . . . . . . 283 13.4 Classe com atributo e m etodo est atico. . . . . . . . . . . . . . . . . . . . . . . . . 284 ../listagens/Cap13/classatributometodostatic.out . . . . . . . . . . . . . . . . . . 286 13.5 A classe CPonto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 13.6 Implementa ca o da classe CPonto. . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 13.7 Usando m etodos e atributos de uma classe. . . . . . . . . . . . . . . . . . . . . . 289 ../listagens/Cap13/ProgCPonto.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 15.1 Usando ponteiros para criar e usar objetos din amicos. . . . . . . . . . . . . . . . 303 ../listagens/Cap15/ProgCPontoDinamico.out . . . . . . . . . . . . . . . . . . . . . . 303 15.2 Usando refer encias. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 ../listagens/Cap15/referencia.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 15.3 Entendendo o alinhamento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308 ../listagens/Cap15/sizeofealinhamento.out . . . . . . . . . . . . . . . . . . . . . . . 309 16.1 Usando construtor default e de c opia. . . . . . . . . . . . . . . . . . . . . . . . . 320 ../listagens/Cap16/classconstrutorcopia.out . . . . . . . . . . . . . . . . . . . . . . 322 16.2 Problemas com a falta do construtor de c opia em objetos com atributos din amicos.324 ../listagens/Cap16/ObjDinamico.out . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 16.3 Ordem de constru ca o dos atributos de um objeto. . . . . . . . . . . . . . . . . . . 327 ../listagens/Cap16/OrdemConstrucao.out . . . . . . . . . . . . . . . . . . . . . . . . 327 16.4 Objetos est aticos globais. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 ../listagens/Cap16/ObjEstatico.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 16.5 Erro ao denir o construtor default e um construtor sobrecarregado com inicializadores. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 ../listagens/Cap16/construtorambiguidade.out . . . . . . . . . . . . . . . . . . . . . 329 16.6 Construindo objetos ou declarando fun co es? . . . . . . . . . . . . . . . . . . . . . 330 ../listagens/Cap16/DeclaracaoEConstrucaoAmbiguidade.out . . . . . . . . . . . . . 331

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Lista de Programas 16.7 Construtor e interface: erro na passagem de par ametros. . . . . . . . 16.8 Construtor e interface: erro na passagem de par ametros corrigidos. . 17.1 A classe CCirculo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17.2 Implementa ca o da classe CCirculo. . . . . . . . . . . . . . . . . . . . 17.3 Usando especicador de acesso e de heran ca. . . . . . . . . . . . . . ../listagens/Cap17/especicadorheranca.out . . . . . . . . . . . . . . . . 17.4 Usando using em heran cas. . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap17/UsandoUsingEmHerancas.out . . . . . . . . . . . . . 17.5 Redeclara ca o de m etodo ou atributo na classe-derivada. . . . . . . . ../listagens/Cap17/herancaERedeclaracao.out . . . . . . . . . . . . . . . 18.1 Seq u encia de constru ca o e destrui ca o em heran ca m ultipla virtual. ../listagens/Cap18/herancaMultiplaVirtual.out . . . . . . . . . . . . . . 18.2 A classe CElipse. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18.3 Implementa ca o da classe CElipse. . . . . . . . . . . . . . . . . . . . 18.4 Usando as classes CPonto, CCirculo e CElipse. . . . . . . . . . . . . ../listagens/Cap18/UsandoCPontoCCirculoCElipse.out . . . . . . . . . . 18.5 A classe CCirculoElipse. . . . . . . . . . . . . . . . . . . . . . . . . 18.6 Implementa ca o da classe CCirculoElipse. . . . . . . . . . . . . . . . ../listagens/Cap18/CCirculoElipse.out . . . . . . . . . . . . . . . . . . . 19.1 Exemplo de uso do polimorsmo. . . . . . . . . . . . . . . . . . . . . ../listagens/Cap19/Polimorsmo.out . . . . . . . . . . . . . . . . . . . . 19.2 A classe CPessoa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19.3 Implementa ca o da classe CPessoa. . . . . . . . . . . . . . . . . . . . 19.4 A classe CAluno. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19.5 Implementa ca o da classe CAluno. . . . . . . . . . . . . . . . . . . . . 19.6 A classe CFuncionario. . . . . . . . . . . . . . . . . . . . . . . . . . 19.7 Implementa ca o da classe CFuncionario. . . . . . . . . . . . . . . . . 19.8 A classe CAlunoFuncionario. . . . . . . . . . . . . . . . . . . . . . . 19.9 Implementa ca o da classe CAlunoFuncionario. . . . . . . . . . . . . 19.10Testando a heran ca m ultipla. . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap19/HerancaMultiplaa.out . . . . . . . . . . . . . . . . 20.1 Usando classes friend. . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap20/classesfriend.out . . . . . . . . . . . . . . . . . . . . 20.2 Usando m etodos friend. . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap20/metodofriend.out . . . . . . . . . . . . . . . . . . . . 20.3 Usando fun co es globais friend. . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap20/funcaoGlobalfriend.out . . . . . . . . . . . . . . . . 21.1 A classe CPonto com sobrecarga de operador. . . . . . . . . . . . . . 21.2 Implementa ca o da classe CPonto com sobrecarga de operador. . . . . 21.3 Usando a sobrecarga de operador. . . . . . . . . . . . . . . . . . . . . ../listagens/Cap21/TesteCPontoComSobrecarga.out . . . . . . . . . . . . 21.4 Sobrecarregando new em uma classe. . . . . . . . . . . . . . . . . . . ../listagens/Cap21/sobrecarregandonew.out . . . . . . . . . . . . . . . . 22.1 Formata ca o b asica da sa da de dados. . . . . . . . . . . . . . . . . . ../listagens/Cap22/FormatacaoBasicaDaSaidaDeDados.out . . . . . . . . 22.2 Formata ca o da sa da de dados usando o m etodo setf(). . . . . . . . ../listagens/Cap22/Usandosetf.out . . . . . . . . . . . . . . . . . . . . . 22.3 Formata ca o da sa da de dados usando a classe <iomanip>. . . . . . . ../listagens/Cap22/Usandoiomanip.out . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29 331 331 338 339 340 341 341 342 343 344 354 355 357 358 358 359 359 360 360 368 368 371 371 372 373 374 374 375 375 376 377 383 383 384 384 384 385 391 392 394 395 397 398 408 409 410 411 412 413

Andr e Duarte Bueno

30

Lista de Programas 22.4 Contando n umero de linhas, palavras e caracteres. . . . . . . . . . . . . . . . . ../listagens/Cap22/ContandoNumeroLinhasPalavrasCaracteres.out . . . . . . . . . 22.5 Controle de entrada. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap22/controleEntrada.out . . . . . . . . . . . . . . . . . . . . . . . . . 22.6 Usando sstream (ostringstream e istringstream). . . . . . . . . . . . . . . . ../listagens/Cap22/Usandosstrean.out . . . . . . . . . . . . . . . . . . . . . . . . . 22.7 Usando a classe locale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap22/UsandoLocale.out . . . . . . . . . . . . . . . . . . . . . . . . . . 22.8 Usando facets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap22/UsandoFacets.out . . . . . . . . . . . . . . . . . . . . . . . . . . 23.1 Uso de stream de disco (ifstream e ofstream). . . . . . . . . . . . . . . . . . ../listagens/Cap23/Usandofstream.out . . . . . . . . . . . . . . . . . . . . . . . . . 23.2 Lendo um arquivo com dados e coment arios. . . . . . . . . . . . . . . . . . . . ../listagens/Cap23/Usandofstreamcomcomentario.out . . . . . . . . . . . . . . . 23.3 Leitura e grava ca o de objetos simples usando read() e write(). . . . . . . . . ../listagens/Cap23/LeituraGravacaoDeObjetos.out . . . . . . . . . . . . . . . . . . 23.4 Usando redirecionamento de arquivo. . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap23/UsandoRedirecionamento.out . . . . . . . . . . . . . . . . . . . 23.5 Usando read(), write() e seekg(). . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap23/Usandoseekgseekp.out . . . . . . . . . . . . . . . . . . . . . . 23.6 Executando e enviando comandos para um outro programa (com <opstream>). ../listagens/Cap23/Usandopstream.out . . . . . . . . . . . . . . . . . . . . . . . . 24.1 Usando a classe <string> de C++. . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap24/Usandostring.out . . . . . . . . . . . . . . . . . . . . . . . . . . 24.2 Usando os m etodos de pesquisa da classe string de C++. . . . . . . . . . . . . ../listagens/Cap24/Usandostringpesquisa.out . . . . . . . . . . . . . . . . . . . . 24.3 Usando as classes <string> e sstream para executar comandos do shell. . . . . ../listagens/Cap24/interfaceShell.out . . . . . . . . . . . . . . . . . . . . . . . . . . 25.1 Mostrando a necessidade de convers oes. . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap25/necessidadeConversao.out . . . . . . . . . . . . . . . . . . . . . 25.2 Usando construtor com explicit. . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap25/Usandoexplicit.out . . . . . . . . . . . . . . . . . . . . . . . . . 25.3 Usando dynamic_cast e typeid. . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap25/Usandodynamiccast.out . . . . . . . . . . . . . . . . . . . . . 26.1 Exce co es: Divis ao por zero. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap26/DivisaoPorZero.out . . . . . . . . . . . . . . . . . . . . . . . . . 26.2 Exce co es: Divis ao por zero com controle simples. . . . . . . . . . . . . . . . . . ../listagens/Cap26/DivisaoPorZeroComControleSimples.out . . . . . . . . . . . . . 26.3 Exce co es: Divis ao por zero com exce co es. . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap26/DivisaoPorZeroComExcecoes.out . . . . . . . . . . . . . . . . . 26.4 Exce co es e desempilhamento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap26/ExcecoesDesempilhamento.out . . . . . . . . . . . . . . . . . . 26.5 Usando set_unexpected() e set_terminate(). . . . . . . . . . . . . . . . . . ../listagens/Cap26/TesteListaExcecoes.out . . . . . . . . . . . . . . . . . . . . . . . 26.6 Exce ca o para new. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap26/Excecoesnew.out . . . . . . . . . . . . . . . . . . . . . . . . . . 26.7 Usando exce co es para controle de entrada e sa da. . . . . . . . . . . . . . . . . ../listagens/Cap26/ExcecoesControleEntradaSaida.out . . . . . . . . . . . . . . . . 27.1 Deni ca o de classe template com argumentos pr e-denidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419 420 420 421 423 423 425 426 427 427 434 435 435 436 437 438 440 441 442 443 445 446 455 457 457 458 458 459 462 463 465 465 467 468 473 473 474 474 475 476 481 481 482 483 483 484 484 485 500

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Lista de Programas 27.2 Deni ca o dos m etodos da classe template com argumentos pr e-denidos. 27.3 Usando a classe template com argumentos pr e-denidos. . . . . . . . . . ../listagens/Cap27/UsandoClasseTemplateComArgumentosPreDenidos.out 28.1 Exemplo de fun ca o expandida em tempo de compila ca o. . . . . . . . . . . ../listagens/Cap28/FuncaoExpandidaEmTempoDeCompilacao.out . . . . . . . 28.2 Fun ca o pot encia expandida em tempo de compila ca o. . . . . . . . . . . . ../listagens/Cap28/FuncaoExpandidaEmTempoDeCompilacaopotencia.out . 28.3 Exemplo de mapeamento de tipo com templates. . . . . . . . . . . . . . . ../listagens/Cap28/MapeamentoDeTipo.out . . . . . . . . . . . . . . . . . . . 28.4 Problema na chamada a m etodos template. . . . . . . . . . . . . . . . . . ../listagens/Cap28/ProblemaNaChamadaAMetodosTemplate.out . . . . . . . ../listagens/Cap28/TemplatesComErro.out . . . . . . . . . . . . . . . . . . . . 28.5 Deni ca o de classe template com template adicional. . . . . . . . . . . . 28.6 Implementa ca o dos m etodos da classe template com template adicional. 28.7 Uso de classe template com template adicional. . . . . . . . . . . . . . . ../listagens/Cap28/UsandoTemplateComTemplateAdicional.out . . . . . . . 28.8 Exemplo: Instanciando fun co es e classes template. . . . . . . . . . . . . . ../listagens/Cap27/InstanciandoFuncoesEClassesTemplate.out . . . . . . . . . 29.1 Associa ca o com atributo de liga ca o. . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap29/associacoes.out . . . . . . . . . . . . . . . . . . . . . . . . 30.1 Usando fun co es matem aticas de <cmath>. . . . . . . . . . . . . . . . . . . ../listagens/Cap30/Usandocmath.out . . . . . . . . . . . . . . . . . . . . . . 30.2 Usando <complex>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap30/UsandoComplex.out . . . . . . . . . . . . . . . . . . . . . . 30.3 A classe <complex> da biblioteca padr ao. . . . . . . . . . . . . . . . . . . 30.4 Exemplo descritivo da classe <bitset>. . . . . . . . . . . . . . . . . . . . ../listagens/Cap30/ExemploDescritivoDaClassebitset.out . . . . . . . . . . . . 30.5 Usando <bitset> com <vector>, criando uma matriz de bits. . . . . . . . ../listagens/Cap30/Usandobitsetvector.out . . . . . . . . . . . . . . . . . . . 31.1 Usando insert_iterator e fun ca o predicado. . . . . . . . . . . . . . . . . ../listagens/Cap31/insertIterator.out . . . . . . . . . . . . . . . . . . . . . . . 32.1 Usando <vector>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap32/Usandovector.out . . . . . . . . . . . . . . . . . . . . . . 32.2 Usando <list>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap32/Usandolist.out . . . . . . . . . . . . . . . . . . . . . . . . 32.3 Usando <list> com as fun co es gen ericas (algoritmos gen ericos). . . . . . ../listagens/Cap32/Usandolist2.out . . . . . . . . . . . . . . . . . . . . . . . 32.4 Usando <deque>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap32/Usandodeque.out . . . . . . . . . . . . . . . . . . . . . . . 33.1 A classe container <stack>. . . . . . . . . . . . . . . . . . . . . . . . . . . 33.2 Usando <stack>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap33/Usandostack.out . . . . . . . . . . . . . . . . . . . . . . . 33.3 A classe container <queue>. . . . . . . . . . . . . . . . . . . . . . . . . . . 33.4 Usando <queue>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap33/Usandoqueue.out . . . . . . . . . . . . . . . . . . . . . . . 34.1 Usando <set>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap34/Usandoset.out . . . . . . . . . . . . . . . . . . . . . . . . 34.2 Usando <map>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap34/Usandomap.out . . . . . . . . . . . . . . . . . . . . . . . Novatec - Programa ca o Orientada a Objeto com C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31 501 501 502 509 509 509 510 512 513 513 514 514 514 515 516 516 518 519 524 525 529 529 532 532 533 535 537 537 538 553 554 563 563 568 569 569 571 573 573 578 579 580 581 582 582 587 588 591 593

Andr e Duarte Bueno

32

Lista de Programas 35.1 Usando sort(), find(), find_if(), fill(). . . . . . . . . . . . . . . . . . . . ../listagens/Cap35/Usandosortndnd ifll.out . . . . . . . . . . . . . . . . . . 35.2 Usando sort() e copy() para ordenar linhas de texto. . . . . . . . . . . . . . . ../listagens/Cap35/ordenandoTexto.out . . . . . . . . . . . . . . . . . . . . . . . . . 35.3 Usando copy() para copiar dados de um arquivo de disco para um <vector>. . ../listagens/Cap35/dadosParaVector.out . . . . . . . . . . . . . . . . . . . . . . . . 35.4 Usando <vector> com algoritmos gen ericos: C alculo da mediana. . . . . . . . . ../listagens/Cap35/CalculoMediana.out . . . . . . . . . . . . . . . . . . . . . . . . . 35.5 Usando generator_n() para gerar uma s erie de dados. . . . . . . . . . . . . . ../listagens/Cap35/TCSeries.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36.1 Usando divides<>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap36/divides.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36.2 Usando multiplies<>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap36/multiplies.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36.3 Criando e usando uma classe fun ca o. . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/Cap36/CriandoEUsandoClassefuncao.out . . . . . . . . . . . . . . . . 36.4 Usando fun co es gen ericas e objetos da STL. . . . . . . . . . . . . . . . . . . . . A.1 Pr e-processamento: Usando #ifdef..else. . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceA/ifelse.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.2 Pr e-processamento: Usando #if..else. . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceA/ifelse3.out . . . . . . . . . . . . . . . . . . . . . . . . . . . A.3 Pr e-processamento: Usando macros pr e-denidas. . . . . . . . . . . . . . . . . . ../listagens/ApendiceA/Macros.out . . . . . . . . . . . . . . . . . . . . . . . . . . . B.1 Classe Autixliar Cteste. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.2 Fun ca o e escopo A. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.3 Fun ca o e escopo B. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceB/escopoa.out . . . . . . . . . . . . . . . . . . . . . . . . . . B.4 Usando modicadores de acesso. . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceB/const.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.1 Usando os operadores de compara ca o, incremento, decremento, e os operadores compostos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceC/comparacao.out . . . . . . . . . . . . . . . . . . . . . . . . C.2 Usando os operadores l ogicos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3 Usando os operadores de bits. . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceC/RepresentandoInteirosCombits.out . . . . . . . . . . . . . C.4 Usando operador de incremento. . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceC/incremento.out . . . . . . . . . . . . . . . . . . . . . . . . . C.5 Usando operador m odulo % e operador tern ario ? . . . . . . . . . . . . . . . . . ../listagens/ApendiceC/while3.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . D.1 Usando switch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceD/switch.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . D.2 Usando while. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceD/while2.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . D.3 Usando do..while. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceD/dowhile.out . . . . . . . . . . . . . . . . . . . . . . . . . . D.4 Usando break, continue, do..while, e switch. . . . . . . . . . . . . . . . . . ../listagens/ApendiceD/breakecontinue.out . . . . . . . . . . . . . . . . . . . . . E.1 Fun ca o main() e a entrada na linha de comando. . . . . . . . . . . . . . . . . . ../listagens/ApendiceE/entradalinhacomando.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607 608 609 609 610 610 610 611 611 612 617 617 617 617 618 619 620 642 642 642 643 644 644 650 650 651 651 652 652 659 660 661 661 662 662 663 664 664 670 670 672 673 673 673 674 675 677 678

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Lista de Programas E.2 Processando par ametros de main() com getopt(). . . . . . . . . . . . . . . . . ../listagens/ApendiceE/maingetopt.out . . . . . . . . . . . . . . . . . . . . . . . . E.3 Fun ca o recursiva: c alculo do fatorial. . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceE/funcaorecursiva.out . . . . . . . . . . . . . . . . . . . . . . E.4 Usando elipses (...) : fun ca o m edia. . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceE/UsoDeElipse.out . . . . . . . . . . . . . . . . . . . . . . . . F.1 Ponteiro de ponteiro. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceF/ponteirodeponteiro.out . . . . . . . . . . . . . . . . . . . F.2 Comparando o uso de vetores est aticos de C, din amicos de C++, com auto_ptr de C++ e <vector> da stl. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceF/autoptr.out . . . . . . . . . . . . . . . . . . . . . . . . . . F.3 Usando ponteiro de fun ca o. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceF/ponteiroDeFuncao.out . . . . . . . . . . . . . . . . . . . . . F.4 Ponteiro para m etodos da classe. . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceF/PonteiroParaMetodo.out . . . . . . . . . . . . . . . . . . . . F.5 Ponteiro em hierarquias e oset. . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceF/oset.out . . . . . . . . . . . . . . . . . . . . . . . . . . . . F.6 Usando operador de endere co (&) e sizeof(). . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceF/enderecosizeof.out . . . . . . . . . . . . . . . . . . . . . . . G.1 Usando estruturas aninhadas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceG/EstruturasAninhadas.out . . . . . . . . . . . . . . . . . . . G.2 Usando enumera co es: Um calend ario. . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceG/Enumeracoesdia.out . . . . . . . . . . . . . . . . . . . . . G.3 Usando enumera ca o anonima. . . . . . . . . . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceG/enumeracaoanonima.out . . . . . . . . . . . . . . . . . . . . ../listagens/ApendiceH/FormatosPBMPGM . . . . . . . . . . . . . . . . . . . . . H.1 Usando arrays: Um programa de binariza ca o. . . . . . . . . . . . . . . . . . . . Lista de programas . . . . . . . . . . . . . . . . . . . . . . . . . .

33 678 679 680 680 681 681 687 687 689 690 691 691 692 693 693 693 694 694 699 699 702 703 703 704 709 709

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

34

Pref acio

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Agradecimentos
Gostaria de agradecer aos amigos e companheiros que em algum momento e de alguma forma contribu ram para o desenvolvimento deste livro. Do LENEP - Laborat orio de Engenharia e Explora c ao de Petr oleo da UENF - Universidade Estadual do Norte Fluminense Darcy Ribeiro, Antonio A. G. Carrasquilla, Viatcheslav Priimenko (Slava), George Mitrofanov, Luiz O. E. dos Santos, Pavel Bedrikovetsky, Themis Carageorgos, Adolfo Puime, Severiano Ribeiro, Jorge Triguis, Marilia Barbosa, Victor Hugo, Eliane Souza, Roseane Miss agea, Geraldo Loures, S ergio Oliveira, Carlos Dias, Fernando Moraes, Bena Rodrigues, Alexandre Servulo, Luciano Botelho, Marcos Pinheiro, Pedro Mesquita, Cristofer, Debora Mendon ca, Eli ezer Freire, Sidna Abreu, Ana Pacheco, Kenedy Tavares, Verlaine Pereira, Remilson Rosa, e Marco Ceia. Da UFSC - Universidade Federal de Santa Catarina, Paulo C. Philippi, Roberto Lamberts, Jos e A. B. da Cunha Neto, Celso Fernandes, Saulo Guths, Vicente Nicolau, Amir de Oliveira, Fabiano Wolf, Lu s Hegele, Paulo Facin, Rodrigo Surmas, Carlos Ortiz, Carlos Paghi, Diego Silva, Geziel de Oliveira, Henrique de Gaspari, Jaison Meiss e Rodrigo Homann. Da PUC, Nathan Mendes, Luis Moura. Da UFRN, Adriano Santos, Aldomar Pedrini. Da UPFE, F abio Magnani. Da UEZO, Vania Estrela, Alfredo Boente, Rosana Pinheiro. Da ANP, S ergio Almeida (Biotita). Da ESSS, Marcos Damiani, Clovis Maliska. E os amigos extrangeiros, Jean F. Daian, Liang Zhirong. Aos alunos das disciplinas de Programa c ao Orientada a Objeto com C++, Programa c ao Pr atica, Software Livre e An alise de Imagens Aplicada, pelas constantes sugest oes apresentadas. Ao pessoal da Revista do Linux, que publicou no CD dessa publica c ao, edi c ao 33, a Apostila de Programa c ao Orientada a Objeto com C++, um embri ao da primeira edi c ao. Ao Rubens Prates, editor da Novatec, e sua equipe Marcelo Ferreira Paiva e Patrizia Zagni. Aos desenvolvedores do GNU/Linux a id eia do software livre . Ao GUFSC, o grupo de usu arios de software livre da UFSC. Em especial ao Ricardo, que me enviou uma lista de termos sobre software livre . Quero fazer um agradecimento especial a este pessoal maravilhoso que tive a oportunidade de conhecer em eventos como a Confer encia Internacional de Software Livre , o CONISLI, o LATINOWARE e em pequenos eventos de divulga c ao do software livre , e que tem defendido e lutado pelo software livre no Brasil: Cesar Brod, Rubens Queiros, Sulamita Garcia, Isabel Valverde, Timoty Ney, John Maddog Hall, Lucas Santos, Rafael Peregrino, S ergio Amadeo, Rog erio Santana, Julio Cezar Neves, Augusto Campos, Pablo DallOglio, Piter Punk, Walter Pinheiro, Djalma Valois. A PETROBRAS, Guilherme Castro, Farid S. Schecaira, Jos e Ten orio, pelo constante apoio as atividades de pesquisa desenvolvidas no setor de geo-inform atica do LENEP (LDSC). Nos u ltimos anos adquirimos dezenas de livros e equipamentos computacionais com recursos de projetos de pesquisa apoiados pela PETROBRAS, FAPERJ, FENORTE e CNPq. As pessoas que ajudaram na revis ao desta segunda edi c ao, Tiago Schaewer, Tiago Calimman, Irineu Silva, Allan Galante, Giovanni Colonese, Tiago Camara, Tayne Martins, Vitor Seraphim. Ao meu amigo de inf ancia, Luiz Alberto Alano. Aos meus sobrinhos e sobrinhas, Alessandra, Andr ea, Adroaldo, Alissa, Patricia, Angela, Isabel, Ana Paula, Gabriel, Beatriz, Manoela e Gustavo, que representam o futuro. Finalmente, gostaria de dedicar esta segunda edi c ao ` a minha esposa F atima e minhas lhas J ulia e Soa. No momento em que escrevo esta dedicat oria estou ausente. Pe co a J ulia e Soa desculpas pela minha aus encia, na sua inf ancia, quando fazia doutorado, e na sua adolesc encia, entre 13 e 16 anos quando fazia, nos ns de semana e a noite, esta segunda edi c ao.

35

36

Pref acio

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Pref acio da Segunda Edi c ao


S ao muitas e constantes as inova co es no mundo da inform atica, quando do lan camento da primeira edi ca o algumas tecnologias ainda estavam amadurecendo; como a UML, a STL, o cvs, a programa ca o com software livre. Atualmente a UML est a na sua vers ao 2, a STL e bastante conhecida e utilizada, o uso do cvs se consolidou e o desenvolvimento de software livre n ao para de crescer, se tornando pr atica usual. J a em nossa primeira edi ca o procuramos fazer um livro moderno, conceitos de C foram movidos para o m do livro, acrescentamos no co es gerais de UML e uma metodologia de desenvolvimento de software. Abordamos conceitos de programa ca o para software livre, STL e em de conceitos b asicos de o uso de ferramentas atuais como cvs, JAVA DOC e doxygen. Al programa ca o paralela. Recentemente, a Borland realizou um estudo completo sobre a rotina de um desenvolvedor, identicando aspectos positivos e negativos. Dentre os aspectos positivos destacou-se a necessidade de constante evolu ca o tecnol ogica, a capacidade criativa e a satisfa ca o do desenvolvedor ao produzir um produto de software que resolva os requisitos apresentados. Na lista de tens negativos est ao a falta de tempo para pesquisa, estudo e atualiza ca o de seus conhecimentos. Esta segunda edi ca o atende muitas destas solicita co es, pois traz para voc e, de uma forma resumida e did atica os u ltimos conceitos de POO com UML 2 e C++, as mais recentes bibliotecas, dicas e truques de C++. Esta segunda edi ca o tem como objetivos: Incluir diversas revis oes e corre co es. Descrever a UML 2 e um modelo de engenharia de software que inclui conceitos de UP e XP. Incluir inova co es de C++ (como as do TC1), da STL, de programa ca o com software livre e programa ca o paralela. Ser mais did atica, incluindo maior n umero de exemplos e exerc cios. Denir as disciplinas alvo. Atra r programadores de C, Fortran, Delphi, Java, e C#, em fun ca o do sucesso e da robustes de C++. Finalmente, gostariamos de dizer que nos u ltimos quatro anos, zemos uma pesquisa e sele ca o criteriosa do que h a de mais recente e u til para o desenvolvimento de software multiplataforma utilizando C++. 37

38

Pref acio

Revis oes e Inova c oes


Veja a seguir a lista de revis oes e inova co es desta segunda edi ca o. Todos os cap tulos foram revisados e atualizados em detalhe. Todas as listagens foram testadas em diferentes plataformas, incluindo 32 e 64 bits, utilizando a mais recente vers ao do compilador da GNU, o g++ vers ao 4.x. A parte I: foi inteiramente reorganizada e reescrita considerando UML 2.x. Os diagramas foram gerados usando os programas dia e umbrello. Diversos diagramas novos foram acrescentados. Incluimos novos exemplos e v arios exerc cios. A parte II: foi ampliada considerando as u ltimas inova co es de C++, o TC1 - Technicun Corrigendum 1, al em de dezenas de novos exemplos. A parte III: incluimos novos exemplos da STL e dicas avan cadas de STL. A parte IV: incluimos as u ltimas vers oes dos softwares da GNU (autoconf, automake e libtool ). Foram adicionadas descri co es de novos programas, incluindo oreport, calgrind, ddd, cervisia, subversion, cvs avan cado, ssh, entre outros. A parte V: foi reescrita e bastante ampliada, inclui diversos exemplos novos. A parte VI: e nova e cont em cap tulos sobre bibliotecas usuais como Magick++, Boost, Blitz++. Incluimos uma introdu ca o a programa ca o com interfaces gr acas usando a mais recente vers ao da biblioteca Qt, a Qt 4. A parte VII: foi totalmente revisada, novos exemplos, novos exerc cios, e novos links foram acrescentados.

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Pref acio da Primeira Edi c ao


A elabora ca o deste livro teve como princ pio a reuni ao dos conceitos de programa ca o orientada a objeto com C++ pelo pr oprio autor, uma esp ecie de resumo particular. O objetivo era organizar os conceitos de C++ e criar uma apostila de consulta r apida, em que a sintaxe de C++ fosse apresentada de forma suscinta e direta. Como o interesse pela programa ca o orientada a objeto cresceu substancialmente, diversos bolsistas, mestrandos e doutorandos do LMPT - Laborat orio de Meios Porosos e Propriedades Termof sicas, site em http://www.lmpt.ufsc.br, solicitaram-me a realiza ca o de cursos r apidos abordando C++. Durante a apresenta ca o desses cursos, foram identicadas as maiores diculdades dos alunos, o que levava a revis ao e amplia ca o da apostila. Com o passar dos anos, a linguagem C++ evoluiu e centenas de conceitos novos lhe foram ` medida que C++ adicionados (exce co es, templates, STL - Standard Template Library ). A evolu a, a apostila tamb em necessitava de modica co es. Em 1999 comecei a desenvolver um software utilizando as ferramentas de software livre da GNU, o que me levou a incluir descri co es dessas ferramentas na apostila. Em setembro de 2002, a vers ao 0.4 da Apostila de Programa ca o Orientada a Objeto com C++ foi distribu da no CD-ROM da Revista do Linux (edi ca o 33). Diversos leitores me enviaram sugest oes e me incentivaram a transformar a apostila em livro. Foi nesta ocasi ao que entrei em contato com a Editora Novatec. De setembro de 2002 a junho de 2003, z centenas de revis oes, corre co es e atualiza co es. A estrutura do livro foi reorganizada, o que torna mais f acil sua leitura. Diversos cap tulos foram totalmente reescritos e novos exemplos foram inclu dos. Todos os cap tulos de programa ca o multiplataforma com software livre foram ampliados e atualizados com as mais novas vers oes das ferramentas da GNU. Foi adicionada uma parte que aborda o uso de cluster de computadores e processamento paralelo (com exemplos). Um curso de C++ e longo, e a experi encia mostrou que inici a-lo com modelagem e depois abordar conceitos de C n ao funciona. Perde-se a rela ca o de objeto conceitual (modelagem) com objeto da linguagem C++. O curso torna-se confuso. Como o n umero de conceitos novos e grande, ao chegar ` a parte interessante de C++, polimorsmo e STL, o aluno j a n ao tinha mais capacidade de aprendizado. Por este motivo, todos os conceitos relativos ` a linguagem de programa ca o C foram inseridos nos ap endices. Procurei montar cada cap tulo de forma que cada um possa ser consultado para aprendizado dos conceitos de C++, bem como para relembrar o prot otipo e a sintaxe de C++. Normalmente a sintaxe e apresentada no in cio do cap tulo e inclui indicadores para as se co es onde s ao detalhados. Desta forma, o livro e tamb em uma boa refer encia de C++. Atualmente esta obra e utilizada como livro-texto da disciplina Programa ca o Orientada a Objeto com C++, ministrada no LENEP - Laborat orio de Engenharia e Explora ca o de Petr oleo da UENF - Universidade Estadual do Norte Fluminense Darcy Ribeiro.

39

40

Pref acio

Quem deve comprar este livro?


Segundo [Meyers, 2005], C++ e uma linguagem de programa ca o multiplataforma, e uma confedera ca o de linguagens, suportando programa ca o procedural, orientada a objeto, funcional, gen erica e t ecnicas de meta programa ca o. C++ suporta diferentes estilos de programa ca o, e, ao aprender C++ voc e estar a apto a trabalhar em um conjunto de empresas de software. O autor de C++, Bjarne Stroustrup, arma que e melhor come car a programar diretamente em C++ [Bjarne, 1999]. Ou seja, se voc e n ao sabe se deve come car a programar com C ou C++, siga a dica do autor da linguagem C++ e inicie diretamente com C++. Programadores de C e Fortran que desejam aprender a usar os conceitos de orienta ca o a objeto e tem curiosidade por C++. Programadores de Java que querem aprender conceitos avan cados, como sobrecarga de operador, heran ca-m ultipla, templates e STL. Se voc e quer aprender UML 2.x. Se voc e quer conhecer em detalhes a sintaxe de C++. Se voc e quer aprender a usar a STL, seus iteradores, containers e algoritmos gen ericos. Se voc e e novo no mundo do software livre, ou usu ario do GNU/Linux e tem interesse em fazer programas para esta plataforma. Se voc e tem interesse em aprender a desenvolver softwares multiplataforma. Isto e, softwares para Windows, GNU/Linux, Mac OS X, SUN Solaris, Unix, etc. Se voc e quer aprender os conceitos de programa ca o paralela usando m ultiplas-threads e m ultiplos-processos. Se voc e j a programa em C++ e quer atualizar seus conhecimentos. Se voc e quer fazer suas pr oprias bibliotecas. Se voc e quer aprender a usar novas bibliotecas, como Magick++, Common C++, Boost, Blitz++, Matpack, GSL e Qt 4. Enm, se voc e quer crescer, aprender conceitos e id eias novas.

Pr e-requisitos
A leitura do presente livro n ao requer nenhum pr e-requisito. Entretanto, para um melhor acompanhamento dos assuntos da Parte ?? - Programa ca o Multiplataforma com Software Livre, e aconselh avel um conhecimento pr evio de software livre e alguma experi encia com GNU/Linux. Voc e obt em material sobre software livre no s tio da Disciplina de Software Livre, veja tem disciplinas no endere co http://www.lenep.uenf.br/~bueno.

Site de aux lio a professores e alunos


Professores e alunos poder ao consultar o site das disciplinas, Programa ca o Orientada a Objeto com C++, Programa ca o Pr atica com C++ e Processamento Paralelo e Distribu do, dispon veis no endere co http://www.lenep.uenf.br/~bueno (selecione o tem disciplinas). Tamb em disponibilizamos um site para a disciplina Software Livre, o mesmo inclui conceitos relacionados ao uso de softwares livres, ferramentas e programas da GNU e do GNU/Linux. Novatec - Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

Pref acio

41

Alguns exemplos pr aticos de programas relacionados a area de an alise e processamento de imagens ser ao inclu dos no site da disciplina An alise e Processamento de Imagens.

Disciplinas Alvo
A nova estrutura do livro e mais did atica, foi montada de modo a fornecer a voc e um livro que possa ser utilizado como livro texto das seguintes disciplinas: Introdu ca o a Programa ca o Orientada a Objeto e UML. C++ e STL. Programa ca o Multiplataforma e Programa ca o com Software Livre (GNU/Linux). Introdu cao a Programa ca o Paralela e Distribu da. Cobre ainda o uso de algumas bibliotecas GPL e programa ca o gr aca com Qt 4. Did atica Este livro tem uma diferen ca did atica e conceitual muito clara em rela ca o a grande maioria dos livros programa ca o orientada a objeto e programa ca o em C++. Historicamente os livros de programa ca o usam uma abordagem estruturada - v cio dos velhos tempos. Os mesmos iniciam direta ou indiretamente com estruturas de controle, fun co es, arrays, vetores e ponteiros, ou seja, iniciam com os conceitos b asicos de linguagens estruturadas - como C e Fortran. Isto se explica em boa parte porque seus autores - pelo menos a maioria - come cou a desenvolver programas quando n ao existia programa ca o orientada a objeto. Outro problema comum na maioria dos livros de programa ca o e tratar o leitor como um quase idiota. Dezenas de livros repetem o mesmo conceito e as mesmas frases v arias vezes. O mesmo exemplo de c odigo e listado dezenas de vezes, e a cada nova apresenta ca o apenas pequenas inova co es s ao apresentadas. O livro ca enorme e com pouco conte udo. Misturam o desenvolvimento de um assunto com dezenas de dicas alheias ao conceito que esta sendo apresentado, distraindo o leitor. Alguns livros perdem muito tempo com os conceitos b asicos - f aceis de aprender. E dedicam pouco espa co para os conceitos mais dif ceis. O leitor tem a impress ao de que aprendeu o necess ario, quando ainda falta muito a aprender. Este livro e claramente diferente. O livro trabalha com conceitos de orienta ca o a objeto desde os primeiros cap tulos. De uma maneira geral cada cap tulo apresenta um conceito, abordando sua concep ca o te orica e pr atica, indo do mais f acil (usu arios iniciantes) ao mais dif cel (usu arios avan cados). Ou seja, voc e leitor e tratado com respeito e seriedade. Novatec - Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

42 Did atica e estilo de apresenta c ao

Sobre o livro

Quando poss vel, a apresenta ca o dos conceitos segue uma did atica pr e-denida. Por exemplo, na parte de UML os conceitos s ao apresentados na seguinte ordem: Conceito geral. Exemplo e ilustra ca o/gura. Como o conceito e aplicado em orienta ca o a objeto (formalismo). Descri ca o formal do conceito aplicado a orienta ca o a objeto. Exemplo e ilustra ca o/gura. Conceitos correlatos. Exemplo real. Exemplo e ilustra ca o/gura.

Sobre o livro
O livro est a dividido nas seguintes partes: Parte I - Filosoa e Modelagem Orientada a Objeto: Destina-se a transmitir os conceitos b asicos de POO - Programa ca o Orientada a Objeto, a id eia, a losoa e a nomenclatura utilizada. Veremos alguns exemplos de objetos, os mecanismos b asicos e os conceitos-chave da POO; a modelagem orientada a objeto utilizando a UML - Unied Modelling Language ; como montar os diagramas de uma AOO - An alise Orientada a Objeto, utilizando a UML. Apresenta as etapas de desenvolvimento de um programa: a concep ca o, a elabora ca o, a an alise orientada a objeto, o projeto do sistema, o projeto orientado a objeto, a implementa ca o e o teste; a manuten ca o e a documenta ca o. Parte II - POO Utilizando C++: Apresenta a sintaxe de C++. Tipos pr e-denidos de C++, tipos do usu ario e tipos da STL - Standard Template Library. Como declarar, denir e utilizar classes, objetos, atributos e m etodos. Como implementar a heran ca simples, a heran ca m ultipla, a utiliza ca o de polimorsmo, a sobrecarga de operadores, a convers ao de tipos, e os tipos gen ericos (templates). Apresenta a entrada e a sa da de dados com as classes <ios_base>, <istream>, <ostream> e <sstream>. Como realizar opera co es com arquivos de disco utilizando as classes <fstream>, <ofstream> e <ifstream>. Apresenta um grupo de classes-padr ao de C++. A classe de strings-padr ao de C++, a <string>, a classe para tratar n umeros complexos <complex> e a classe <bitset>. Parte III - Introdu c ao ` a STL: Apresenta a STL, uma biblioteca de objetos em C++. Descrevem-se os conceitos b asicos de containers e iteradores. Voc e aprender a a utilizar um <vector> para vetores, <list> para listas duplamente encadeadas, <queue> que representa uma la, <stack> que representa uma pilha (como em uma calculadora HP ), <deque> que e uma la com duas extremidades e classes containers para tratamento de conjunto de dados com chaves, <set>, <multi_set>, <map> e <multi_map>. O uso de algoritmos gen ericos e fun co es objeto. Novatec - Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

Sobre o livro

43

Parte IV: Programa c ao Multiplataforma com Software Livre : Uma introdu ca o aos comandos de shell do GNU/Linux, programas u teis como ftp, telnet, ssh. Descreve conceitos de programa ca o multiplataforma. Apresenta as ferramentas de programa ca o com software livre, cobrindo emacs, gcc /g++, make, automake, autoconf, libtool, gdb, oes com cvs, cervisia, ddd, documenta ca o com JAVA DOC e doxygen, controle de vers subversion, e programas como di, patch e indent. Parte V: Cluster de Computadores e Processamento Paralelo: Apresenta os conceitos e os diferentes tipos de clusters de computadores. Uma introdu ca o ao processamento paralelo. As diferentes formas de processamento paralelo incluindo: i) a utiliza ca o de m aquinas com mais de um processador (SMP); ii) a utiliza ca o de processamento distribu do em um cluster com OpenMosix, e as vantagens e desvantagens da utiliza ca o de bibliotecas, como PVM - Paralel Virtual Machine e MPI - Message Passing Interface. A programa ca o com m ultiplos-processos e com m ultiplas-threads e apresentada com exemplos pr aticos. Os resultados de tempo de processamento de um cluster real s ao apresentados. Parte VI: Bibliotecas: S ao apresentadas algumas bibliotecas GPL, como Magick++, Common C++, Boost, Blitz++, Matpack, GSL e Qt 4. Parte VII: Ap endices: Descreve conceitos gerais de programa ca o em C/C++, como: diretrizes de pr e-processador, classes de armazenamento e modicadores de acesso, operadores, estruturas de controle, fun co es, ponteiros, refer encias, estruturas, uni oes e enumerac o es. Nos ap endices s ao apresentados ainda um gloss ario de C++, arquivos de cabe calho e a licen ca geral da GNU, a GPL. imAo longo da apresenta ca o dos temas, s ao inclu dos exemplos de programas completos. E portante que voc e compile os programas e verique o seu funcionamento.

Como fazer download dos arquivos fonte


As listagens dos programas est ao dispon veis em: http://www.novateceditora.com.br/downloads.php http://www.lenep.uenf.br/~bueno/LivroCpp Usu arios do Windows devem baixar o arquivo com a extens ao .zip e usu arios do GNU/Linux, Mac OS X, Unix, o arquivo com a extens ao .tar.gz. Ap os fazer o download do arquivo com as listagens voc e deve descompactar os arquivos e a seguir ler o arquivo LEIAME.html (ou LEIAME.pdf). O mesmo cont em instru co es detalhadas para compila ca o e instala ca o dos exemplos do livro. Tamb em foi disponibilizado um arquivo ERRATA.html, que inclui uma lista de erros encontrados ap os a impress ao do livro.

Como compilar e testar os programas


Na Parte II do livro, iremos apresentar os primeiros programas em C++. Mas antes disto, na se ca o 6.6.6, veremos diversas IDEs - Interfaces de Desenvolvimento de Software em C++. De forma que o usu ario poder a selecionar o tipo de IDE que mais lhe agrada, tanto no Windows quanto no GNU/Linux. Novatec - Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

44

Como ler este livro

Dica: se voc e tem pressa em instalar uma IDE a dica e: usu arios do GNU/Linux devem instalar o pacote de desenvolvimento da GNU, o gcc/g++. Usu arios do Windows podem instalar o programa DevC++, dispon vel em http://www.bloodshed.net/dev/.

Como ler este livro


Para facilitar a leitura do livro, alguns t tulos t em um c odigo informando a prioridade deste. Este formato foi adotado para permitir a leitura do livro por programadores iniciantes, intermedi arios e avan cados. T tulo - Iniciante/B asico N vel b asico para iniciantes na programa ca o orientada a objeto com C++. Os t tulos de se ca o no formato Titulo2 e Titulo3 n ao devem ser lidos por iniciantes na programa ca o em C++. Os t tulos de n vel 2 e 3 podem incluir refer encias a conceitos que ainda n ao foram apresentados e s o devem ser lidos por quem tem experi encia em C++ ou em uma segunda leitura do livro. T tulo2 - Intermedi ario N vel intermedi ario. Leitura aconselhada para quem j a conhece C++ e quer se aperfei coar. T tulo3 - Avan cado N vel avan cado. Se voc e j a programa a algum tempo em C++ e quer aperfei coar seus conhecimentos, leia os t tulos de n vel 3, que abordam aspectos com os quais voc e ir a se deparar ap os ter feito alguns programas. Tamb em foram acrescentadas dicas gerais, dicas de desempenho e dicas para evitar erros (bugs ), utilizando a seguinte nota ca o: Dica: Ao longo dos cap tulos s ao apresentadas algumas dicas. O objetivo das dicas e ressaltar algum aspecto da linguagem C++ ou algum comando ou programa externo. Desempenho: S ao dicas de como aumentar o desempenho de seus programas. Bugs : Cuidados para evitar a presen ca de bugs em seus programas. Para que o aluno possa xar os conceitos, apresenta-se ao longo do texto prot otipos, exemplos e listagens de programas. Prot otipo: Dene a sintaxe de uso de determinado comando ou programa (aparece em it alico). Deni co es e descri co es de fun co es/m etodos/comandos aparecem como no exemplo abaixo: comando Explica a utilidade do comando/programa. Op ca o op ca o1 op ca o2 Exemplos: Novatec - Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno Descri ca o ...descri ca o... ...descri ca o...

Experi encia do autor Exemplos textuais podem ser apresentados como nesta frase. /* Os exemplos embutidos no texto tem a linha de comando em fonte fixa n~ ao s~ ao programas completos, s~ ao partes de programas. Apenas ilustram determinada caracter stica da linguagem e sua sintaxe. Os exemplos de c odigo fonte s~ ao apresentados em fonte fixa.*/ int x = 2;

45

Comandos embutidos no texto usam fonte normal, it alico e negrito, e a sa da aparece indentada, com fonte xa em it alico, como abaixo. libtool mode=compile g++ -c List-15-2-TCirculo.cpp mkdir .libs g++ -c List-15-2-TCirculo.cpp -fPIC -DPIC -o .libs/List-15-2-TCirculo.o g++ -c List-15-2-TCirculo.cpp -o List-15-2-TCirculo.o >/dev/null 2> &1

In umeras listagens de programas completos e testados foram inclu dos no livro. Cada programa e documentado, assim, o leitor entender a o signicado de cada linha. Veja a seguir, um exemplo de listagem que apresenta um programa funcional em C++, o tradicional Ol a Mundo. Logo a seguir apresenta-se a sa da. Listing 1: Exemplo de uma listagem (Listing).
/* * @ c o p y r i g h t ( C ) Andre Duarte Bueno # include < iostream > int main () { std :: cout << " Ol a mundo !\ n " ; return 0; } Ol a mundo ! @file List -1 - E x e m p l o D e L i s t i n g . cpp */

Senten cas: Senten cas s ao regras, exemplos e deni co es curtas e diretas. Se voc e encontrar termos desconhecidos d e uma olhada no gloss ario. 2 Senten ca de n vel 2 e recomentada para quem j a conhece C++ e quer se aperfei coar. 3 Senten ca de n vel 3 e recomendada para programadores avan cados. Algumas senten cas podem incluir extrato de c odigo, como abaixo. // Coment arios em C++ iniciam com //

Por onde come car?


A Figura 1 mostra um diagrama onde voc e pode identicar a melhor seq uencia de leitura deste livro. Novatec - Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

46

Experi encia do autor

<<C++>> Profissional <<C++>> Estudante

<<C++>>

Biblioteca STL
+28,29,30,31,32,33

Filosofia POO
+1,2

Bsico
+5,6,7,8,9,10,11,24,26 +A,C,D

Modelagem OO
<< C++>> +3,4

Intermedirio
<< C++>> +12,13,14,15,17,18,19,20,25 +B,E,G

Avanado
+16,20,21,22,23,27, +F

Classes
+2,3,4,9,10,11,12,14,19,21

debug
+41

Documentao
+44

Herana
+2,3,4,15,16,17

Associaes
+2,3,4,20

Controle Verses
+47

<<C++>> Profissional Multiplataforma

Ferramentas
+4,35,36,37,38,40,41,42,44,47

Multiplataforma
+4,34,45,46

Pr.Paralelo
+48,49,50,51

Portabilidade
+45,46

Figura 1: Por onde come car?

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Experi encia do autor

47

Experi encia do autor


Ao longo dos u ltimos anos, o autor trabalhou no desenvolvimento de diversos softwares, alguns destes softwares s ao apresentados no Cap tulo 1 - Introdu ca o ` a Programa ca o. Dica de estudo: Ap os terminar de ler cada cap tulo, fa ca uma breve revis ao dos conceitos apresentados. Dedique 5 minutos para dar uma folheada r apida no cap tulo que leu, revendo os principais conceitos. Quando chegar em casa, dedique de 30-50 minutos para rever o que foi visto em aula (ou o que foi lido), xando os conceitos.

Errata
Nos esfor camos ao m aximo para fornecer a voc e um livro de primeira qualidade. Entretanto, atividades de revis ao e testes, parecem nunca serem sucientes. Se encontrar erros, omiss oes, entre em contato com bueno@lenep.uenf.br. Antes entretanto, aconselha-se dar uma olhada na se ca o errata. http://www.lenep.uenf.br/~bueno/LivroCpp, veja arquivo Errata.html Errata.html.

Contatando o autor
Embora tenha sido realizado um esfor co enorme no sentido de se fazer um bom livro de programa ca o orientada a objeto com C++, a extens ao do livro e a sua abrang encia, tornam dif cel a sua manuten ca o (inclus ao de novos conceitos). Neste sentido, se voc e tiver dicas, sugest oes, e exemplos para melhoria deste livro, favor entrar em contato com:

Prof. Andr e Duarte Bueno. Software Enginering, Image Analysis and Processing Petroleum Engineering and Exploration Laboratory Science and Technology Center North Fluminense State University Rodovia Amaral Peixoto, km 163, Avenida Brenand S/N CEP 27925-310 - Imboassica - Maca e - RJ - Brasil e-mail: bueno@lenep.uenf.br http://www.lenep.uenf.br/~bueno Site do LENEP - Laborat orio de Engenharia e Explora ca o de Petr oleo http://www.lenep.uenf.br

Novatec - Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

48

LISTINGS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Parte I

Filosoa e Modelagem Orientada a Objeto

49

Cap tulo 1

Introdu c ao ` a Programa c ao
Neste primeiro cap tulo apresentaremos o conceito de software (se ca o 1.1), o que e um programa, um software (se ca o 1.1.1), as diferen cas entre o software livre e o software propriet ario (se ca o 1.2). Al em disso, apresentaremos diferentes tipos de interface dos programas (se ca o 1.3), kernel num erico (se ca o 1.3.1), linha de comando (se ca o 1.3.2), modo texto (se ca o 1.3.3) e gr aca (se ca o 1.3.4). Discutiremos tamb em qual tipo de software voc e deve desenvolver (se ca o 1.4). Finalizaremos o cap tulo com um resumo e alguns exerc cios.

1.1

Programas e softwares

O objetivo de um programa de computador e facilitar a vida do usu ario, aumentar sua produtividade, principalmente para a realiza ca o de tarefas repetitivas e tamb em para possibilitar uma comunica ca o e intera ca o com o mundo de forma mais efetiva, r apida e globalizada. J a e poss vel a um usu ario de computador escrever documentos, montar planilhas, fazer gr acos e apresenta co es, enviar e receber mensagens e arquivos, fazer transa co es banc arias com seguran ca, montar projetos de engenharia, navegar na internet, ouvir m usicas, ver lmes e realizar diversas outras atividades de rotina e de lazer. Numa passagem r apida, podemos citar programas do dia a dia como o Oce (Power Point, Excel, Word), OpenOce (Impress, Calc, Write), Internet Explorer, Firefox, E-mail, Orkut, Players, programas t picos de servidores, como SSH, Telnet, FTP, programas especialistas de engenharia (Octave, Gnuplot, Matlab, Scilab, Autocad) e programas para o desenvolvimento de software (g++, make, gdb, ddd, cvs, cervisia, kdevelop, glade). Como podemos ver, temos ` a nossa disposi ca o centenas de softwares e programas, livres e propriet arios, com as mais variadas interfaces e formas de uso.

1.1.1

O que e um programa, um software?

Software ou programa de computador e uma seq u encia de instru co es a serem seguidas e/ou executadas, na manipula ca o, redirecionamento ou modica ca o de um dado/informa ca o ou acontecimento. Quando um software est a escrito usando instru co es que podem ser executadas diretamente por um processador dizemos que est a escrito em linguagem de m aquina. O dispositivo mais conhecido que disp oe de um processador e o computador. Existem outras m aquinas program aveis, como telefone celular, m aquinas de automa ca o industrial, calculadora, etc. Um programa e feito usando Linguagens de Programa ca o. [Wikipedia, 2007]. 51

52

DE SOFTWARE PROPRIETARIO 1.2. DEFINIC AO E SOFTWARE LIVRE

Eu prero uma deni ca o mais simples, como: conjunto de instru co es l ogicas, em linguagem de m aquina, utilizadas para realiza ca o de tarefas de nosso cotidiano por interm edio de um computador. Formalmente n ao existe diferen ca entre o conceito de software e programa. Mas particularmente uso o termo software, para um programa com interface gr aca amig avel e documenta ca o disponibilizada. Costumo usar o termo programa para um sistema que tem uma interface pobre e n ao tem documenta ca o (ou e mal documentado); Observe que essa e uma diferencia ca o de que gostamos de fazer, embora outros autores tenham suas pr oprias deni co es.

1.2

Deni c ao de software propriet ario e software livre

A seguir, ser ao apresentadas a deni ca o e as caracter sticas dos softwares propriet arios e dos softwares livres. Veja maiores detalhes nas refer encias: [Comunidade-GNU, 1996, http://www.fsl.org, 2004, Comunidade-Software-Livre, 1996]. [Anais, 2000, Queiroz, 2002, Amadeo., 2003].

1.2.1

Deni c ao e caracter sticas do software propriet ario

Veja a seguir as principais caracter sticas do software propriet ario: Segundo a refer encia [Wikipedia, 2007], o software propriet ario e um conceito criado por empresas de software com a inten ca o de proteger o seu produto de qualquer tipo de altera ca o. Sua licen ca pro be a distribui ca o ou c opia sem a autoriza ca o do propriet ario. Possui licen ca propriet aria, n ao podendo ser copiado em outros computadores, pois o usu ario compra uma licen ca de uso para um computador e sistema espec co. desenvolvido por empresas comerciais como Microsoft, Borland etc. E N ao pode ser modicado, uma vez queo c odigo-fonte n ao e distribu do. Possui suporte ocial, geralmente bem documentado.

1.2.2

Deni c ao e caracter sticas do software livre

Veja a seguir as principais caracter sticas do software livre: Garante ao usu ario plenas liberdades de uso, acesso e modica ca o do c odigo-fonte, c opia e publica ca o de vers oes modicadas. A deni ca o completa de software livre pode ser encontrada em http://www.gnu.org/philosophy/free-sw.html. A licen ca GPL e a licen ca de software livre mais utilizada no mundo, mas existem outras licen cas de software livre, como: BSD, LGPL, Artistic Licence, CC. A caracter stica e que qualquer trabalho derivado de um software livre obrigatoriamente deve permanecer livre. Uma descri ca o da GPL pode ser obtida em http://www.gnu.org/licenses/gpl.html e no Ap endice L Licen ca P ublica Geral GNU. Desenvolvido a partir do movimento pelo software livre, o qual surgiu na d ecada de 1970 em conseq u encia da crescente press ao recebida para a ado ca o de softwares propriet arios e assinaturas de tratados de n ao-divulga ca o. O movimento ganhou for ca a partir da d ecada Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

DE SOFTWARE PROPRIETARIO 1.2. DEFINIC AO E SOFTWARE LIVRE

53

de 1980 com o projeto GNU, que libertava os usu arios dos sistemas UNIX propriet arios. O GNU consolidou-se na d ecada de 1990 como um sistema operacional completo e funcional, atingindo uma qualidade t ecnica compar avel a ` dos melhores sistemas operacionais propriet arios. Em 1998 surgiu a Iniciativa Open Source 1 (c odigo aberto), grupo desmembrado do movimento pelo software livre em 1998 que rejeita a luta pela liberdade na utiliza ca o do software. Seu objetivo e disseminar a id eia de que o c odigo-fonte esteja dispon vel e que as modica co es sejam permitidas, gerando, assim, programas melhores. Apesar disso, esse grupo costuma recomendar a utiliza ca o da licen ca GPL, que representa melhor o esp rito do software livre. Isto torna os dois grupos cooperativos, do ponto de vista de cria ca o de softwares. Na maioria dos casos n ao possui suporte ocial (mas existem exce co es como o RedHat Enterprise, da RedHat, e o SUSE Linux Enterprise, da Novell). Nem sempre e bem documentado. Veja a seguir outros termos utilizados no mundo do software livre. O que e GNU? Acr onimo para GNU, n ao e UNIX. GNU e o nome de um sistema operacional completo e compat vel com UNIX escrito em 1983 por Richard Stallman e in umeros hackers da comunidade de software livre espalhados pela internet. O GNU e totalmente livre, ou seja, ele fornece as quatro liberdades b asicas do software livre: liberdade de uso, modica ca o, c opia e publica ca o de vers oes modicadas. O que e Linux? Clone livre do kernel do UNIX, escrito a partir do zero por Linus Torvalds, que contou com a ajuda de um grupo de programadores espalhados pela internet (isto e, o Linux e somente um kernel). Foi projetado para estar em conformidade com o POSIX e com a Single Unix Specication. O que e GNU/Linux? o sistema operacional GNU totalmente livre que utiliza o Linux como kernel; sendo a E variante mais conhecida do sistema GNU. Em resumo, Linux e um kernel, e n ao um sistema operacional. Apesar de Linux ser comumente utilizado em refer encia ao sistema operacional GNU/Linux, devemos evitar este uso equivocado por quest oes de clareza t ecnica e de cr edito ao projeto GNU, que forneceu o seu sistema operacional para ser adaptado ao kernel Linux. Sempre que quisermos falar deste sistema operacional, devemos usar o termo GNU/Linux. Desta forma, estaremos levando adiante os ideais do software livre que est ao representados no projeto GNU. Nota: uma descri ca o detalhada da licen ca GPL pode ser vista no Ap endice L Licen ca P ublica Geral GNU. Dicas e refer encias para migrar para software livre est ao dispon veis no , [GuiaLivre, 2004].
1 C odigo aberto: express ao utilizada para indicar que voc e pode ver o c odigo-fonte do programa. Entretanto, nada pode ser dito a respeito das condi co es sob as quais o c odigo-fonte se encontra. Existem programas de c odigo aberto que n ao s ao livres, pois o usu ario, dependendo da licen ca, pode ser proibido de alterar e publicar o c odigo.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

54

1.3. TIPOS DE INTERFACE DE UM PROGRAMA/SOFTWARE

1.2.3

Exemplos de softwares livres e propriet arios

Exemplo de sistemas operacionais propriet arios: Windows Mac OS X Unix Exemplo de sistemas operacionais livres: GNU/Linux Free-BSD Exemplos de programas propriet arios: Microsoft Oce Internet Explorer Borland Builder C++ Exemplos de programas livres GPL (equivalentes): OpenOce Firefox Kdevelop, Glade, Qt Designer J a sabemos o que e um software e as diferen cas entre software livre e software propriet ario. Tamb em vimos alguns exemplos de programas. Veremos a seguir os diferentes tipos de interface de um programa.

1.3

Tipos de interface de um programa/software

A interface de um programa e a forma como ele interage com o usu ario. Embora estejamos, na maior parte do tempo, utilizando programas com interface gr aca, ainda temos, muitas vezes, de utilizar programas com interface em modo texto. Usu arios avanc ados de Unix e GNU/Linux preferem utilizar programas neste modo, alegando conseguirem melhor produtividade. Nesta se ca o apresentaremos quatro tipos de interface de programas: Um programa sem nenhum tipo de interface kernel num erico (veja se ca o 1.3.1) . Um programa com interface via linha de comando (veja se ca o 1.3.2). Um programa com interface em modo texto (veja se ca o 1.3.3). Um software com interface em modo gr aco (veja se ca o 1.3.4). Nosso objetivo e apresentar as caracter sticas e as diferen cas entre esses programas, al em de apresentar o n vel de complexidade da sua interface. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

1.3. TIPOS DE INTERFACE DE UM PROGRAMA/SOFTWARE

55

1.3.1

Um programa sem interface (kernel num erico)

De uma maneira geral, um kernel num erico e um programa sem nenhum tipo de interface com o usu ario, sendo utilizado para realiza ca o de algum processamento de dados. Veja as caracter sticas de um programa do tipo kernel num erico: N ao tem interface com o usu ario (entradas e sa das). Tem como objetivo realizar algum processamento, geralmente um processamento pesado, ou a realiza ca o de tarefas bem espec cas. Uma documenta ca o simplicada pode ou n ao estar disponibilizada. Veja a seguir um exemplo de programa do tipo kernel num erico em C++. A classe TRotulador3D e usada para separar e identicar os objetos presentes em uma imagem binarizada. Para tanto, e utilizado um algoritmo de rotulagem dos pixels da imagem. Neste exemplo n ao existe nenhuma intera ca o com o usu ario; o arquivo com a imagem imagem.pbm e carregado do disco em (1), a rotulagem e realizada em (2) e o resultado e armazenado em disco com o nome rotulada.pgm em (3). Veremos na se ca o ?? outros exemplos de programas do tipo kernel num erico. Nota: n ao se preocupe em entender o programa, o objetivo e mostrar que neste exemplo n ao temos intera ca o com o usu ario. // Exemplo de rotulagem de imagens 3D #include <iostream> #include <TRotulador/TRotulador3D.h> int main(int argc, char* argv[]) { TRotulador3D rot("imagem.pbm"); // (1) Cria rotulador e carrega imagem rot.Go(); // (2) Executa rotulagem rot.Write("rotulada.pgm"); // (3) Salva resultado em disco return 0; }

1.3.2

Um programa com interface via linha de comando

Um programa pode ser desenvolvido de forma a receber a entrada do usu ario utilizando a linha de comando. Como exemplo, temos os programas dir e ls, os quais podem receber par ametros opcionais e s ao utilizados para visualiza ca o dos arquivos de um determinado diret orio. Observe que neste caso j a existe algum tipo de intera ca o entre o usu ario e o programa. Veja as caracter sticas de um programa com interface via linha de comando: A passagem dos par ametros e feita na chamada do programa, via linha de comando. Os par ametros podem ser opcionais como em ls -lah , dir /w . Para ver as op co es do programa ls, abra um terminal e digite ls - -help ou man ls . A sa da de dados e opcional, pode ser para tela, para um arquivo de disco ou para outro dispositivo. Este tipo de programa permite o uso de redirecionamentos (exemplo: ls > saida.txt ), uso de pipes (ex: ls | sort ) (veja se ca o 23.4). Veremos exemplos de programas com interface via linha de comando nas se co es E.1 e E.2. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

56

1.3. TIPOS DE INTERFACE DE UM PROGRAMA/SOFTWARE

1.3.3

Um programa com interface em modo texto

Um programa com interface em modo texto inclui entrada e sa da de dados usando uma interface simplicada (teclado e monitor). Veja a seguir as caracter sticas de um programa com interface neste modo: Apresenta interface simplicada, em modo texto. As entradas s ao executadas via teclado e as sa das, usando a tela, geralmente por meio de um terminal. Muito utilizado em servidores, em programas para manuten ca o do sistema, em programas cient cos, em engenharia e em sistemas antigos (legados). O programa de reconstru ca o tridimensional, ilustrado na Figura 1.1(a), e um exemplo de programa com interface em modo texto, o qual cria uma imagem 3D a partir de dados medidos em imagens 2D. O programa inicia mostrando valores-padr ao a serem utilizados na reconstru ca o e um menu simplicado, no qual o usu ario pode selecionar uma das seguintes op co es: iniciar a reconstru ca o, modicar os valores a serem utilizados ou abandonar o programa. Observe que, depois de selecionar a op ca o Valores corretos, iniciar reconstru ca o.....(r), cada etapa executada pelo programa e mostrada na tela, indicando que a mesma foi conclu da. Na Figura 1.1(b), e apresentada a tela inicial do programa Octave, utilizado para a realiza ca o de c alculos t picos de m etodos num ericos. No exemplo, o Octave e utilizado para somar dois vetores. Para maiores detalhes do programa Octave, consulte o site http://www.gnu.org/ software/octave/. Ao longo deste livro apresentaremos dezenas de exemplos de programas com interface em modo texto.

Figura 1.1: Em (a) programa de reconstru ca o tridimensional, em (b) o programa Octave.

(a) Programa de reconstru ca o 3D.

(b) Programa octave.

Um programa com interface em modo texto e mecanismo de recupera c ao O programa do grafo de conex ao serial, apresentado na Figura 1.2, e utilizado para determinar a permeabilidade de rochas usando representa co es 3D (imagens tridimensionais). Sua Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

1.3. TIPOS DE INTERFACE DE UM PROGRAMA/SOFTWARE

57

entrada e a imagem gerada pelo programa de reconstru ca o (veja Figura 1.1(a)). Observe ainda na Figura 1.2 que o programa tamb em tem uma interface em modo texto semelhante ao programa de reconstru ca o, mas apresenta alguns diferenciais interessantes: Salva valores parciais da simula ca o em disco. Permite o rein cio do programa ap os queda de energia. N ao repete a simula ca o de imagens j a processadas (trabalha com lista de imagens). Essas caracter sticas s ao bastante u teis em programas de engenharia, programas cient cos e programas que envolvam o processamento de grandes quantidades de dados. O sistema de rein cio e bastante simples: a m aquina e programada para iniciar automaticamente o programa quando for reiniciada. O programa l e o arquivo com a lista de imagens a serem processadas, verica quais j a foram processadas, e ent ao reinicia a simula ca o da imagem que estava sendo processada quando a energia caiu.

ca o. Figura 1.2: Programa com interface em modo texto e mecanismos de recupera

1.3.4

Um software com interface em modo gr aco

O software Anaimp apresentado na Figura 1.3(a) e um software educativo para an alise de imagens e que possui interface em modo gr aco. Veja a seguir as caracter sticas de um software com interface em modo gr aco: ca o automatizada. Tem programa para instala Tem interface gr aca e amig avel (menus, bot oes, di alogos, barra de tarefa e de status). Tem previs ao de impress ao, possibilidade de desenho das imagens, sistema de controle dos processamentos (exemplo: visualiza ca o passo a passo dos processos realizados). Tem manual do usu ario. Infelizmente o programa Anaimp n ao foi nalizado, uma vez que, por utilizar uma biblioteca gr aca propriet aria que foi descontinuada a OWL da Borland , decidimos abandonar o desenvolvimento do programa Anaimp e posteriormente constru -lo utilizando bibliotecas GPL, como a Qt. Na se ca o ??, veremos diversos exemplos de uso da biblioteca Qt 4, utilizada para a montagem de programas com interface gr aca. Um exemplo de software prossional e completo com este tipo de interface e o Imago (veja Figura 1.3(b)), . O Imago e exemplo de software nacional, premiado, desenvolvido numa parceria da ind ustria (Petrobras) com a universidade (UFSC) e a empresa ESSS.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

58

1.4. QUE TIPO DE SOFTWARE DEVO DESENVOLVER?

Figura 1.3: Programas com interface gr aca.

(a) O software Anaimp.

(b) O software Imago.

1.4

Que tipo de software devo desenvolver?

Bem, agora que voc e j a conhece as principais diferen cas entre o software propriet ario e o software livre e os diferentes tipos de interface com o usu ario, voc e precisa responder quest oes como: Devo desenvolver software propriet ario ou software livre? Devo desenvolver software com interface em modo texto ou em modo gr aco? Devo desenvolver software propriet ario ou software livre? A resposta para esta quest ao n ao e f acil. Voc e ter a de analisar os pr os e contras de cada modelo, e ent ao escolher o modelo de desenvolvimento de software que mais se aproxima de seu perl. Como sou defensor do modelo de software livre, aconselho a leitura das seguintes refer encias: O que e a losoa do SL? [Comunidade-GNU, 1996, http://www.fsl.org, 2004] Porque usar SL? [Queiroz, 2002] Quem paga pelo SL?[Comunidade-Software-Livre, 1996, Amadeo., 2003] Devo desenvolver software com interface em modo texto ou em modo gr aco? Esta resposta e mais f acil. Se o programa e um programa cient co, que envolve c alculos/processamentos pesados e que tem pouca necessidade de intera ca o com o usu ario, voc e pode usar uma interface em modo texto. No entanto, se o programa requer uma intera ca o constante com o usu ario, a op ca o correta e o software com interface em modo gr aco. Dica: tente montar o programa usando os conceitos prossionais da engenharia de software, pois viabilizam o desenvolvimento de softwares complexos e facilitam a migra ca o de um programa com interface em modo texto para interface em modo gr aco. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

1.5. RESUMO DO CAP ITULO

59

1.5

Resumo do cap tulo

Neste primeiro cap tulo aprendemos o conceito de software, de programa e as diferen cas entre o software livre e o software propriet ario. Ademais, foi colocada a quest ao sobre o que desenvolver: software propriet ario ou software livre. Vimos que um programa de computador pode ter diferentes tipos de interface e que um kernel num erico e um programa sem interface. Um programa em linha de comando, por sua vez, recebe seus par ametros na chamada do programa e pode ou n ao apresentar uma sa da na tela do computador. Um programa em modo texto, como o Octave, apresenta uma interface simplicada, em modo texto, e e utilizado por usu arios experientes. J a os softwares mais amig aveis contam com interface gr aca com menus, bot oes e di alogos que facilitam seu uso. No pr oximo cap tulo apresentaremos uma breve introdu ca o ` a programa ca o orientada a objeto. Dica: embora o computador possibilite uma intera ca o mais universal, seja por meio de um jogo de xadrez pela internet com pessoas de qualquer parte do mundo, seja por meio da cria ca o e desenvolvimento de sua pr opria tribo, n ao deixe de apreciar e viver a vida na sua comunidade. Aprenda a conciliar estes dois universos.

1.6

Exerc cios

1. Explique com suas palavras o que e um programa e porque desenvolvemos programas de computador? 2. Quais as principais diferen cas entre sistemas operacionais livres e propriet arios? 3. Porque devemos ler a licen ca de um software quando o instalamos? 4. Voc e j a deve ter utilizado um navegador para fazer o download de arquivos pela internet (como o Firefox/Explorer), mas existem programas em modo texto, como o FTP (veja se ca o ??) e o Wget (http://www.gnu.org/software/wget/wget.html), que tamb em s ao utilizados para fazer download de arquivos. Descreva quais as vantagens e desvantagens dos programas em modo gr aco e dos programas em modo texto. 5. Qual a vantagem de um programa que pode ser reinicializado automaticamente pelo sistema? 6. Um programa escrito por voc e pode usar componentes fornecidos por um programa livre como o OpenOce Impress? E se o programa fosse o Microsoft Word, voc e poderia utilizar componentes do Microsoft Word em seu programa? 7. Um sistema de engenharia gera uma quantidade enorme de dados, sendo necess ario fazer 100 gr acos. Estes gr acos podem ser mais rapidamente feitos em uma planilha como o OpenOce Calc ou em programas em modo texto como o Gnuplot (http: //www.gnuplot.info/)? 8. Quais as aplica co es e vantagens de programas do tipo kernel num erico? 9. Quais os programas com interface via linha de comando que voc e costuma utilizar? 10. Fa ca um breve hist orico de programas novos e antigos utilizados na sua area de estudo. Al em de perquisar na internet, converse com professores e prossionais antigos; tente entender as transforma co es que t em ocorrido no mundo da inform atica. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

60

1.6. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 2

Introdu c ao ` a Programa c ao Orientada a Objeto POO


Neste cap tulo apresentaremos uma se ca o sobre como entendemos os objetos (se ca o 2.1), um exemplo de objeto (se ca o 2.2) e em seguida o conceito de objeto (se ca o 2.3). Veremos ainda um breve hist orico da programa ca o orientada a objeto (se ca o 2.4), uma compara ca o desta versus a vis ao desorganizada e a vis ao estruturada (se ca o 2.4.1), e as vantagens da programa ca o orientada a objeto (se ca o 2.4.2). Nota: em nossas aulas, sempre utilizamos exemplos de objetos reais e abstratos. Primeiro falamos de um exemplo real, mais f acil de entender, e depois de algum exemplo abstrato. Este procedimento did atico e adotado ao longo deste livro.

2.1

Entendendo os objetos

Para explicar os conceitos b asicos de orienta ca o a objeto, costumo usar primeiramente os objetos que est ao na sala de aula: cadeiras, mesas, computadores, projetor, cabos de energia e de rede, tomadas, l ampadas, pincel, quadro, apagador. Uma pergunta que sempre fa co e: como uma crian ca v e uma sala de aula? uma cadeira?. O objetivo desta pergunta e relembrar como aprendemos a entender o mundo em que vivemos. Entendemos o mundo por meio de classica co es e associa c oes. Estamos o tempo todo classicando, identicando os atributos (propriedades) e fun co es (a co es, m etodos) que determinado objeto e capaz de realizar. Na maioria dos casos conseguimos encaixar o objeto numa classe pr e-existente. Em alguns casos o objeto n ao e exatamente do mesmo tipo, mas e uma varia ca o, uma evolu ca o ou adapta ca o de um objeto conhecido. Assim, para uma crian ca, uma cadeira e um objeto cuja fun ca o e ser utilizada para se sentar. Neste sentido, uma cadeira de uma sala de aula, de um restaurante, ou at e mesmo um sof a e um tipo de cadeira. Rapidamente a crian ca come ca a fazer outras classica co es sobre as cadeiras, como, cadeira branca, cadeira com apoio para bra co, cadeira com rodinhas. Identicamos assim diversos atributos do objeto cadeira. Estes atributos (propriedades ou caracter sticas) s ao utilizados para diferenciar uma cadeira da outra, criando eventualmente subgrupos, mas o conceito essencial de objeto para se sentar permanece. Segundo [Guedes, 2004], sempre que precisamos compreender um conceito novo, criamos uma nova classe para este conceito e determinamos que todo objeto com as mesmas caracter sticas desta classe e um exemplo, uma inst ancia dela. Vamos a um exemplo: ao ver pela 61

62

2.2. EXEMPLO DE OBJETO

primeira vez um SkySurf, voc e automaticamente o associa ao Surf e a esportes como AsaDelta. Neste caso, criamos um conceito novo baseado na composi ca o de conceitos j a conhecidos. Outro exemplo: uma c elula PVT. Possivelmente voc e vai perguntar que raio de objeto e esta tal c elula PVT? Uma c elula PVT e um equipamento utilizado em engenharia de petr oleo para determinar propriedades do oleo baseando-se em an alises de Press ao, Volume, Temperatura, ou seja, e um equipamento de medi ca o. Observe que e um conceito novo, um equipamento totalmente desconhecido. Nosso c erebro precisa criar este novo conceito, criando uma nova classe de objetos. Agora que j a sabemos mesmo que basicamente a forma como identicamos e classicamos os objetos, vamos apresentar um exemplo de objeto e a seguir o conceito de objeto.

2.2

Exemplo de objeto

Veja a seguir um exemplo de objeto do mundo real e a an alise de algumas de suas caracter sticas. Concluiremos que a programa ca o orientada a objeto e baseada em conceitos que j a conhecemos.

Um rel ogio Retire o seu rel ogio do pulso e comece a analis a-lo. Verique que ele e um objeto real, que lhe d a algumas informa co es como hora, data e dia da semana e que tem cron ometro e alarmes. Essas informa co es s ao atributos que s ao manipulados pelo rel ogio, ou seja, um objeto tem atributos. O rel ogio tamb em tem bot oes, como um bot ao de ilumina c ao, um bot ao para selecionar o atributo a ser visto, um bot ao para acertar a hora. Podemos dizer que o acionamento desses bot oes corresponde a um evento, uma mensagem enviada para o objeto solicitando que determinada fun ca o do rel ogio seja executada. Logo, um objeto tem fun co es (m etodos). Al em dos bot oes, o rel ogio tamb em tem uma caixa externa e uma pulseira, ou seja, um objeto rel ogio e composto de outros objetos. Um objeto pode ser formado a partir de um conjunto de objetos que s ao agregados/agrupados. Falamos de um rel ogio moderno, com alarmes e cron ometros; mas um rel ogio antigo s o informava a hora; de um rel ogio de bolso evoluiu-se para rel ogios de pulso, para rel ogios de parede, para rel ogios com alarmes, com cron ometros etc., ou seja, um objeto pode evoluir e esta evolu ca o est a associada a uma heran ca, uma hierarquia. Apesar de todas essas informa co es, a informa ca o principal do rel ogio e a hora certa. Visto que o rel ogio n ao e uma m aquina perfeita, ele pode atrasar. Neste caso, o dono do rel ogio utiliza a informa ca o de um rel ogio-padr ao, com a hora certa, para acertar a hora. Nesse exemplo, um objeto homem interagiu com o objeto rel ogio, logo, podem existir intera co es entre os objetos. Uma informa ca o de um rel ogio-padr ao (a hora certa) foi usada para acertar outro rel ogio. Observe que um objeto tamb em pode acessar diretamente informa co es de outros objetos. Voc e tamb em sabe que existe uma f abrica de rel ogios e que nela est ao as informa co es para se construir o rel ogio. Veremos que uma classe e uma f abrica de objetos, e e na classe que se encontram as informa co es de como montar o objeto. Os conceitos discutidos neste exemplo, atributos, eventos, m etodos, agrega ca o, heran ca, classes, al em da abstra ca o, s ao os conceitos b asicos da POO e j a s ao nossos conhecidos. Os mesmos ser ao detalhados no Cap tulo 3 Conceitos B asicos de Orienta ca o a Objeto. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

2.3. O CONCEITO DE OBJETO (OU INSTANCIA)

63

2.3

O conceito de objeto (ou inst ancia)

Objetos s ao coisas do mundo real ou imagin ario que podemos, de alguma forma, identicar, como uma pedra, uma caneta, um copo ou uma fada. Segundo [Rezende, 2002], um objeto pode ser uma entidade externa, coisas, unidades organizacionais, lugares, estruturas. Um objeto possui determinadas propriedades que o caracterizam e que s ao armazenadas nele mesmo. Suas propriedades s ao chamadas de atributos e s ao utilizadas para identicar o estado do objeto. O objeto interage com o meio e, em fun ca o de excita co es que sofre, realiza determinadas a co es que alteram o seu estado (seus atributos). Observe que os atributos do objeto n ao s ao est aticos, pois sofrem altera co es com o tempo. Para a AOO (An alise Orientada a Objeto), um objeto e uma entidade u nica que re une atributos e m etodos, ou seja, re une as propriedades do objeto e os m etodos respons aveis pela realiza ca o de opera co es sobre o objeto (as rea co es ` as excita co es que sofre). Nota: por conven ca o, o nome dos objetos e escrito como em RioDasOstras (e n ao Rio das Ostras ou Rio das Ostras).

2.4

Breve hist orico da programa c ao orientada a objeto

As linguagens de programa ca o de primeira gera ca o eram bastante r usticas, de baixo n vel (como o Assembler), e obrigavam o programador a conhecer em excesso as caracter sticas do hardware que estava usando. Um programa se dirigia para um equipamento espec co, era extremamente complexo de desenvolver, e n ao podia ser utilizado em outras m aquinas. N ao era poss vel reaproveitar os c odigos desenvolvidos. Com o passar dos anos, desenvolveram-se novas linguagens de programa ca o, que foram desvinculando os programas do hardware, de tal forma que um mesmo c odigo poderia ser compilado e executado em diferentes plataformas. Entre as linguagens de segunda gera ca o, podemos citar Fortran e Algol. Estas linguagens proporcionaram um grande avan co no desenvolvimento do software. Observe que persistiam dois problemas: o execut avel ainda era espec co e n ao existia reaproveitamento de c odigo. Enquanto o desenvolvimento de hardware se dava a passos largos, o desenvolvimento de softwares estava atrasado cerca de 20 anos. As linguagens de programa ca o de terceira gera ca o, como C e Pascal, s ao linguagens procedurais, que permitem o uso de programa ca o estruturada , na qual as fun co es manipulam os dados, mas n ao t em uma liga ca o ntima com eles. O enfoque e a implementa ca o de m odulos de programas que s ao desenvolvidos utilizando metodologias como bottom-up ou top-down. Com o desenvolvimento das t ecnicas de programa ca o estruturada, o problema da falta de reaproveitamento de c odigo diminuiu, pois foram desenvolvidas bibliotecas que podiam ser reaproveitadas. Para uma descri ca o completa das t ecnicas de programa ca o estruturada, consulte [Martin and McClure, 1993, Sonerviile, 1993, Pressman, 2002]. Mesmo com o surgimento dos primeiros modelos de engenharia de software e das t ecnicas de programa ca o estruturada, as equipes de desenvolvimento sempre tiveram enormes problemas para o desenvolvimento de seus programas. Tinham de partir praticamente do zero para o desenvolvimento de um programa ou reaproveitar muito pouco os c odigos e bibliotecas j a desenvolvidos. Para solucionar o problema do reduzido reaproveitamento dos c odigos, deniu-se melhor a id eia da Programa ca o Orientada a Objeto. A POO n ao e nova; sua formula ca o data de 1960, Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

64

ORIENTADA A OBJETO 2.4. BREVE HISTORICO DA PROGRAMAC AO

mas passou a ser efetivamente utilizada a partir da d ecada de 1990, de modo que todas as grandes empresas de inform atica t em desenvolvido os seus softwares utilizando a POO. A programa ca o orientada a objeto e diferente da programa ca o estruturada. Nela, fun co es e dados est ao juntos, formando o objeto. Essa abordagem cria uma nova forma de analisar, projetar e desenvolver programas; uma forma mais abstrata e gen erica, que permite maior reaproveitamento dos c odigos e facilita a sua manuten ca o. Observe que a POO n ao e somente uma nova forma de programar, mas uma nova forma de pensar um problema, utilizando conceitos do mundo real e n ao conceitos computacionais. Por exemplo: o usu ario nal ver a todos os cones e janelas da tela como objetos e associar a a manipula ca o desses objetos visuais ` a manipula ca o dos objetos reais que eles representam. Um cone impressora representar a a impressora de seu sistema computacional e permitir a a execu ca o de impress ao, a sele ca o do tamanho da p agina, entre outras opera co es realizadas com esse objeto. Na modelagem orientada a objeto, o conceito de objeto deve acompanhar todo o ciclo de desenvolvimento do software. Ela tamb em inclui uma nova nota ca o e exige do analista/programador o conhecimento desta (diagramas). Em resumo, A ess encia do desenvolvimento orientado a objeto e a identica ca o e a organiza ca o de conceitos da aplica ca o, tendo como pe ca b asica de todo desenvolvimento o conceito um modo de pensar natural e universal e n de objeto. E ao uma t ecnica de programa ca o. [Blaha and Rumbaugh, 2006]. As linguagens de programa ca o mais modernas permitem que um programa seja compilado e executado em diferentes plataformas. Em alguns casos, o c odigo bin ario do programa pode ser executado em diferentes plataformas, sem necessidade de recompila ca o e com grande reaproveitamento de c odigo. Atualmente existem centenas de bibliotecas cuidadosamente desenhadas para dar suporte aos programadores menos sosticados, de modo que estes podem montar seus programas unindo as bibliotecas externas com alguns objetos que criaram, ou seja, podem montar suas aplica co es rapidamente, contando com m odulos pr e-fabricados. O paradigma da POO e, como veremos a seguir, uma resposta eciente a uma s erie de problemas da area de desenvolvimento de software. Veremos exemplos de bibliotecas externas na se ca o ?? Bibliotecas Uteis.

2.4.1

Vis ao desorganizada e vis ao estruturada versus vis ao orientada a objeto

Esta se ca o apresenta tr es formas de desenvolvimento de um programa simples, o qual realiza a integra ca o num erica de uma fun ca o parab olica. Mesmo n ao entendendo nada de m etodos num ericos, voc e deve ler esse exemplo; o que importa e o conceito abordado. Especica ca o: quero desenvolver um programa que realize a integra ca o num erica da equa ca o de uma par abola y = a + b.x + c.x2 , no intervalo que vai de limiteInferior a limiteSuperior, usando 100 subintervalos (numeroPontos = 100). Vis ao desorganizada O programador desorganizado come ca imediatamente a desenvolver o seu programa. Cria um arquivo u nico no qual dene as vari aveis, a fun ca o e nalmente inclui o c odigo para realizar a integra ca o pelo m etodo de Simpson (porque e o que ele conhece e domina). Os nomes das vari aveis s ao v1 (o valor de y), v2 (o a da equa ca o), v3 (o b), v4 (o c), v5 (ele n ao utiliza, mas deixa denida). Dene ainda s1, s2, s3 e s4 (vari aveis utilizadas pelo m etodo de integra ca o). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

ORIENTADA A OBJETO 2.4. BREVE HISTORICO DA PROGRAMAC AO

65

O programa funcionar a; o programador ent ao dar a um nome como prog1 e o armazenar a num diret orio qualquer. Depois de um m es, ele j a n ao se lembra mais do nome do programa e de onde o guardou, e agora precisa desenvolver um programa de integra ca o para uma outra fun ca o. Bem, come ca tudo de novo, pois, mesmo que localize o arquivo, n ao se lembrar a do que signica v1, v2 etc. Vis ao estruturada Na vis ao estruturada o programador se preocupa em dividir/separar as fun co es. Em um arquivo prog.cpp, o usu ario inclui as bibliotecas-padr ao do sistema que utilizar a. O usu ario declara fun co es globais, uma para c alculo da fun ca o parab olica y = f(x) = a + b.x + c.x2 ;, e outra para c alculo da integral com o nome AreaSimpson(f, limiteInferior, limiteSuperior, numeroPontos);. Uma fun ca o principal main() e encarregada da entrada de dados, da chamada da fun ca o AreaSimpson(f, limiteInferior, limiteSuperior, numeroPontos); e da sa da dos resultados. Observe que, com uma vis ao estruturada, o programa apresentar a alguma organiza ca o. Vis ao orientada a objeto Na vis ao orientada a objeto todo o desenvolvimento do software e feito de forma diferente. A inten ca o nunca e a de resolver um problema u nico e imediato. 1. Especico com clareza o que quero: resolver uma integra ca o num erica de uma equa ca o gen erica por qualquer m etodo. 2. Elaboro melhor o problema, estudando materiais relacionados ao programa a ser desenvolvido, lendo alguns livros de matem atica e m etodos num ericos relacionados ao tema. 3. Em seguida, fa co uma an alise para identicar os objetos e seus relacionamentos. Ao olhar um livro de m etodos num ericos, descubro que existe um conjunto de m etodos que podem ser utilizados para resolver o problema. As equa co es podem ser as mais diversas poss veis, mas possuem algumas caracter sticas em comum. A fun ca o parab olica obedece ` a forma y = f(x). Com rela ca o aos m etodos num ericos, ela identica os m etodos mais conhecidos: Trap ezio, Simpson e Gauss, que possuem em comum atributos como limiteInferior, limiteSuperior, numeroPontos e o intervalo dx. Assim, identicam-se alguns objetos: i) um objeto gen erico de integra ca o num erica, um objeto de integra ca o por Simpson, outro por Trap ezio e outro por Gauss; ii) um objeto fun ca o da forma y = f(x), que tem os atributos y, x; e- iii) um m etodo de c alculo que executa a fun ca o em si. O objeto integra ca o deve receber o objeto fun ca o e realizar a integra ca o dessa fun ca o. 4. Antes de iniciar o desenvolvimento do programa, o programador deve considerar as caracter sticas da linguagem que vou utilizar e do hardware que est a dispon vel. Devo revisar a an alise desenvolvida considerando o hardware e a linguagem de programa ca o escolhida. 5. Agora sim, come co a escrever o programa, que utiliza uma nota ca o uniforme. 6. Finalmente o programa e testado e os erros (bugs) s ao eliminados. 7. N ao me esque co de documentar tudo o que foi feito, para que possa reaproveitar o programa em uma outra ocasi ao. A documenta ca o tamb em ajuda nas etapas de teste e manuten ca o. 8. O programa nal e armazenado em um reposit orio, podendo ser facilmente localizado, reaproveitado e/ou extendido. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

66

2.5. RESUMO DO CAP ITULO

2.4.2

Vantagens da POO

Comparando a vis ao desorganizada e a vis ao estruturada com a vis ao orientada a objeto, podemos identicar as seguintes vantagens da POO: Os objetos s ao representa co es de conceitos j a conhecidos. Os objetos, as fun co es e as vari aveis t em nomes claros e precisos. Os objetos se relacionam da forma esperada, de modo que um programador iniciante ter a uma vis ao facilitada do programa. Os diagramas desenvolvidos na etapa de an alise facilitam o entendimento de todo o programa (os diagramas ser ao apresentados no Cap tulo 6 Etapas para o Desenvolvimento de um Programa). O programa e documentado, facilitando o reaproveitamento dos c odigos desenvolvidos. O trabalho desenvolvido e gravado como uma biblioteca de objetos em um local adequado (normalmente um reposit orio). Para desenvolvedores, programadores, analistas ou gerentes, as vantagens da POO podem ser resumidas a: Gerentes maior velocidade e menores custos no desenvolvimento do programa. Analistas e desenvolvedores processo de modelagem mais simples, com maior reaproveitamento de c odigos e facilidade de manuten ca o. Programadores aumento da produtividade.

2.5

Resumo do cap tulo

Neste cap tulo vimos que C e Pascal s ao linguagens procedurais, de terceira gera ca o, e que a linguagem C++ pode ser considerada uma linguagem de quinta gera ca o. Destacamos que a programa ca o orientada a objeto e mais natural e organizada que a programa ca o estruturada e camos conhecendo as vantagens da POO, como a maior velocidade e o aumento da produtividade no desenvolvimento de sistemas complexos. Passamos a entender o conceito de objeto e vimos que os conceitos utilizados na POO s ao nossos conhecidos. No Cap tulo 3 Conceitos B asicos de Orienta ca o a Objeto, aprenderemos os conceitos de abstra ca o, encapsulamento, objeto, heran ca e polimorsmo. Depois, no Cap tulo 4 Modelagem Orientada a Objeto, analisaremos a vantagem do uso de modelos, o hist orico e o uso da UML Veremos ainda a evolu ca o hist orica do ciclo de desenvolvimento de um software no Cap tulo 5 Engenharia de software. Finalmente, no Cap tulo 6 Etapas para o desenvolvimento de um software, descrevemos todo o ciclo de desenvolvimento de um software

2.6

Exerc cios

1. Procure na internet material que compare a programa ca o estruturada e a programa ca o orientada a objeto. Fa ca um resumo comparativo. 2. Diga, com suas palavras, as principais diferen cas entre a vis ao estruturada e a vis ao orientada a objeto. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

2.6. EXERC ICIOS 3. Quais as desvantagens da POO?

67

4. Quando estiver dentro de um carro, procure identicar quais s ao os objetos agregados (que fazem parte do carro). 5. Pense num carro de 40 anos atr as. Quais as principais diferen cas em rela ca o a um carro atual? 6. Para um objeto impressora, quais s ao seus atributos? Quais s ao seus m etodos? 7. Releia a se ca o 2.2 Exemplo de objeto e verique que os conceitos apresentados objetos, atributos, fun co es, composi ca o, evolu ca o, heran ca, intera co es s ao conceitos que j a conhecemos, ou seja, a orienta ca o a objetos j a faz parte de nosso dia-a-dia. Voc e concorda com esta arma ca o? 8. Diga com suas palavras o que e um objeto? 9. Quando estiver em casa, fa ca uma an alise dos atributos e das fun co es dos objetos: sof a, televisor, mesa, cadeira, escrivaninha, torneira etc. 10. Para cada grupo de objetos ou de palavras a seguir, identique as caracter sticas em comum e depois suas diferen cas: Pasta, mala, mochila. Cadeira, poltrona, sof a. Carro, caminh ao, trator. Winchester, zip drive, CD-RW, DVD-RW, pen-drive. 11. Separe alguns objetos reais e procure identicar seus atributos, funcionalidades e como os mesmos interagem com outros objetos.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

68

2.6. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 3

Conceitos B asicos de Orienta c ao a Objeto OO


A Orienta ca o a Objeto (OO) tem uma s erie de conceitos-chave que auxiliam as pessoas a delinearem claramente um problema e a identicarem os objetos e seus relacionamentos. Neste cap tulo descreveremos alguns conceitos b asicos de OO: abstra ca o (se ca o 3.1), encapsulamento e oculta ca o (se ca o 3.2), classes (se ca o 3.3), atributos (propriedades/vari aveis) (se ca o 3.4), m etodos (fun co es/opera co es/servi cos) (se ca o 3.5), heran ca (se ca o 3.6) e polimorsmo (sec a o 3.7). Ao nal, ser ao apresentados outros conceitos u teis (se ca o 3.8).

3.1

Abstra c ao

No dicion ario Aur elio, abstra ca o signica considerar isoladamente coisas que est ao unidas, ou seja, partimos do enfoque global de um determinado problema e procuramos separar os elementos fundamentais e coloc a-los de uma forma mais pr oxima da solu ca o. A id eia da abstra ca o e identicar os elementos essenciais de um problema e suas propriedades fundamentais, separando ocorr encias e atributos acidentais (isolando detalhes menos importantes). Para a an alise orientada a objeto, abstra ca o e o processo de identica ca o dos objetos e seus relacionamentos. Ela permite ao analista concentrar-se no que um objeto e e faz, sem se preocupar como ele o faz. A abstra ca o se d a em diferentes n veis: inicialmente, abstrai-se o objeto; em seguida, procuramos identicar seus atributos e funcionalidades. De um conjunto de objetos, cria-se um conjunto de classes relacionadas, geralmente uma hierarquia ou um assunto. Por exemplo: em nossa sala de aula temos um interruptor e l ampadas. Todos sabemos que o interruptor e o objeto a ser acionado para que a l ampada acenda/apague. Existe uma clara rela ca o entre o interruptor e a l ampada. Juntamente com os os e o disjuntor eles formam o sistema de ilumina ca o. Observe as Figuras 3.1 (a) e 3.1 (b). Qual imagem e mais confusa? Em 3.1(a), est ao representados elementos do sistema de ilumina ca o, do sistema de telefonia, do cluster e os computadores da sala. A Figura 3.1(b) e mais simples, pois eliminamos os detalhes que n ao s ao importantes, deixando apenas os elementos essenciais ao sistema de ilumina ca o. A partir da Figura 3.1(b), podemos identicar mais claramente os objetos do sistema de ilumina ca o. 69

70

3.2. ENCAPSULAMENTO E OCULTAC AO

Observe que podemos ver o interruptor e a l ampada como sendo um objeto u nico ou como dois objetos que se relacionam. Outra percep ca o importante: nossa vis ao natural. Nossos conceitos b asicos enfocam os objetos e n ao os sistemas dos quais fazem parte. Por exemplo: focamo-nos no objeto l ampada, no objeto interruptor, e n ao no sistema de ilumina ca o. Finalmente e importante destacar que uma boa abstra ca o do sistema e conseguida ap os v arias itera co es, muita an alise e um pouco de experi encia. Figura 3.1: O processo de abstra ca o.

Quadro de distribuio lmpada lmpada

Quadro de distribuio lmpada lmpada

servidor

interruptor

interruptor

caixa de atividades sistema telefonico


A0

(a)

(b)

No exemplo da Figura 3.1 identicamos os seguintes objetos: Quadro de distribui ca o Fios Interruptor L ampadas

3.2

Encapsulamento e oculta c ao

Todos os equipamentos que utilizamos s ao altamente encapsulados. Tome como exemplo seu monitor de computador. Ele tem um pequeno conjunto de bot oes que lhe permitem manipular os atributos do objeto monitor que s ao de seu interesse, como: ligar/desligar, controlar o brilho, o contraste, a resolu ca o. Mas voc e sabe que o funcionamento do objeto monitor e extremamente complexo e que, ao mudar a resolu ca o, uma s erie de atributos internos s ao processados e alterados. Um monitor CRT tem um tubo de raios cat odicos, dezenas de os, placas internas, resistores, capacitores e uma innidade de dispositivos el etricos que est ao ocultos, encapsulados, escondidos do usu ario; ou seja, o encapsulamento separa o que e vis vel (p ublico) do que e oculto (protegido/privado). Na Figura 3.2, temos a imagem de dois monitores: em (a) a vis ao de um usu ario comum; em (b) a vis ao de um engenheiro eletricista. A vis ao de cada um e diferente, depende de suas especialidades. Observe que os engenheiros eletricistas zeram um bom trabalho de encapsulamento, deixando acess vel apenas o que e de nosso efetivo interesse. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

3.2. ENCAPSULAMENTO E OCULTAC AO

71

Figura 3.2: O que voc e v e?

(a) A vis ao do usu ario.

(b) A vis ao do engenheiro.

Exemplos: Um computador e um objeto extremamente complexo, mas para o usu ario o que importa e o teclado, o monitor de v deo, o DVD, o mouse e o gabinete. Ao utilizar um software como o OpenOce, a forma de uso e a mesma, seja em um Windows com Pentium IV ou em um GNU/Linux com AMD Athlon 64. Os elementos invis veis do computador (placa-m ae, processador e mem oria) e do sistema operacional n ao alteram a forma de uso do programa. As propriedades f sicas de um determinado material de constru ca o (telha) e os m etodos de c alculo de suas propriedades (resist encia ` a compress ao, condutividade t ermica etc.). Aqui, a telha e o objeto, as propriedades s ao seus atributos e o c alculo de suas propriedades s ao os m etodos. Para o usu ario o que interessa s ao as propriedades conhecidas, e n ao as equa co es, as vari aveis intermedi arias e a forma de c alculo, pois isto ca escondido. Para a an alise orientada a objeto, encapsulamento e o ato de esconder do usu ario informa co es que n ao s ao de seu interesse. O objeto atua como uma caixa preta, que realiza determinada opera ca o, mas o usu ario n ao sabe, e n ao precisa saber, exatamente como e feita; ou seja, o encapsulamento envolve a separa ca o dos elementos vis veis de um objeto dos invis veis. Os elementos vis veis formam a interface de acesso ao objeto. Veja a seguir um exemplo: Em um programa que calcula a area da curva normal, o c alculo interno pode ser realizado por um polin omio que aproxima a area da normal ou pela integra ca o num erica da equa ca o da normal. A decis ao de qual m etodo de c alculo ser a utilizado e realizada pelo objeto TNormal em fun ca o de um atributo interno, o limiteErro. O usu ario externo cria o objeto TNormal, informa o limite de erro e solicita o c alculo da area. O usu ario n ao sabe qual m etodo de c alculo ser a utilizado, pois isto ca escondido. A vantagem do encapsulamento surge quando ocorre a necessidade de se modicar um programa existente. Por exemplo: voc e pode modicar todas as opera co es invis veis de um objeto (os sistemas internos), para melhorar o desempenho dele, sem se preocupar com o resto do programa. Como estes m etodos n ao s ao acess veis ao resto do sistema, eles podem ser modicados sem causar efeitos colaterais. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

72

3.3. CLASSES

Segundo [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006], o encapsulamento evita que um programa se torne t ao interdependente que uma pequena modica ca o tenha um efeito de propaga ca o grave. [Pressman, 2002] lembra que os detalhes internos de implementa ca o dos dados e procedimentos s ao ocultados do mundo exterior (oculta ca o de informa ca o). Isso reduz a propaga ca o de efeitos colaterais quando ocorrem modica co es. Segundo [Parga, 2006], como conseq u encia do encapsulamento temos uma diminui ca o consider avel do n vel de acoplamento entre as classes que fazem parte do sistema. O n vel de acoplamento e avaliado pela interdepend encia entre os c odigos de duas ou mais classes, ou seja, o quanto o funcionamento de uma determinada classe e afetado por altera co es em uma outra classe que interaja com ela. O encapsulamento permite a implementa ca o de uma abstra ca o com a separa ca o clara entre a interface com o usu ario e a implementa ca o.

3.3

Classes

Quando falamos de classes, lembramo-nos de classes sociais, de classes de objetos da natureza, de hierarquias (por exemplo, a classe dos animais vertebrados). De um modo geral, uma classe descreve um grupo de objetos com os mesmos atributos e comportamentos, al em dos mesmos relacionamentos com outros objetos. Veja a seguir alguns exemplos de classes: Cachorros buldogue, pastor alem ao, vira-lata. Rel ogios de ponteiro, digital, com alarmes, com cron ometros, com calculadoras. A classe cont em a descri ca o da forma do objeto; e um molde para a cria ca o do objeto, e uma f abrica de objetos. Uma classe tamb em e um tipo denido pelo usu ario. Para a an alise orientada a objeto, uma classe e um conjunto de c odigos de programa ca o que incluem a deni ca o dos atributos e dos m etodos necess arios ` a cria ca o de um ou mais objetos. Grady Booch [Booch, 1986], diz que um objeto e uma entidade concreta que existe no tempo e no espa co, uma classe representa apenas uma abstra ca o, a ess encia do objeto. [Blaha and Rumbaugh, 2006] lembra que qualquer escolha de classe e arbitr aria e depende da aplica ca o. No exemplo da Figura 3.3 apresentamos um rel ogio e um cachorro. Podemos associar a estes dois objetos uma classe e uma classe Cachorro. Figura 3.3: Um rel oogio e um cachorro.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

3.4. ATRIBUTOS (PROPRIEDADES E VARIAVEIS)

73

3.4

Atributos (propriedades e vari aveis)

Podemos relacionar alguns atributos (propriedades) a todo objeto. No exemplo do rel ogio, podemos relacionar a hora e a data. Uma cadeira pode ser branca ou preta, ter apoio para os bra cos, ter rodinhas. Um monitor de computador pode ter 15, 17, 19 ou 21 (polegadas) e sua resolu ca o m axima em pixels pode ser 1024x768, 1280x1024, 1600x1280; ou seja, todo objeto tem seus pr oprios atributos, propriedades. Os atributos do objeto s ao utilizados para diferenciar os objetos e para identicar o estado do objeto. Na programa ca o orientada a objeto, os atributos s ao denidos na classe e armazenados de forma individual ou coletiva pelos objetos. Quando um atributo e individual (ou de inst ancia), ele e armazenado no objeto. Exemplo: A hora de um rel ogio. Cada rel ogio tem uma hora, que pode ou n~ ao estar certa. Quando um atributo e compartilhado entre todos os objetos de uma classe, ele e armazenado nela e e conhecido como atributo coletivo ou de classe. Este tipo de atributo dene uma caracter stica de toda classe. Exemplo: Um contador de rel ogios criados. Quando um atributo n ao muda nunca, ele e denominado constante. Exemplo: O n umero constante pi = 3.1415... Veremos na se ca o 6.4.2 como identicar os atributos usando AOO, e na se ca o 6.4.4, como representar os atributos usando UML. No Cap tulo 12 Atributos, veremos como implementar os conceitos de atributos em C++.

3.5

M etodos (fun c oes, opera c oes e servi cos)

Podemos relacionar determinados comportamentos, fun co es, opera co es, a co es e rea co es a um objeto. Veja a seguir alguns exemplos: Um autom ovel tem o comportamento de se locomover. Uma edica ca o tem a fun ca o de dar abrigo. Um equipamento de medi ca o e utilizado para realizar medidas. Um computador processa os programas, realizando as opera co es codicadas. Um meio poroso permite o uxo de massa. Na an alise orientada a objeto, as fun co es, opera co es e os comportamentos dos objetos s ao descritos pelos m etodos, os quais tamb em servem para manipular e alterar os atributos do objeto (alteram o estado do objeto). Em um programa orientado a objeto os est mulos s ao representados por eventos. Por exemplo: um evento ocorre quando o usu ario clica o mouse sobre o cone impressora, o qual envia uma mensagem para o objeto impressora solicitando a impress ao do arquivo selecionado. O m etodo Imprimir() recebe o nome do arquivo a ser impresso, realiza a impress ao do mesmo Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

74

3.6. HERANCA

e ent ao retorna um ag indicando que a opera ca o de impress ao terminou com sucesso ou falhou. Observe que o objeto impressora e representado na tela por seu cone. Na maioria dos programas, um item de menu e usado para acessar um di alogo com propriedades do objeto impressora. Podemos dizer que um m etodo e uma opera ca o realizada sobre um objeto e e descrito por uma classe. Um m etodo e a implementa ca o de uma opera ca o. S ao elementos de um m etodo: Retorno todo m etodo retorna um objeto ap os sua execu ca o. Nome o nome de um m etodo deve identicar com clareza o que ele faz. Par ametros s ao as vari aveis e objetos passados para o m etodo para realiza ca o de suas tarefas. Veremos na se ca o 6.4.3 como identicar os m etodos usando AOO, e na se ca o 6.4.4, como representar os m etodos usando UML. No Cap tulo 13 M etodos, veremos como implementar os m etodos em C++. Veremos tamb em, na se ca o 3.6, que, numa hierarquia de classes, m etodos com a mesma assinatura podem apresentar comportamento polim orco. Observe ainda que todos os objetos criados a partir de uma mesma classe-base compartilham os m etodos da classe.

3.6

Heran ca

A heran ca est a relacionada ` as hierarquias e ` as rela co es entre os objetos. No dia-a-dia, quando se fala de heran ca, refere-se ` a transfer encia de propriedades de um pai aos seus lhos, ou seja, aquilo que e do pai passa a ser do lho. comum ainda o dito popular puxou o pai, que signica que o lho tem as mesmas E caracter sticas do pai. De uma maneira geral, as pessoas sabem que o lho assemelha-se ao pai, mas n ao s ao a mesma pessoa. Al em disso, o lho apresenta determinadas caracter sticas diferentes de seu pai. Veja a seguir outros exemplos: Um processador Pentium IV tem preservadas todas as caracter sticas do Pentium III, mas acrescentou mais mem oria cache (a mem oria cache j a existia, mas foi ampliada). Alguns modelos apresentam a tecnologia de Hyper-Threading que antes n ao existia. Uma placa-m ae nova apresenta a interface USB; trata-se de uma novidade que antes tamb em n ao existia. Na an alise orientada a objeto, heran ca e o mecanismo em que uma classe-lha herda automaticamente todos os atributos e m etodos de sua classe-pai (classe-base). Heran ca e a propriedade de podermos criar classes que se ampliam a partir de deni co es b asicas. De classes mais simples e gen ericas para classes mais complexas e espec cas. A heran ca permite criar classes-lhas implementando apenas os m etodos e atributos que se diferenciam da classe-pai. A maior vantagem do uso do conceito de heran ca est a associada ` a compreens ao de que os objetos que fazem parte da heran ca t em o mesmo comportamento, possibilitando um maior reaproveitamento de c odigo com conseq uente aumento da seguran ca. Existem dois tipos de heran ca: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

3.7. POLIMORFISMO

75

Heran ca simples ocorre quando uma classe herda as propriedades de uma u nica classe-pai. Heran ca m ultipla1 ocorre quando uma classe tem mais de um pai. Exemplo: heran ca de comportamento; muitas vezes dizemos que um menino herdou o jeito engra cado do tio e e estudioso como o pai, ou seja, o menino herdou caracter sticas comportamentais de mais de uma pessoa. Antecipando um pouco nosso estudo, veja na Figura 3.4 como representamos pela UML o conceito de heran ca. Observe que evolu mos de um rel ogio que s o tem hora para um rel ogio com hora e data. A seguir temos um rel ogio com hora, data e cron ometro. O nosso modelo mais moderno tem embutido uma calculadora. Observe que temos heran ca-m ultipla, uma vez que o rel ogio com calculadora e uma mistura de um rel ogio com uma calculadora. Figura 3.4: Uma hierarquia de rel ogios.
Relogio
+hora: int

Calculadora

RelogioData RelogioCalculadora
+hora: int +data: int +hora: int +data: int +tempoCronometro +calculadora: void

RelogioDataCronometro
+hora: int +data: int +tempoCronometro

Na Figura 6.12 a classe-base e Rel ogio. Esta possui um atributo, a hora, e dois m etodos usados para ler a Hora() ou acertar a Hora(int horaCerta). A classe Rel ogioAlarme e herdeira de Rel ogio, recebendo automaticamente os atributos e m etodos denidos em Rel ogio. Ademais, esta acrescenta o atributo horaAlarme, alarmeAtivo e os m etodos para ler e denir a hora em que o alarme deve tocar. Veremos na se ca o 6.4.10 como identicar heran cas usando AOO, e, na se ca o 6.4.11, como representar heran cas usando UML. No Cap tulo 17 Heran ca, veremos como implementar heran cas em C++, e no Cap tulo 18 Heran ca M ultipla, como implementar heran ca m ultipla. Nota: os termos classe-pai e classe-base s ao sin onimos. O termo superclasse indica a classe mais b asica de uma hierarquia. J a o termo classe-lha e sin onimo de classe-derivada.

3.7

Polimorsmo

A palavra polimorsmo signica muitas formas e representa o fato de uma determinada caracter stica (por exemplo, a pot encia do motor do ve culo) ser diferente para cada lho (tipo de ve culo). Quem j a andou de Volks e de Mercedes sabe bem a diferen ca.
1A

heran ca m ultipla e utilizada em C++ (n ao sendo dispon vel em Java).

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

76

3.8. OUTROS CONCEITOS UTEIS

Na natureza, o conceito de polimorsmo e inerente ao processo de desenvolvimento; os seres evoluem, modicam-se. Por exemplo: o homo-sapiens e uma evolu ca o de seus ancestrais e tem atributos melhorados e atributos novos. Em suma, estamos partindo de um objeto mais simples e evoluindo, mas os conceitos do objeto-pai continuam a existir nos objetos descendentes, mesmo que tenham sofrido modica co es, aperfei coamentos e tenham assumido novas formas (polimorsmo). Para a AOO, polimorsmo e o processo de redeni ca o dos m etodos nas classes-derivadas. Os m etodos da classe-base s ao reescritos para realizarem as mesmas tarefas de uma forma mais especializada. O conceito de polimorsmo e fundamental para a an alise orientada a objeto; sua aplica ca o se fundamenta no uso de uma superclasse, por meio da qual vamos desenvolver nossa hierarquia de classes. Por exemplo: em um programa de simula ca o num erica utilizado para calcular a area de uma fun ca o, pode-se ter a evolu ca o dos m etodos de integra ca o. Do m etodo do Trap ezio para o m etodo de Simpson, para o m etodo de Gauss. O m etodo de Simpson e uma evolu ca o do m etodo do Trap ezio; seu algoritmo de c alculo e um pouco mais complexo, mais especializado, e apresenta resultados mais precisos. No Cap tulo 19 Polimorsmo, veremos como implementar o polimorsmo em C++.

3.8

Outros conceitos u teis

Apresenta-se aqui, brevemente, outros conceitos relacionados ` a programa ca o orientada a objeto. Ao longo do livro estes conceitos ser ao reapresentados e detalhados com exemplos. Todos estes conceitos s ao suportados por C++, alguns deles s ao suportados por Java. Associado ao conceito de objeto temos os conceitos de inst ancia, identidade, persist encia e delega ca o: Inst ancia um outro nome que se d E a ao objeto e que, geralmente, refere-se a um objeto espec co. Identidade uma propriedade que permite identicar univocamente um objeto. Os objetos se distinE guem por sua pr opria exist encia, sendo distintos mesmo que todos os seus atributos sejam iguais, ou seja, existe um u nico identicador para cada objeto. Em C++ o endere co do objeto e seu identicador. Persist encia o tempo de vida de um objeto, podendo ser tempor E ario ou permanente: tempor ario quando ele s o existe durante a execu ca o do programa. Por exemplo: um objeto pode ser criado com new e destru do com delete; permanente quando ele e armazenado em um meio f sico, como o disco r gido. A vantagem dos objetos permanentes (persistentes) e que eles podem ser acessados por mais de um programa, pelo mesmo programa em uma outra ocasi ao, ou como um dep osito de dados (banco de dados). Delega c ao o mecanismo pelo qual um objeto transfere a execu E ca o de uma tarefa para outro. Veja a seguir outros conceitos relacionados ` a id eia de classe: Tipica c ao As classes representam os tipos de dados denidos pelo usu ario. A tipica ca o e a capacidade de o sistema distinguir as diferentes classes e resolver as convers oes. Veremos os Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

3.8. OUTROS CONCEITOS UTEIS

77

conceitos de tipos em C++ no Cap tulo 9 Tipos. Os conceitos de convers oes ser ao vistos no Cap tulo 25 Convers oes. Classica c ao Os objetos com a mesma estrutura de dados e com os mesmos m etodos s ao agrupados em uma classe. Todo objeto cont em uma refer encia impl cita ` a sua classe e sabe a qual classe pertence (identidade). Classes abstratas Uma classe e abstrata quando n ao e completa e n ao pode criar objetos, podendo surgir naturalmente ou pela migra ca o de m etodos das classes-derivadas para uma classe-base (gen erica). Uma classe abstrata costuma ser uma classe de interface. Veremos os conceitos de classes no Cap tulo 11 Classe. Protocolo o conjunto de m E etodos p ublicos da classe que podem ser acessados pelo usu ario, o conjunto de mensagens a que o objeto responde. O protocolo pode ser denido por uma classe de interface. Classes de interface Interfaces s ao classes abstratas que cont em apenas m etodos puros (n ao podem criar objetos). S ao utilizadas para mostrar ao usu ario a forma de acesso aos objetos. Veremos as classes de interface na se ca o 11.5.2. Responsabilidades Pode-se incluir na descri ca o da classe as suas responsabilidades pequenas frases que descrevem as obriga co es do objeto. Tamb em podemos incluir a descri ca o das colabora co es (veja na se ca o 6.10.2 o uso dos cart oes CRC Classe/Responsabilidade/Colaboradores). Veja a seguir informa co es adicionais sobre heran cas: Nomes de classe Em uma fam lia, os lhos e netos compartilham os nomes de seus ancestrais; da mesma forma, em uma hierarquia de classes, os nomes devem ser signicativos, semelhantes e esclarecedores. Superclasse Uma superclasse e a classe-base de uma hierarquia de classes; e a classe mais alta na hierarquia ( e a origem da arvore). Veremos como implementar heran ca em C++ no Cap tulo 17 Heran ca. Compartilhamento As t ecnicas orientadas a objeto facilitam o compartilhamento de c odigo por meio do conceito de heran ca. Al em do maior compartilhamento do c odigo, a an alise orientada a objeto reduz a codica ca o em fun ca o da maior clareza dos diagramas desenvolvidos. Veja a seguir informa co es adicionais sobre m etodos: Assinatura A assinatura de um m etodo e seu nome, a ordem e o tipo de seus par ametros. Observe que o tipo de retorno n ao faz parte da assinatura. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

78

3.8. OUTROS CONCEITOS UTEIS

Liga c ao est atica/din amica Liga ca o e o processo de identicar a posi ca o dos m etodos a serem executados. Na liga ca o est atica, o endere co dos m etodos e denido durante a compila ca o do programa. Na liga ca o din amica, o endere co dos m etodos e denido somente durante a execu ca o do programa. Sobrecarga de m etodos: O conceito de sobrecarga de um m etodo esta associado a preserva ca o do nome do m etodo, mesmo que este receba tipos ou n umero de par ametros diferentes. Por exemplo, um m etodo Soma() poderia realizar a soma de n umeros inteiros ou utuantes, sem a necessidade de se criar SomaInt() e SomaFloat(). Com o conceito de sobrecarga o programador tem de aprender a usar um n umero menor de m etodos, tendo um aumento de seu desempenho (veremos no Cap tulo 14 - Sobrecarga de M etodos, como implementar sobrecarga de m etodos). Sobrecarga de operador Algumas linguagens de programa ca o permitem a sobrecarga dos operadores, isto e, um operador + (soma) poderia ser reescrito para os diferentes tipos de objetos criados. Por exemplo: o programador pode denir um operador + que vai atuar sobre n umeros complexos. Veremos como implementar sobrecarga de operador em C++ no Cap tulo 21 Sobrecarga de operador. Cancelamento a substitui E ca o de um m etodo da classe-base por outro na classe-derivada. Pode ocorrer com os seguintes objetivos: cancelamento para extens ao (amplia ca o das tarefas que eram realizadas), cancelamento para restri ca o (quando a tarefa n ao e mais necess aria), cancelamento para otimiza ca o (quando se deseja aumentar o desempenho), cancelamento por conveni encia (quando o cancelamento pode ser conveniente por um motivo qualquer; deve ser evitado pois os m etodos n ao devem ser substitu dos com a nalidade de terem um comportamento diferente do esperado). Veja a seguir outros conceitos u teis: Friend (ou amizade) Um desconhecido n ao tem acesso ` a sua casa, aos seus bens pessoais. Um amigo pode entrar na sua casa e fazer uso de alguns objetos. A programa ca o orientada a objeto funciona da mesma forma. Voc e pode criar objetos diferentes e informar que um objeto A e amigo do objeto B, podendo acessar determinadas funcionalidades de B. Veremos a implementa ca o do conceito de amizade no Cap tulo 20 Friend. Ponteiros Em C/C++, um ponteiro e um objeto pequeno que aponta para outro objeto (que pode ser grande). Ponteiros s ao muito utilizados em C/C++ e ser ao vistos em detalhes no Cap tulo 15 Ponteiros, Refer encias e Gerenciamento de Mem oriae no Ap endice F Uso Avan cado de Ponteiros. Refer encias C++ acrescentou o conceito de refer encias, um tipo de apelido que substitui em grande parte o uso de ponteiros (veja como usar refer encias em C++ no Cap tulo 15 Ponteiros e refer encias). Convers oes Em um programa real e comum a necessidade de se converter um objeto de um tipo para Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

3.9. RESUMO DO CAP ITULO

79

outro. Por exemplo: um determinado m etodo espera receber como par ametro um n umero utuante, mas o programador passou um n umero inteiro. Neste caso, o n umero inteiro vai ser convertido para utuante. Veremos como implementar convers oes em C++ no Cap tulo 25 Convers oes. Templates O conceito de template est a associado ao uso de programa c ao gen erica, a qual e extensivamente utilizada na STL Standard Template Library. Veja os conceitos de templates no Cap tulo 27 Templates (ou Gabaritos). A STL ser a vista a partir do Cap tulo 31 Introdu ca o ` a Biblioteca Padr ao de Gabaritos de C++ (STL). Exce co es O problema de erros em programas e sua solu ca o sempre foi complicado. O uso cada vez mais intenso de interfaces elaboradas e a necessidade de se terminar o projeto em tempo limitado provocam a ocorr encia de um n umero cada vez maior de erros em programas. Veremos como implementar solu co es para tratamento de erros utilizando os conceitos de exce co es no Cap tulo 26 Exce co es. Modularidade Um programa pode ser desenvolvido utilizando-se m odulos que podem ser compilados separadamente. Um m odulo costuma ser constru do a partir de um conjunto de classes relacionadas (geralmente um assunto). Em C++ os assuntos s ao empacotados com o uso da palavra-chave namespace; tamb em e usual separar a deni ca o das classes de sua implementa ca o (arquivos .h e .cpp). Pacotes Um pacote e um conjunto de classes mais fortemente relacionadas entre s . Costumam fazer parte do mesmo assunto. Evento Um evento pode ser um est mulo provocado por um sistema externo ou interno. Um evento provoca a mudan ca do estado de um objeto, representa uma a ca o que ocorre em determinado tempo e tem dura ca o zero. Atividade Uma atividade e uma opera ca o que demora um determinado tempo para ser executada. Sinergia Os conceitos da an alise orientada a objeto apresentam um efeito de sinergia (soma de qualidades), em que a soma dos diversos conceitos da AOO implicam em um resultado mais positivo que o esperado.

3.9

Resumo do cap tulo

Neste cap tulo aprendemos alguns conceitos b asicos de OO, como a id eia da abstra ca o, que consiste em simplicar os sistemas eliminando detalhes, ou ent ao o conceito de encapsulamento ou ocultamento da informa ca o cujo objetivo e simplicar o objeto, permitindo ao usu ario ver apenas o que ser a efetivamente utilizado. Vimos ainda exemplos reais e imagin arios de classes e objetos, com suas propriedades e funcionalidades. Relembramos o conceito de heran ca e tivemos uma id eia do conceito de polimorsmo. No nal do cap tulo vimos um conjunto de conceitos que ser ao melhor descritos ao longo do livro. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

80

3.10. EXERC ICIOS

Apresentaremos, no Cap tulo 4 Modelagem Orientada a Objeto, o que e um modelo e porque usamos modelos, o que e a UML e quais seus diagramas. Veremos no Cap tulo 5 Engenharia de Software, o que e, quais as caracter sticas e alguns modelos conhecidos de engenharia de software. No Cap tulo 6 Etapas para o Desenvolvimento de um Programa, ser a apresentada em detalhes uma metodologia para desenvolvimento de programas orientados a objeto usando os diagramas da UML.

3.10

Exerc cios

1. Descreva, com suas palavras, os conceitos de: abstra ca o, classe, heran ca, atributos e m etodos. 2. Fale das vantagens de se usar o conceito de encapsulamento. 3. Descreva, de forma objetiva, as diferen cas entre classe, objeto e heran ca. 4. Descreva o que os objetos em cada uma das listas abaixo t em em comum (caracter sticas e a co es em comum). prateleira, estante, arm ario; moto-serra, faca, tesoura, estilete, machado; prego, parafuso, pino rebite; carro, caminh ao, trator, motocicleta; televis ao, monitor, display de c amera digital, display de lmadora. 5. Nas aplica co es a seguir s ao utilizadas estruturas de suporte. Para cada uma delas, fa ca uma lista de caracter sticas que sejam importantes e explique a import ancia de cada caracter stica para a aplica ca o. Estrutura met alica de um edif cio. Estrutura met alica de um avi ao. Estrutura met alica de uma plataforma de petr oleo. 6. Descreva as principais caracter sticas do paradigma de orienta ca o a objeto. 7. Fa ca uma r apida revis ao dos termos descritos neste cap tulo. Observe que s ao termos conhecidos, que voc e provavelmente j a utilizou, ou seja, a orienta ca o a objetos usa termos e conceitos conhecidos, facilitando seu entendimento e uso. 8. Porque devemos usar o conceito de abstra ca o sempre que temos de tratar um problema complexo?

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 4

Modelagem Orientada a Objeto


Neste cap tulo apresentaremos uma introdu ca o ` a modelagem (se ca o 4.1): o que e um modelo (se ca o 4.1.1), porque usamos modelos para representar a realidade (se ca o 4.1.3), e quais s ao os tipos de modelos (se ca o 4.1.2). Em seguida veremos uma introdu ca o ` a modelagem orientada a objeto (se ca o 4.2): o que ea modelagem que tem como foco principal o conceito de objeto (se ca o 4.2.1), quando a modelagem orientada a objeto surgiu (se ca o 4.2.2) e quais suas vantagens (se ca o 4.2.3). Veremos tamb em o que e a UML Linguagem de Modelagem Unicada (se ca o 4.3), suas diferentes vis oes (se ca o 4.3.1), seus diagramas (se c ao 4.3.1), seus elementos (se ca o 4.3.2) e seus estere otipos (se ca o 4.3.3). No nal do cap tulo veremos alguns softwares utilizados para modelagem orientada a objeto (se ca o 4.4), como os softwares dia (se ca o 4.4.1), umbrello (se ca o 4.4.2), e Visual-Paradigm VP (se ca o 4.4.3).

4.1

Introdu c ao ` a modelagem

Apresenta-se nesta se ca o o que e um modelo, tipos e exemplos e a raz ao pela qual usamos modelos.

4.1.1

O que e um modelo?

Um modelo e uma representa ca o da realidade; e uma liga ca o, uma ponte entre conceitos te oricos e observa co es [Aris, 1978]. O desenvolvimento de um modelo envolve o uso do conceito de abstra ca o, a vis ao do todo e de suas partes. Adaptando [Bender, 1978], podemos dizer que no desenvolvimento de um modelo devemos: i) formular as id eias precisamente [com clareza]; ii) ser concisos no uso da linguagem; e iii) identicar bibliotecas e sistemas dispon veis. Segundo [Bender, 1978], A teoria e util para obter conclus oes gerais dos modelos simples. Computadores s ao u teis para obter conclus oes espec cas de modelos mais complexos. Alguns modelos s ao focados em aspectos estruturais, como um projeto das funda co es e da estrutura de um edif cio. Outros modelos s ao focados na din amica e no comportamento do sistema, como, por exemplo, um modelo da din amica de um sistema de comportas 81

82

A ` MODELAGEM 4.1. INTRODUC AO (canal do Panam a), ou do funcionamento de um motor de combust ao. O uso de diferentes modelos estruturais/comportamentais nos permite ver os sistemas de diferentes formas; cada modelo, cada ator, fornece-nos vis ao/detalhamento de uma parte do sistema, [Sonerviile, 1993].

4.1.2

Tipos e exemplos de modelos

Veja a seguir alguns exemplos de modelos utilizados pelo homem. Colocamos uma classica ca o n ao-rigorosa indicando ser um modelo estrutural/din amico: Modelos estruturais Maquetes (maquete de uma casa, de um autom ovel). Mapas (mapa das ruas de uma cidade). Projetos (projeto de uma casa). Modelos matem aticos (equa co es diferenciais, fun co es, exemplo: y = f(x) = a + b.x ). Modelos multiescala (miniaturas, modelos reduzidos). Modelos din amicos Modelos f sicos/qu micos/biol ogicos (exemplo: a equa ca o do movimento retil neo uniforme). Modelos num ericos (exemplo: m etodo de integra ca o por Simpson). Algor tmos/uxogramas (s ao diagramas utilizados para representar a din amica de determinado sistema). Nota: de modo geral, um modelo matem atico M1 pode ser utilizado em diferentes areas, como a F sica, a Qu mica, a Biologia. Isto e, um mesmo conjunto de equa co es podem ser utilizadas para representar diferentes problemas [Aris, 1978, Bender, 1978].

4.1.3

Por que usamos modelos?

O problema da linguagem, a necessidade de linguagens universais A engenharia civil utiliza com freq u encia modelos simplicados da realidade, como, por exemplo, plantas de edif cios e casas. As plantas s ao utilizadas por permitirem o entendimento de como a obra deve car depois de pronta; e o modelo utilizado pelo engenheiro (ou arquiteto) para se comunicar com o propriet ario, bem como com o mestre de obra. Assim, a planta viabiliza a troca de informa co es entre todos os envolvidos no projeto. Veja na Figura 4.1 tr es tipos de plantas usadas pelos engenheiros: uma fachada, uma planta baixa e uma planta isom etrica. Cada uma destas plantas procura destacar determinadas caracter sticas da casa. A fachada tem como objetivo mostrar como car a a frente da casa; a planta baixa, a disposi ca o dos ambientes da casa; a planta isom etrica, como ser ao dispostos os encanamentos de um banheiro. As plantas utilizadas pelo engenheiro/arquiteto t em como objetivo mostrar a estrutura e o funcionamento da casa e s ao utilizadas universalmente. Um engenheiro brasileiro, por exemplo, pode utilizar uma planta feita por um arquiteto russo para construir a casa de um indiano na China. Com rela ca o ao desenvolvimento de software, o uso de uma linguagem universal, como a UML e como a C++, facilita a troca de informa co es e c odigos entre os desenvolvedores. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A ` MODELAGEM 4.1. INTRODUC AO

83

Figura 4.1: Modelos da realidade a planta de uma casa.


pia chuveiro

X
vaso

Banheiro Quarto Quarto

Planta isometrica do banheiro

Cozinha Sala

Varanda

Fachada

Planta Baixa

(a) Fachada

(b) Planta Baixa

O problema do custo Usamos modelos para reduzir custos. Antigamente, um carro novo era desenvolvido utilizandose prot otipos em tamanho real, a um custo muito elevado e com poucas varia co es e testes. Na pr atica, boa parte dos testes era feita pelos pr oprios propriet arios. Atualmente, um carro e feito valendo-se de modelos de computador, em um programa CAD, reduzindo consideravelmente o custo do desenvolvimento de novos modelos. Os modelos do carro s ao testados em simuladores. O problema da escala (conceito de escala) A maquete de uma casa e um modelo reduzido da casa, em uma outra escala. A vantagem do uso de modelos em escalas reduzidas e seu baixo custo. Por exemplo: o teste da performance aerodin amica de um carro, como um f ormula 1, e normalmente feito em um tunel de vento com modelos reduzidos. Com rela ca o ao desenvolvimento de um software, a quest ao da escala est a associada ao crescimento do software. A cada vers ao novos recursos s ao adicionados, e o uso de modelos permite a previs ao antecipada do crescimento do software. Nota: quando um modelo n ao muda ao modicarmos a escala do problema, dizemos que o mesmo e invari avel com rela ca o ` a escala [Aris, 1978]. Outras vantagens do uso de modelos Maior facilidade para testar uma entidade f sica antes de lhe dar uma forma nal. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

84

A ` MODELAGEM ORIENTADA A OBJETO 4.2. INTRODUC AO Maior facilidade na comunica ca o entre as diversas pessoas envolvidas (pela utiliza ca o de nota ca o uniforme). Redu ca o da complexidade dos sistemas. Possibilidade de testar o sistema em escalas reduzidas.

4.2

Introdu c ao ` a modelagem orientada a objeto

Agora que voc e j a sabe a import ancia dos modelos, vamos apresentar uma introdu ca o ` a modelagem orientada a objeto: o que e, quando surgiu e quais s ao suas vantagens.

4.2.1

O que e a modelagem orientada a objeto?

Reveja a imagem da Figura 3.2; a vis ao do usu ario e diferente da vis ao do engenheiro. Da mesma forma, a vis ao de cada um dos participantes de um grupo de desenvolvimento de software e diferente. Para que nossa linguagem de comunica ca o seja uniformizada, precisamos utilizar a mesma base de informa co es, os mesmos conceitos. Paradigmas de programa ca o tradicionais, como o paradigma de programa ca o estruturada, ensinam-nos uma nova linguagem (centenas de conceitos novos e seus relacionamentos). Todos os programadores devem entender e utilizar esta nova linguagem. Contudo, a modelagem orientada a objeto elimina a necessidade de se aprender uma nova linguagem, pois a mesma e baseada em conceitos que j a conhecemos os objetos e seus relacionamentos. Isto ocorre porque, na modelagem orientada a objeto, os modelos da realidade s ao desenvolvidos tendo como fonte de inspira ca o os objetos. Segundo [Sonerviile, 1993], a modelagem orientada a objeto e baseada na oculta ca o de informa co es, nos objetos e seus relacionamentos. A modelagem orientada a objeto e os diagramas da UML Linguagem de Modelagem Unicada s ao criados e utilizados para permitir a todos os programadores uma vis ao uniforme do sistema que vai ser desenvolvido (da mesma forma que o projeto de uma casa). A modelagem orientada a objeto e um instrumento fundamental para o desenvolvimento de programas com qualidade.

4.2.2

Quando surgiu a modelagem orientada a objeto?

Segundo [Fowler and Scott, 2000], os m etodos de an alise e projeto orientado a objetos surgiram entre 1988 e 1992, destacando-se: i) o enfoque em projetos recursivos de Sally Shlaer e Steve Mellor; ii) os trabalhos de Coad e Yourdan, [Coad and Yourdon, 1993]; iii) os cart oes CRC de Beck e Cunningham (1989); iv) as t ecnicas de Booch, [Booch, 1986]; v) o m etodo TMO - T ecnica de Modelagem de Objetos, de [Rumbaugh et al., 1994]; e vi) os casos de uso de Ivar Jacobson. No in cio existiam v arios m etodos de modelagem orientada a objeto, e uma disputa para ver qual seria o padr ao. Em 1997, o grupo de gerenciamento de objetos, conhecido como OMG Object Management Group, adotou a UML como linguagem-padr ao, o que provocou um impulso na aceita ca o da UML. Em outras palavras, a UML foi desenvolvida para unicar a nota ca o utilizada no desenvolvimento de softwares orientados a objeto. Hoje em dia a UML e utilizada universalmente para modelagem de software orientado a objeto, bem como para modelagem de sistemas em geral; ou seja, voc e pode usar UML para fazer seus softwares ou para auxiliar no desenvolvimento de projetos de engenharia. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A UML? 4.3. O QUE E

85

4.2.3

Quais as vantagens da modelagem orientada a objeto?

Segundo [Pressman, 2002], a modelagem orientada a objeto apresenta algumas vantagens inerentes: Reuso de componentes do programa. Desenvolvimento mais r apido e com melhor qualidade. Facilidade de manuten ca o, adapta ca o e amplia ca o. Veremos a seguir o que e a UML, suas vis oes, seus diagramas, elementos e estere otipos.

4.3

O que e a UML?

A UML e o padr ao utilizado para o desenvolvimento de modelos de software orientados a objeto. Como foi desenvolvida depois da TMO com a participa ca o de Rumbaugh, alguns diagramas utilizados na TMO foram preservados (mas ocorreram algumas altera co es). A UML estendeu a TMO acrescentando novas funcionalidades e novos diagramas, destacando-se os casos de uso. A TMO e descrita brevemente na se ca o 5.3.7. Segundo [Fowler and Scott, 2000], o c odigo e o meio preciso e detalhado, e a linguagem natural e muito imprecisa; UML seria ent ao o meio termo. A UML e uma linguagem visual que usa a id eia uma imagem vale mais do que mil palavras. A UML e uma linguagem de modelagem independente de processo. A UML e din amica; inova co es e ajustes s ao acrescentados a cada nova vers ao. A UML e o padr ao da ind ustria para modelagem de software orientado a objeto. A UML e extens vel, podendo ser adaptada ` as suas necessidades.

4.3.1

As diferentes vis oes da UML e os respectivos diagramas

A seguir s ao apresentadas as diferentes vis oes da UML e os respectivos diagramas: Vis ao do modelo do usu ario mostra a vis ao do usu ario do sistema, sendo descrita principalmente pelos casos de uso. Diagrama de caso de uso (veja se ca o 6.1.2). Vis ao do modelo estrutural mostra a estrutura do sistema (equivale ao modelo de objetos do m etodo TMO). Diagrama de pacotes (veja se ca o 6.2.3). Diagrama de classes, atributos, m etodos (veja se ca o 6.4.4), associa co es (veja se ca o 6.4.6), agrega co es (veja se ca o 6.4.9), heran cas (veja se ca o 6.4.11), e depend encias (veja se ca o 6.4.15). Diagrama de objetos (veja se ca o 6.4.17). Diagrama de estrutura composta (veja se ca o 6.4.18). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

86

A UML? 4.3. O QUE E Vis ao do modelo din amico mostra a din amica e o comportamento do sistema, sua intera ca o com o usu ario e com sistemas externos (equivale ao modelo din amico e funcional do m etodo TMO).

Diagrama de seq u encia (eventos e mensagens) (veja se ca o 6.5.2). Diagrama de comunica ca o/colabora ca o (veja se ca o 6.5.3). Diagrama de m aquina de estado (estados do objeto) (veja se ca o 6.5.5). Diagrama de atividades (detalha as fun co es/m etodos) (veja se ca o 6.5.7). Diagrama de tempo (veja se ca o 6.5.8).

Vis ao de implementa c ao mostra aspectos estruturais do sistema relacionados ` as necessidades de implementa ca o (equivale em parte ao projeto do sistema do m etodo TMO).

Diagrama de componentes (veja se ca o 6.7.1).

Vis ao do modelo de ambiente mostra o ambiente-alvo e as necessidades para se colocar o sistema em funcionamento.

Diagrama de implanta ca o (veja se ca o 6.7.2).

Veja na Figura 4.2 o relacionamento dos diagramas estruturais da UML. No exemplo apresentamos um sistema para simula ca o de um reservat orio de petr oleo ou de um po co. O diagrama de pacotes e o mais geral e representa todo o sistema. O diagrama de componentes inclui dentro dele os componentes do sistema (sub-sistemas, bibliotecas e m odulos). No exemplo inclu mos um componente biblioteca de simula ca o. O diagrama de classes mostra as classes, seus atributos, m etodos e o relacionamento entre as classes. Por m, a estrutura interna de uma classe pode ser representada em um diagrama de estrutura composta (inclu mos o diagrama de estrutura composta da classe SimPoco). Observe que estamos partindo do geral e descendo para o espec co, de uma vis ao macroestrutural, para uma vis ao microestrutural. Da mesma forma, a din amica do sistema tamb em e representada por diferentes diagramas (veja Figura 4.3). O caso de uso representa a vis ao mais simples da din amica do sistema, a vis ao do usu ario. Os diagramas de seq u encia e de comunica ca o ilustram a intera ca o entre os pacotes, os m odulos e os objetos. Observe no diagrama de comunica c ao que o usu ario cria um simulador, seleciona uma fun ca o e um objeto de integra ca o e em seguida solicita o c alculo da area da fun ca o a ser realizado pelo objeto de integra ca o (veja Figura 6.17 e 6.19). O diagrama de m aquina de estado (veja Figura 6.20) ilustra os estados de um objeto. Na Figura 6.20, o objeto integral est a recebendo a fun ca o, recebendo dados e calculando a integral. O diagrama de atividades, por sua vez, detalha o funcionamento de um m etodo, a descri ca o de uma atividade espec ca. A Figura 4.3 mostra o diagrama de atividades para o m etodo do Trap ezio, respons avel pelo c alculo da area de uma fun ca o (veja exemplo mais detalhado na Figura 6.25). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A UML? 4.3. O QUE E


<<estrutura>> Diagrama de pacotes <<bibliotecas>> <<Banco de dados>> <<estrutura>> Diagrama de componentes

87

Biblioteca matemtica

Biblioteca estatstica <<Executveis>>

Biblioteca Simulao

<<estrutura>> Diagrama de classes

Simulador

SimReservatorio

SimPoco

<<estrutura>> Diagrama de estrutura composta

funcao: TFuncao integral: IntTrapezio

Simulao

Figura 4.2: Relacionamento dos diagramas estruturais da UML.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

88

A UML? 4.3. O QUE E


<<dinmica>> Diagrama de casos de uso

<<dinmica>> Diagrama de comunicao

Calcular rea funo

Ator funo

Ator simulador integral

<<dinmica>> Diagrama de mquina de estado

recebendo funo

recebendo dados

calculando integral (rea)

<<dinmica>> Diagrama de atividades enquanto x<xmax x=x+dx y=f(x) Area=Area+y.dx

faz x=xmin, Area=f(x).dx/2 x>xmax

Area=Area+f(x).dx/2

Figura 4.3: Relacionamento dos diagramas din amicos da UML.

4.3.2

Os elementos da UML

Veja na Figura 4.4 um esbo co dos elementos da UML e observe que a UML tem um conjunto de elementos, como classe (ativa, inativa), gabarito/template, interface, pacote, componente, estado, nota, etiqueta, restri ca o, depend encia, associa ca o, generaliza ca o, agrega ca o/composi ca o, realiza ca o, colabora ca o, intera ca o, estere otipos etc. Veja na Figura 4.5 outros elementos utilizados pela UML, cujos elementos ser ao explicados em detalhes no Cap tulo 6 Etapas para o Desenvolvimento de um Programa. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A UML? 4.3. O QUE E

89

Componentes UML do programa dia dependncia

Classe

Classe
nota

generalizao {restrio} agregao

associao

realizao

pequeno pacote pacote caso de uso observao tempo vida

implementao objeto mensagem receptculo Fonte de evento dissipador de evento atividade estado Componente

note

Ator

incio

fim

ramo bifurcao

esteretipo

Figura 4.4: Elementos da UML.

Figura 4.5: Outros elementos da UML.


Notao UML para associaes, agregao, composio, generalizao, implementao, observao e receptculo, fonte e dissipador de eventos, restrio, dependncia, interface. papel de B nb associao papel de A na agregao papel de A na composio papel de A na papel de B nb papel de B nb <<esteretipo>> implementao interface simples Receptculo enviar/send Observao Dissipador de Evento Fonte de Evento retorno recursiva Tipos de mensagens <<create>> {restrio} <<esteretipo>> generalizao <<esteretipo>> dependncia chamada <<destroy>>

cone de classe. controle limite entidade um ramo

4.3.3

Os estere otipos da UML2

Lembre-se que esta e uma se ca o de n vel 2 e s o deve ser lida em uma segunda leitura do livro ou por usu arios experientes. Os estere otipos s ao apresentados nos diagramas da UML dentro de < <> > e s ao utilizados para estender as funcionalidades da UML ou para indicar alguma propriedade de um elemento da UML. Veja a seguir alguns exemplos de estere otipos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

90 Estere otipos para classes: persistente A classe e armazenada em disco ou em uma base de dados.

A UML? 4.3. O QUE E

entity Representa uma classe que tem forte intera ca o com o sistema, recebendo e fornecendo dados [entidade]. boundary Representa uma classe de contorno, utilizada para intera ca o do sistema com elementos externos. Por exemplo, a classe que faz o acesso ` a impressora [contorno]. control Classe utilizada para controle de alguma atividade. Muitas vezes e utilizada uma classe < <control> > entre uma classe < <boundary> > e o sistema [controle]. interface Indica uma classe abstrata que tem apenas m etodos puros. A UML inclui cones especiais para indicar interfaces. bind Especica os tipos utilizados em uma especializa ca o. friend A classe-fonte tem acesso ` a classe-alvo [amigo]. instanceOf Indica uma inst ancia do alvo (usado em rela co es entre classes e objetos) [inst ancia de]. instantiate A classe-fonte cria objetos da classe-alvo. rene Indica ser mais detalhado/renado [rena]. use Indica depend encias de uso [uso]. become Indica ser o mesmo objeto mas com rela co es diferentes (em um estado diferente). call O fonte chama o alvo [chama]. copy Indica ser uma c opia independente [copia]. acess Indica acesso [acesso]. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A UML? 4.3. O QUE E Estere otipos para atributos: const O atributo e constante, n ao muda. crescente O atributo e um valor crescente. decrescente O atributo e um valor decrescente. Estere otipos para m etodos: const O m etodo n ao altera os atributos do objeto [constante]. sequencial O m etodo n ao aceita acesso concorrente; o acesso deve ser seq uencial. concorrente O m etodo aceita acesso concorrente (processamento paralelo).

91

guarded O acesso concorrente e permitido, e o controle do acesso aos atributos internos e controlado pelo pr oprio objeto. alt Indica uma alternativa; e usado em estruturas de controle [alternativa]. opt Indica item opcional [opcional]. loop Indica um looping [la co]. Estere otipos para mensagens: create A mensagem solicita a cria ca o de um objeto [criar]. destroe A mensagem solicita a destrui ca o de um objeto [destruir]. call A mensagem chama determinado m etodo [chamar]. return Representa uma mensagem de retorno [retornar]. send Representa o envio de um sinal [enviar]. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

92 Estere otipos para associa co es: implicita A associa ca o est a impl cita. ordenada A associa ca o requer dados ordenados. modic avel A associa ca o pode ser modicada. crescente A associa ca o deve ser crescente. constante A associa ca o deve ser constante. Estere otipos para heran cas: implementation Implementa m etodos da classe-base [implementa].

A UML? 4.3. O QUE E

complete A classe completa a hierarquia; a hierarquia est a completa [completa]. incomplete A hierarquia est a incompleta, faltam classes [incompleta]. Estere otipos para processamento paralelo/distribu do: processo Representa um processo do sistema. thread Representa uma thread do sistema. par Indica processamento paralelo. Estere otipos para caso de uso: extende Indica uma extens ao de um caso de uso [estende]. include Indica uma inclus ao de um caso de uso [inclui]. generalize Indica uma generaliza ca o de um caso de uso [generaliza]. Antes de apresentarmos em detalhes os diagramas da UML, vamos olhar rapidamente alguns programas que podem ser utilizados para gerar os diagramas, assim voc e poder a desenhar os diagramas enquanto l e o livro. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

4.4. PROGRAMAS PARA MODELAGEM ORIENTADA A OBJETO

93

4.4

Programas para modelagem orientada a objeto

Existem diversos programas para desenho dos diagramas da UML, entre os quais podemos citar: Rational Rose e um pacote prossional que, al em da montagem dos diagramas, per um pacote pago, dispon mite simultaneamente a implementa ca o dos c odigos. E vel para diversas plataformas no endere co http://www.rational.com. With Class e um pacote prossional, que, al em da montagem dos diagramas, per um pacote pago, dispon mite simultaneamente a implementa ca o dos c odigos. E vel para diversas plataformas no endere co http://www.microgold.com/index.html. Dia o modelador dia e muito simples de usar, e software livre e ser a descrito na se ca o 4.4.1. Pode ser obtido em http://www.gnome.org/gnome-office/dia.shtml. Umbrello o modelador umbrello tamb em e muito simples de usar, e software livre e ser a descrito na se ca o 4.4.2. Pode ser obtido em http://uml.sourceforge.net/index.php. Visual Paradigm pacote prossional, com vers ao livre. Ser a descrito na se ca o 4.4.3.

4.4.1

O programa Dia

Parte dos diagramas UML apresentados neste livro foram criados utilizando-se o programa dia, um software livre utilizado para a cria ca o dos mais diversos tipos de diagramas. Veja a seguir uma lista com alguns dos diagramas deste programa: AADL, Cibern etica, Circuitos, equipamentos cisco, engenharia civil, engenharia el etrica, engenharia qu mica, EML, ER, uxograma, cronograma, estrutura funcional, Gane e Sarson, GRAFCET, Lader, l ogica, mapa isom etrico, Miscel aneas, MSE, pneum atico/hidr aulico, rede, rede Jackson, rede KAOS, SADT/IDEF0, SDL, Sybase e, por m, UML. A tela do programa dia e ilustrada na Figura 4.6. Observe que a lista de componentes UML ` esquerda vemos a janela de controle do dia. Observe, na parte superior, est a selecionada. A cones gerais como: sele ca o, aproximar, mover, caixa, elipse, poligono, bezier, linha, arco, zig-zag, polilinha, curva B ezier e inser ca o de gura. No meio da tela de controle temos os elementos da UML, como: classe, modelo, texto, depend encia, interface, heran ca, associa ca o, agrega ca o, implementa ca o, restri ca o, pacote, ator, caso de uso, linha de vida, objeto, mensagem, componente, observa ca o, recept aculo, fonte e dissipador de eventos, n o, estere otipo, estado, atividade, remo, bifurca ca o e transa ca o. Finalmente, na parte de baixo da tela de controle do dia temos: cor de frente e de fundo, espessura da linha, tipo da linha e formato das pontas (setas). Veja nas Figuras 4.4 e 4.5 um esbo co dos elementos da UML disponibilizados pelo programa dia, o qual pode ser obtido no endere co http://www.gnome.org/gnome-office/dia.shtml. N ao e nosso objetivo abordar a utiliza ca o desse programa, e um pequeno manual dele poder a ser obtido em http://www.lysator.liu.se/~alla/dia/ e http://www.togaware.com/ linuxbook/dia.html. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

94

4.4. PROGRAMAS PARA MODELAGEM ORIENTADA A OBJETO

Figura 4.6: O programa dia manipulando uma estrutura UML com representa co es de classes.

4.4.2

O programa umbrello

O programa umbrello e um modelador UML distribu do juntamente com o KDE nas diversas um programa f distribui co es GNU/Linux. E acil de usar e que tem a vantagem de gerar o c odigo dos programas a partir do diagrama de classes. O c odigo pode ser exportado e importado para as seguintes linguagens:

C++, Actionscript, Ada, IDL, Java, JavaScript, Pascal, Perl, PHP, Python, Ruby, SQL, TCL, XMLschema.

Veja na Figura 4.7 a tela do modelador umbrello mostrando um diagrama de componente, e na Figura 4.8, um diagrama de classes. No site http://uml.sourceforge.net/index.php, voc e pode baixar o umbrello, cujo manual j a est a dispon vel em portugu es. . Se voc e usa GNU/Linux, abra um terminal e digite umbrello . A seguir v a em Ajuda>Manual do modelador UML umbrello (ou simplesmente pressione F1).

Dica: no programa umbrello, quando modelar uma associa ca o, indique na linha da associa ca o o nome do papel. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

4.4. PROGRAMAS PARA MODELAGEM ORIENTADA A OBJETO

95

Figura 4.7: A tela do programa Umbrello: Um diagrama de componentes.

Figura 4.8: A tela do programa umbrello um diagrama de classes. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

96

4.5. RESUMO DO CAP ITULO

Nota: veremos na se ca o 6.8.2 como montar o c odigo inicial do programa com o Umbrello.

4.4.3

O programa Visual-Paradigm

O Visual-Paradigm, ilustrado na Figura 4.9, e uma interface de modelagem UML propriet aria. Pode estar integrado a alguns sistemas de desenvolvimento como o Eclipse/IBM, JBuilder, NetBeans/Sun, entre outros. O Visual-Paradigm tem uma vers ao aberta para uso individual e n ao prossional (vers ao com recursos limitados). Tamb em tem uma vers ao standard aberta para comunidade acad emica, com licen ca v alida por um ano. Para obter uma c opia do Visual-Paradigm acesse o site http: //www.visual-paradigm.com/.

Figura 4.9: A tela do programa Visual-Paradigm um diagrama de caso de uso.

4.5

Resumo do cap tulo

Neste cap tulo aprendemos que um modelo e uma descri ca o simplicada e reduzida da realidade cuja vantagem est a associada ao seu baixo custo e ao uso de uma linguagem universal. Vimos que os modelos (estruturais ou din amicos) podem ser utilizados para nos ajudar a solucionar os mais variados problemas da engenharia. Aprendemos que a id eia da modelagem orientada a objeto e desenvolver modelos tendo como foco o conceito de objeto. A modelagem orientada a objeto surgiu ao longo dos anos de 1980 e cou madura nos anos de 1990 com o surgimento da UML, um sistema de modelagem que Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

4.6. EXERC ICIOS

97

unicou as antigas nota co es. No nal do cap tulo vimos o que s ao e como obter programas modeladores como o dia e o umbrello. No Cap tulo 5 Engenharia de software, veremos os conceitos b asicos de engenharia de software e uma descri ca o de modelos e processos utilizados para o desenvolvimento de sistemas de softwares. Dica: todos os diagramas da UML aceitam a inclus ao de notas, as quais s ao utilizadas para adicionar qualquer tipo de descri ca o a respeito do modelo que est a sendo desenvolvido, ou para detalhar algum aspecto que possa estar confuso. Nota: conceitos b asicos de modelagem s ao encontrados nas refer encias [Aris, 1978, Bender, 1978, da Silva Neto and Neto, 2005].

4.6

Exerc cios

1. Descreva, com suas palavras, o que e e para que servem os modelos. 2. Descreva, com suas palavras, o que e um paradigma. 3. Cite exemplos de modelos (estruturais e din amicos). 4. Qual a diferen ca entre a vis ao estrutural e a vis ao din amica? 5. Instale em seu computador uma ferramenta de modelagem (exemplo: umbrello ) e leia o manual do software instalado. 6. Monte alguns exemplos de diagramas utilizando a ferramenta de modelagem escolhida. 7. A Figura 4.3 mostra um diagrama de atividades para c alculo da area de uma fun ca o. O diagrama usa uma vari avel x que e comparada com xmax. Troque o uso de x pelo uso de um contador i. 8. Comente a deni ca o de modelo matem atico de [Bender, 1978], Um modelo matem atico e uma abstra ca o, simplicada, uma constru ca o matem atica relacionada ` a parte de uma realidade, sendo criada com um prop osito particular. Como reescrev e-la considerando aspectos computacionais?

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

98

4.6. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 5

Engenharia de Software
Neste cap tulo apresentaremos os conceitos b asicos de engenharia de software e uma descric a o de modelos e processos utilizados para o desenvolvimento de sistemas de softwares. Iniciaremos com a deni ca o do que e e quais s ao os objetivos da engenharia de software (se ca o 5.1). Em seguida, apresentaremos um breve hist orico da engenharia de software (se ca o 5.2) e suas caracter sticas gerais (se ca o 5.3). Apresentaremos ent ao os diferentes modelos: Modelo seq uencial linear (se ca o 5.3.1). Modelo iterativo (se ca o 5.3.2). Modelo baseado em prototipagem (se ca o 5.3.3). Modelo RAD Rapid Application Development (se ca o 5.3.4). Modelo incremental (se ca o 5.3.5). Modelo espiral (se ca o 5.3.6). Modelo TMO (se ca o 5.3.7). Modelo UP (se ca o 5.3.8). Modelo XP (se ca o 5.3.9). Finalizaremos apresentando o modelo selecionado (se ca o 5.4). Nota: na literatura especializada, esses modelos s ao tratados como modelos, t ecnicas ou processos. Usei o nome uniforme de modelos, uma vez que a palavra t ecnica se refere a aplica ` ca o pr atica dos modelos, depois de estes terem sido testados e consolidados. J a a palavra processo se refere a uma seq u encia espec ca. Como a apresenta ca o neste cap tulo e breve e simplicada, a palavra modelo e mais adequada.

5.1

O que e e quais s ao os objetivos da engenharia de software?

A engenharia de software estuda e desenvolve modelos para o desenvolvimento de softwares considerando as caracter sticas b asicas de um sistema de engenharia, isto e, conceitos como 99

100

5.2. BREVE HISTORICO DA ENGENHARIA DE SOFTWARE

especica ca o, an alise, projeto, testes, documenta c ao, execu ca o e controle. Inclui ainda itens como an alises de custo, divis ao e montagem de equipes, automatiza ca o de processos etc. Um dos objetivos b asicos da engenharia de software e gerar softwares com qualidade. A Norma Qualidade de Software (ISO/IEC 9126: NBR 13596) inclui as seguintes deni co es: Funcionalidade satisfaz as necessidades. Conabilidade e imune a falhas. Usabilidade e f acil de usar. Eci encia e r apido. Segundo [Teles, 2006], o relat orio The Chaos Report identicou que mais de 70% dos projetos de software falhamem raz ao de fatores como: consomem mais recursos do que o planejado. consomem mais tempo do que o planejado. n ao entregam o combinado. todos os tens acima. Outro aspecto interessante e que apenas 67% das funcionalidades prometidas s ao entregues. Das funcionalidades implementadas, 45% nunca s ao utilizadas e 19% raramente o s ao, ou seja, cerca de 64% de todo c odigo escrito n ao e utilizado. Fica evidente a necessidade de melhoria da comunica ca o, principalmente com o cliente, mas tamb em entre os membros da equipe de desenvolvimento. Esses dados demonstram a necessidade de se adotar um modelo de engenharia de software que se adapte de forma mais eciente aos novos tempos e ` a sua equipe de desenvolvimento. Nas pr oximas se co es apresentaremos um breve hist orico da engenharia de software e v arios modelos utilizados ao longo dos u ltimos anos, incluindo os recentes UP e XP.

5.2

Breve hist orico da engenharia de software

Os primeiros modelos de engenharia de software foram desenvolvidos para linguagens estruturadas, como C e Fortram, e s ao apresentadas em detalhes nas refer encias [Martin and McClure, 1993, Sonerviile, 1993, Pressman, 2002]. Com o surgimento da programa ca o orientada a objetos, desenvolveram-se os primeiros m etodos de modelagem orientada a objetos, os quais foram idealizados e aperfei coados por autores como Coad, Yourdan, Grady Boock, James Rumbaugh, Blaha, Premerlani, Eddy, Lorensen e Ivar Jacobsen. Cada um desses autores desenvolveu uma metodologia de modelagem diferente. Posteriormente, os m etodos de Boock, Rumbaugh e Jacobsen foram unicados na UML Unied Modeling Language ou linguagem de modelagem unicada, descrita na se ca o 4.3. Apresentaremos na se ca o 5.3 alguns conceitos relacionados a diferentes modelos, metodo importante destacar que existem logias, t ecnicas e processos de engenharia de software. E diversos modelos de engenharia de software; cada analista, programador, equipe de desenvolvimento deve escolher o modelo que mais se adapta ` as suas necessidades e ` as suas pr oprias caracter sticas. Segundo [Fowler and Scott, 2000], n ao existe um processo ideal; a deni ca o do melhor modelo depende do tipo de software e do tamanho da equipe de desenvolvimento. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

5.3. CARACTER ISTICAS DOS MODELOS DE ENGENHARIA DE SOFTWARE

101

5.3

Caracter sticas dos modelos de engenharia de software

Uma an alise r apida dos diferentes modelos de engenharia de software nos leva ao entendimento de que todos seguem os paradigmas b asicos da engenharia, isto e, conceitos como especica ca o, an alise, projeto, testes, documenta c ao, execu ca o e controle, e que as diferen cas de um modelo em rela ca o ao outro se devem ` as especicidades das equipes e dos sistemas a serem desenvolvidos. Apresenta-se aqui uma lista de conceitos que s ao comuns aos diferentes modelos de engenharia de software e ao pr oprio senso comum, [Teles, 2006]: Necessidade de planejamento. Deni ca o clara e simplicada dos requisitos do sistema. Necessidade de comunica ca o constante entre os membros da equipe de desenvolvimento e com os clientes. Execu ca o do projeto com compartilhamento de responsabilidades (reuni oes constantes e objetivas, compartilhamento de c odigo, fazer primeiro o que e essencial). Quando identicado um problema (um bug, uma falta de padroniza ca o), tentar resolv e-lo o mais rapidamente poss vel. Controlar os sistemas desenvolvidos (inclui teste dos modelos, algoritmos e softwares desenvolvidos, elimina ca o dos bugs). Dividir as equipes de desenvolvimento em grupos compactos, coesos; aliar experi encia e mocidade. Manter as pessoas atualizadas com a realiza ca o de cursos, a leitura de artigos e livros. Desta forma, os desenvolvedores poder ao, pela refatora ca o ou reengenharia, atualizar os c odigos e algoritmos. Segundo [Pressman, 2002], independente do seu dom nio de enfoque, a engenharia de software abrange uma cole ca o de m etodos descendentes (top-down) e ascendentes (botonup).

5.3.1

Modelo sequ encial linear

O modelo seq uencial linear e um dos modelos mais antigos[Pressman, 2002] e envolve a execu ca o consecutiva das seguintes atividades: An alise, projeto, codica ca o e teste. Existem varia co es do modelo seq uencial linear. [Solter and Kleper, 2005] cita o modelo Stagewise Model, o qual inclui: Planejamento, desenvolvimento, implementa ca o, teste de integra ca o, teste de subsistema e avalia ca o. Entre os problemas do modelo seq uencial linear est a a diculdade do cliente em denir com clareza as especica co es do sistema. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

102

5.3. CARACTER ISTICAS DOS MODELOS DE ENGENHARIA DE SOFTWARE

5.3.2

Modelo iterativo

Em 1970 surgiu o modelo iterativo, o qual consiste em realizar revis oes ap os cada etapa do modelo seq uencial linear. An alise->revis ao, projeto->revis ao, codica ca o->revis ao e teste->revis ao.

5.3.3

Modelo baseado em prototipagem

Segundo [Pressman, 2002], o modelo baseado em prototipagem consiste em criar um prot otipo do programa ap os a etapa de especica ca o do sistema. Ainda de acordo com [Pressman, 2002], na pr atica o prot otipo e descartado, sendo necess ario construir uma vers ao reprojetada. Outro problema deste modelo e que o cliente ao ver o prot otipo acha que o sistema est a quase pronto. O pr oprio programador pode achar que este e o melhor caminho.

5.3.4

Modelo RAD Rapid Application Development

O modelo RAD consiste em repetir ciclicamente todas as atividades do modelo seq uencial. A cada ciclo de 60 e 90 dias, desenvolve-se um m odulo diferente que e agregado ao sistema. adequado para aplica E co es em que seus subsistemas possam ser desenvolvidos completa inadequado para sistemas que envolvam novas mente dentro do per odo de 60 a 90 dias. E tecnologias (exemplo: centros de pesquisa, laborat orios de universidades).

5.3.5

Modelo incremental

O modelo incremental mistura os modelos seq uencial, de prototipagem e RAD. Por exemplo: no primeiro ciclo de montagem cria-se um n ucleo do sistema com funcionalidades b asicas. Novas funcionalidades s ao inclu das a cada ciclo. Note que a cada ciclo o sistema deve estar operacional. Este modelo e adequado para equipes pequenas e para centros de pesquisa (nos quais o n umero de pessoas envolvidas no projeto varia constantemente).

5.3.6

Modelo espiral

Em 1988, Barry W. Boehm apresentou o Spiral Method, que consiste em executar todas as atividades de forma iterativa, o que implica na constante revis ao das atividades anteriormente realizadas. A vantagem deste modelo e sua simplicidade, sendo simples de aprender e de utilizar. A diculdade est a em denir o tempo ideal para realiza ca o de cada ciclo. Observe que e um modelo iterativo e incremental. No modelo espiral as primeiras vers oes podem constar apenas do papel, e vers oes incrementais s ao desenvolvidas ao longo de cada ciclo. Segundo [Pressman, 2002], e um modelo realista para o desenvolvimento de sistemas e softwares de grande porte. As etapas a serem desenvolvidas em cada ciclo s ao: Comunica ca o com o cliente Planejamento An alise de risco Engenharia Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

5.3. CARACTER ISTICAS DOS MODELOS DE ENGENHARIA DE SOFTWARE Constru ca o e libera ca o Avalia ca o pelo cliente

103

A seguir ser a apresentado o modelo TMO, um dos primeiros modelos espec cos para o desenvolvimento de software orientado a objeto.

5.3.7

Modelo TMO Tecnologia de Modelagem de Objetos

A TMO (ou OMT em ingl es) e um dos modelos de modelagem orientada a objeto que zeram mais sucesso. A TMO possui tr es modelos: Modelo de objetos a estrutura do sistema e modelada atrav es da constru ca o do diagrama de classes (inclui classes, atributos, m etodos, associa co es, agrega co es, heran cas, e depend encias). Modelo din amico a din amica do sistema, sua intera ca o com os usu arios e modelada atrav es dos diagramas de seq u encia (eventos e mensagens), de comunica ca o e de m aquina de estado. Modelo funcional a din amica das funcionalidades dos objetos e modelada pelo diagrama de atividade (detalha as fun co es/m etodos do objeto). Os tr es modelos s ao ortogonais, ou seja, complementam-se, e a maior import ancia de um em rela ca o ao outro depender a do tipo de programa desenvolvido. A TMO e discutida em detalhes em [Rumbaugh et al., 1994]. Veremos a seguir um breve resumo de duas metodologias mais recentes, a UP Rational Unied Process, e a XP eXtreme Programming.

5.3.8

Modelo UP Unied Process

Desenvolvida pela Rational Software, uma subsidi aria da IBM, o modelo UP foi criado pela mesma equipe que desenvolveu a UML. Entre as caracter sticas do modelo pode-se citar: uma metodologia que permite atualiza E ca o e renamento constante. Inclui um conjunto de programas e ferramentas utilizados por toda a equipe de desenvolvimento. Cada processo e um uxo de trabalho individual. Como os programas e ferramentas s ao pagos e caros, n ao e adequado para pequenas empresas. Veja a seguir as etapas do UP: Concep c ao deni ca o do escopo do projeto, prazos, custos. Elabora c ao na elabora ca o realiza-se um estudo mais detalhado sobre o sistema a ser elaborado (o qu e e como). Constru c ao montar um plano para a etapa de constru ca o que e realizada ciclicamente. Isto e, para cada caso de uso ou subsistema, realizam-se as atividades de an alise, projeto, codica ca o, teste e integra ca o. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

104

5.3. CARACTER ISTICAS DOS MODELOS DE ENGENHARIA DE SOFTWARE

Transi c ao envolve a corre ca o de erros (bugs) e pode incluir otimiza co es. Itera c ao consiste em repetir as etapas anteriores. Observe que cada etapa de UP pode incluir uma ou mais itera co es e, em cada itera ca o, executase (com maior ou menor enfase) todas as atividades da engenharia de software: levantamento de requisitos, an alise, projeto, implementa ca o, testes e implanta ca o. importante lembrar que UP E e uma framework; cada equipe e cada projeto podem ser customizados de forma diferente. Por exemplo: projetos pequenos podem trabalhar somente com concep ca o, elabora ca o e transi ca o. Projetos maiores podem ter mais fases. Voc e encontra maiores detalhes sobre UP em [Kruchten, 2003].

5.3.9

Modelo XP eXtreme Programming

O eXtreme Programming, conhecido como XP, foi desenvolvido em 1999 por Kent Beck. Veja a seguir as 12 regras de ouro deste modelo: O planejamento do sistema deve ser feito ao longo de todo o ciclo de desenvolvimento. Crie pequenas vers oes de seu sistema. Compartilhe a mesma arquitetura (vis ao do sistema). Simplique sua an alise (design). Evite criar sistemas excessivamente abstratos. Teste o sistema de forma constante. Pode-se, por exemplo, manter uma m aquina em tempo integral realizando testes automatizados. Considere a necessidade de se refazer determinadas partes do sistema na medida em que inova co es estejam ocorrendo (evite deixar seu sistema muito defasado). Crie duas equipes de trabalho. Enquanto uma equipe desenvolve o m odulo do software, a outra equipe desenvolve o m odulo de teste e realiza os testes. Compartilhe o c odigo. Evite que os desenvolvedores se sintam donos de sua parte do c odigo. Todos devem poder alterar qualquer parte do c odigo. Mantenha o sistema integrado de forma cont nua. Novamente o sistema de dupla de trabalho deve ser utilizado para manter o sistema integrado. Evite que a equipe de desenvolvimento trabalhe mais do que 40 horas por semana. Comprovadamente o excesso de trabalho implica na adi ca o de bugs ao sistema. Incentive ou viabilize a participa ca o dos clientes/usu arios no uso e teste do sistema. Toda equipe deve, na medida do poss vel, usar uma mesma nota ca o (estabelecer padr oes de desenvolvimento). Segundo [Teles, 2006], as pr aticas de XP s ao denidas de forma clara, embora cada equipe de desenvolvimento deva decidir como aplic a-las. Voc e encontra maiores detalhes sobre XP em [Teles, 2006, Teles, 2004]. Consideramos que quase todos estes itens devem ser aplicados, mas particularmente discordamos dos seguintes pontos : Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

5.4. O MODELO SELECIONADO

105

O planejamento do sistema deve ser feito ao longo de todo o ciclo de desenvolvimento. Neste caso, a tend encia e a equipe fazer um planejamento minimalista, com diversos furos; al em do mais, passa a id eia de que erros no planejamento possam ser resolvidos a qualquer momento. Simplique sua an alise (design). Evite criar sistemas excessivamente abstratos. A an alise deve ser detalhada e n ao simplicada. Os modelos devem ser desenvolvidos fazendo-se uma an alise criteriosa de cada aspecto do sistema a ser desenvolvido. Pequenos erros na an alise t em forte impacto na reimplementa ca o e provocam atrasos e descumprimento de prazos. Crie duas equipes de trabalho. um enfoque exagerado no teste (esta necessidade ocorre quando o planejamento e a E an alise s ao mal feitos). Dependendo do tamanho da equipe e da complexidade do sistema, uma rela ca o de dois ou tr es desenvolvedores para cada testador e mais do que suciente.

5.4

O modelo selecionado

O modelo de engenharia de software aqui apresentado e uma adapta ca o do modelo TMO, do modelo espiral, do modelo iterativo e de itens de UP e XP, aconselhada para pequenos grupos de desenvolvimento e laborat orios de pesquisa num erica. Novos conceitos de UP e XP podem ser integrados a esta metodologia ` a medida que seu grupo de trabalho aumenta. Tamb em eliminamos t opicos muito espec cos, tornando o uso da modelagem orientada a objeto mais f acil. A Figura 5.1 ilustra as diversas etapas a serem seguidas no desenvolvimento de um programa com o modelo aqui apresentado. Note que, sempre que se desenvolve um programa, essas etapas est ao presentes, mesmo que n ao sejam documentadas. As etapas iniciais s ao mais te oricas, conceituais, e cada nova etapa envolve maior detalhamento, ocorrendo uma migra ca o do te orico para o aplicado. Observe que o modelo e iterativo. Concep c ao (requisitos/especica c ao) Envolve a concep ca o/id eia do problema, a deni ca o de requisitos a serem satisfeitos e a especica ca o do sistema (descri ca o do objetivo e o que se espera do sistema a ser desenvolvido) (se ca o 6.1). Elabora c ao Etapa em que a equipe de desenvolvimento toma conhecimento mais detalhado da area e do problema a ser resolvido (veja se ca o 6.2). Identica os subsistemas e pacotes, e feita a an alise de riscos, levantamento de custos e prazos. An alise orientada a objeto AOO An alise do problema com o objetivo de identicar a estrutura do sistema (objetos, classes, atributos, m etodos), o relacionamento das classes (associa co es, agrega co es) e a din amica do sistema (veja se ca o 6.3). Projeto do sistema Deni ca o dos conceitos relativos ao sistema a ser implementado e escolha da plataforma do sistema: hardware, sistema operacional, linguagem de programa ca o e bibliotecas a serem utilizadas (veja se ca o 6.6). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

106

5.5. RESUMO DO CAP ITULO

Projeto orientado a objeto Acr escimo ` a an alise desenvolvida das caracter sticas da plataforma escolhida, maior detalhamento do funcionamento do programa (veja se ca o 6.7). Implementa c ao do programa Transforma ca o do projeto em c odigo. Integrar os diversos m odulos, compilar e linkar (veja se ca o 6.8). Teste e depura c ao No teste vericamos se o programa satisfaz os requisitos. Devemos testar o programa ` medida que o programa realizando as tarefas usuais e depois as excepcionais. A e testado, os erros encontrados s ao corrigidos (veja se ca o 6.9). Documenta c ao Das especica co es, dos assuntos, das classes, das associa co es, dos m etodos e dos atributos. Descri ca o do c odigo para programadores. Cria ca o do arquivo de Ajuda [help] e dos manuais do programa (veja se ca o 6.10). Manuten c ao do programa Objetiva incluir aperfei coamentos e corrigir problemas (veja se ca o 6.11). Nota: embora o teste esteja representado como uma etapa estanque (por quest oes de did atica), ele deve ser realizado ao longo de todo o ciclo de desenvolvimento. Pessoalmente gosto de vericar e testar tudo o que j a desenvolvi a cada ciclo de itera ca o.

5.5

Resumo do cap tulo

Vimos que o uso de um modelo de engenharia de software eu til para o desenvolvimento de softwares prossionais que aliem caracter sticas como funcionalidade, conabilidade, usabilidade e eci encia. Quando n ao usamos engenharia de software, ou usamos modelos inadequados, temos como conseq u encia a gera ca o de c odigos in uteis, nunca utilizados e geradores de bugs. Uma palavra nal sobre modelagem: escolha um modelo que se adapta ` as suas caracter sticas pessoais. Se voc e est a acostumado a desenvolver modelos, use um modelo como TMO (veja se ca o 5.3.7) ou o apresentado na se ca o 5.4. Se voc e gosta de ir mais r apido para a etapa de programa ca o, pense em usar XP (veja se ca o 5.3.9). Uma posi ca o intermedi aria e dada por UP (veja se ca o 5.3.8). No Cap tulo 6 Etapas de para o desenvolvimento de um programa, veremos passo-a-passo as etapas para o desenvolvimento de um programa utilizando uma metodologia mista, que envolve etapas do m etodo TMO, dicas dos m etodos espiral, iterativo, de UP e de XP.

5.6

Exerc cios

1. Pesquise no dicion ario os termos engenharia e software. 2. Quais as caracter sticas comuns aos diferentes modelos de engenharia de software? 3. Por que modelos baseados em prototipagem falham? 4. Quando devemos utilizar um modelo como o espiral? 5. Qual a diculdade para aplicar o modelo UP? Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

5.6. EXERC ICIOS

107

Figura 5.1: Etapas de desenvolvimento de um software e os documentos gerados.


doc Concepo Iteraes (testes) doc Elaborao Anotaes Espeficicao.doc Diag. de caso de uso

doc Anlise Orientada a Objeto

AOO.doc Diag. de classes, de maq.estado, sequncia, comunicao e atividade.

doc Projeto do Sistema Projeto sistema.doc

doc Projeto Orientado a Objeto

POO.doc Diag. Componentes, de execuo.

doc Implementao Implementao.doc

doc Testes/Depurao Documentao.doc Testes/Bugs

Ciclo de manuteno Documentao Desenvolvimento de novas funcionalidades, mdulos, sub-sistemas.

6. Por que XP falha em sistemas novos? Por que XP e adequado para o desenvolvimento de varia co es de sistemas existentes? 7. Fa ca uma an alise cr tica das 12 regras de XP. Por exemplo: o que signica fazer o planejamento ao longo de todo projeto? 8. Fa ca uma an alise cr tica do modelo de engenharia de software selecionado. Dica: voc e quer fazer um churrasco no domingo mas n ao sabe se vai ter sol? A dica do professor Nivaldo e ir at e o site do CPTEC, http://tempo.cptec.inpe.br/, e, em seguir, digitar o nome de sua cidade no campo :: Previs oes Digite o nome da Cidade . O site mostra a previs ao para hoje e para os pr oximos quatro dias e inclui: temperaturas m aximas e m nimas, hora do sol nascente e do sol poente, raios UV, e cones com previs ao de sol/chuva/nublado.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

108

5.6. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 6

Etapas para o Desenvolvimento de um Software


Mostraremos neste cap tulo as etapas para o desenvolvimento de um software, o qual tem uma liga ca o direta com o modelo apresentado na se ca o 5.4 e com a UML apresentada no Cap tulo 4 Modelagem orientada a objeto. Na primeira edi ca o os diagramas foram descritos no Cap tulo 3, e as etapas para desenvolvimento do software no Cap tulo 4. O leitor precisava ler o Cap tulo 3, depois o 4 e novamente o 3 e o 4, pois existiam interdepend encias. Nesta edi ca o as etapas para o desenvolvimento de software incluem a apresenta ca o dos diversos diagramas. Por exemplo: na se ca o 6.4.1 apresentamos um conjunto de regras que auxiliam o programador na identica ca o das classes do programa. J a na se ca o 6.4.4 apresentaremos como modelar os aspectos estruturais do software utilizando diagramas de classe. Iniciaremos este cap tulo apresentando o conceito de concep ca o (ou especica ca o ) do software (se ca o 6.1), os casos de uso (se ca o 6.1.1) e os diagramas de casos de uso (se ca o 6.1.2). Em seguida, apresentaremos a elabora ca o (se ca o 6.2) e os itens correlacionados como a an alise de dom nio (se ca o 6.2.1), a identica ca o de pacotes (se ca o 6.2.2) e os diagramas de pacotes (se ca o 6.2.3). S ao apresentadas ainda a montagem de prot otipos da interface (se ca o 6.2.5) e a deni ca o de cronogramas, prazos e custos (se ca o 6.2.6). Na se ca o 6.3 apresenta-se a AOO an alise orientada a objeto, iniciando com a apresenta ca o do modelo estrutural (se ca o 6.4). Veremos descri co es dos elementos presentes em uma an alise orientada a objeto, e, em seguida, os diagramas UML correspondentes; a identica ca o de classes (se ca o 6.4.1) e os diagramas de classe (se ca o 6.4.4); a identica ca o de atributos (se ca o 6.4.2), m etodos (se ca o 6.4.3), associa co es (se ca o 6.4.5); a classe de associa ca o (se ca o 6.4.6) e os diagramas de classe com associa co es (se ca o 6.4.7); a identica ca o de agrega co es e composi co es (se ca o 6.4.8) e os respectivos diagramas (se ca o 6.4.9); a identica ca o de heran cas (se ca o 6.4.10) e os diagramas de classe com heran cas (se ca o 6.4.11). Veremos ainda o uso de restri co es (se ca o 6.4.13), realiza co es (se ca o 6.4.14) e depend encias (se ca o 6.4.15). A identica ca o de objetos (sec a o 6.4.16) e o diagrama de objetos (se ca o 6.4.17). Descreve-se ainda a etapa de itera ca o (se ca o 6.4.20). No modelo din amico (se ca o 6.5), o foco e a intera ca o entre os objetos, atributos e m etodos como os objetos se comportam quando o programa est a sendo executado. Veremos a identica ca o de eventos e mensagens (se ca o 6.5.1), os diagramas de seq u encia (se ca o 6.5.2), e de comunica ca o (se ca o 6.5.3). Aprenderemos tamb em a identicar os diferentes estados assumidos pelos objetos (se ca o 6.5.4) e os diagramas de m aquinas de estado (se ca o 6.5.5). 109

110

ESPECIFICAC 6.1. CONCEPC AO AO

Na etapa de projeto do sistema (se ca o 6.6), veremos a deni ca o da interface de programa ca o API (se ca o 6.6.1), a sele ca o da implementa ca o de controle (se ca o 6.6.2) e das plataformas a serem suportadas (se ca o 6.6.3). Aprenderemos quando usar e como selecionar bibliotecas externas (se ca o 6.6.4) e a biblioteca gr aca a ser utilizada GDI (se ca o 6.6.5), al em da sele ca o do ambiente de desenvolvimento integrado IDE (se ca o 6.6.6). Na etapa do projeto orientado a objeto (se ca o 6.7), veremos os diagramas de componentes (se ca o 6.7.1) e de implanta ca o (execu ca o) (se ca o 6.7.2). Na etapa de implementa ca o (se ca o 6.8), veremos conceitos relacionados ao teste de software (se ca o 6.9), ao porqu e de se testar (se ca o 6.9.1), ` a equipe (se ca o 6.9.2) e ` a metodologia de teste (se ca o 6.9.3). Finalmente veremos porque a documenta ca o dos programas e t ao importante (se ca o 6.10), al em do uso de cart oes CRC (se ca o 6.32), a manuten ca o (se ca o 6.11) e o reuso do software (se ca o 6.11).

6.1

Concep c ao especica c ao

A primeira etapa do desenvolvimento de um software e a concep ca o, a deni ca o de requisitos a serem satisfeitos e a especica ca o do sistema (descri ca o do objetivo e o que se espera do sistema a ser desenvolvido, o contexto da aplica ca o). Na concep ca o ocorre a primeira reuni ao da equipe de desenvolvimento com os clientes, quando e feita a especica ca o do software. O cliente por meio das especica co es e das entrevistas, passa para o analista id eias gerais de uso do sistema. O resultado da etapa de especica ca o e um conjunto formal de documentos e requisitos organizados pelo analista do sistema com apoio dos usu arios. As especica co es denem as caracter sticas gerais do programa, aquilo que ele deve realizar e n ao a forma como ir a faz e-lo. Denem as necessidades a serem satisfeitas. Envolvem a sele ca o do tipo de interface (modo texto ou gr aca), a forma de intera ca o com o usu ario (teclado, mouse); se vai ter uma ou m ultiplas janelas; se o programa vai imprimir seus resultados, o formato dos arquivos de disco; se vai existir um helpe seu formato. Podem ser especicadas caracter sticas de desempenho. O cliente dene o que deve obrigatoriamente ser satisfeito e o que e opcional isto e, tudo o que o software deve ser. As especica co es devem ser bem feitas, porque s ao a base para a etapa de an alise orientada a objeto (veja se ca o 6.1.1). Cuidado com ambig uidades e com termos vagos nas especica co es; seja claro. Observe que os diagramas de caso de uso podem ser utilizados na etapa de especica ca o (veja se ca o 6.1.2). Fa ca o teste das especica co es (veja a se ca o 6.9, sobre teste de software). Na medida do poss vel, ap os a an alise de dom nio (veja se ca o 6.2.1), os limites do sistema e os atores externos devem estar claros. Dica: a comunica ca o com o cliente pode ser melhorada com o uso de met aforas, como, por exemplo, a met afora da lixeira. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

ESPECIFICAC 6.1. CONCEPC AO AO

111

6.1.1

Casos de uso do software cen arios

Segundo [Blaha and Rumbaugh, 2006], um cen ario pode ser um registro hist orico de execu ca o de um sistema real ou um experimento de execu ca o te orica de um sistema proposto. Um caso de uso descreve um ou mais cen arios de uso do software, exemplos de uso, como o sistema interage com usu arios externos (atores). Ademais, ele deve representar uma seq u encia t pica de uso do programa (a execu ca o de determinadas tarefas-padr ao). Tamb em deve representar as exce co es, casos em que o usu ario comete algum erro, em que o sistema n ao consegue realizar as tarefas solicitadas. Segundo [Pressman, 2002], o caso de uso deve produzir uma descri ca o clara e n ao amb gua de como o usu ario nal e o sistema interagem um com o outro. [Pressman, 2002] diz ainda que uma vez denidos o ator e seu caso de uso, uma hierarquia de comandos e identicada. Devem ser montados diversos diagramas de caso de uso. Por exemplo: para cada cen ario, crie diagramas de seq u encia listando os objetos e os diversos eventos que partem de um objeto para outro (veja se ca o 6.5.2). A Tabela 6.1 mostra os itens a serem inclu dos na descri ca o do caso de uso, podendo-se ainda incluira lista de atores e as pr e-condi co es para execu ca o. O item etapas e opcional, pois elas podem ser inclu das diretamente no diagrama de caso de uso (veja se ca o 6.1.2) Uma vez apresentados os conceitos relacionados aos casos de uso, cen arios, apresentaremos como modelar os cen arios com os diagramas de caso de uso da UML. Tabela 6.1: Exemplo de caso de uso. Nome do caso de uso: Resumo/descri ca o: Etapas: C alculo da integral de uma fun ca o. Determina ca o da integral de uma fun ca o em um dado intervalo. 1. Criar objeto fun ca o. 2. Criar objeto de integra ca o. 3. Denir intervalo de integra ca o e n umero de pontos. 4. Calcular area da fun ca o. 5. Gerar gr acos. 6. Analisar resultados. Um cen ario alternativo envolve uma entrada errada do usu ario (por exemplo, a fun ca o e logar tmica, e o intervalo vai de -1 a 10). O programa apresentar a um bug quando for determinar o logar tmo de -1.

Cen arios alternativos:

6.1.2

Diagrama de casos de uso

o diagrama mais O diagrama de casos de uso e uma representa ca o visual dos casos de uso. E simples da UML, sendo utilizado para demonstrar os cen arios de uso do sistema pelos usu arios, os quais ao verem esses diagramas ter ao uma vis ao geral do sistema. O diagrama de caso de uso pode ser utilizado durante e ap os a etapa de especica ca o, adicionando ` as especica co es textuais alguns cen arios de uso do programa a ser desenvolvido. A Figura 6.1 mostra um diagrama de caso de uso. O diagrama de caso de uso pode incluir: atores, elipses, generaliza co es, associa co es, pacotes, inclus oes, extens oes, notas e restri co es. Um ator e um boneco utilizado para representar um usu ario, um sistema, um hardware, Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

112

ESPECIFICAC 6.1. CONCEPC AO AO uma entidade que interage com o sistema. O ator comunica-se com o sistema somente com associa co es. Um diagrama de caso de uso pode incluir um ou mais atores.

Dentro das elipses s ao inclu das descri co es das etapas, a co es e opera co es que ser ao executadas pelo sistema. Uma elipse tamb em pode incluir um caso de uso, que ser a detalhado em outro diagrama ou em uma tabela (veja Tabela 6.1).

Um associa c ao entre um ator e uma elipse e representada por uma seta. A associa ca o pode ligar ainda dois atores e incluir estere otipos como < <extend> > e < <include> >. O diagrama de caso de uso geral da Figura 6.1 mostra o usu ario acessando os sistemas de ajuda do software, calculando a area de uma fun ca o ou analisando resultados. No exemplo da Figura 4.9, o caso de uso de Acesso ao sistema de ajuda e detalhado. Observe que ilustramos o acesso aos diferentes tipos de manuais que o usu ario poder a acessar. Figura 6.1: Diagrama de caso de uso um caso de uso geral.

O caso de uso Calcular area fun ca o descrito na Figura 6.1 e na Tabela 6.1 e detalhado na Figura 6.2. O usu ario criar a um objeto fun ca o matem atica, um objeto para sua integra ca o; em seguida, denir a o intervalo de integra ca o, calcular a a area da fun ca o criada e, por m, analisar a os resultados (eventualmente gerar a gr acos com os resultados obtidos utilizando um sistema externo, como o programa gnuplot ). Este diagrama de caso de uso ilustra as etapas a serem executadas pelo usu ario ou sistema, a itera ca o do usu ario com o sistema. Figura 6.2: Diagrama de caso de uso calcular area fun ca o.

Especializa c ao/Generaliza c ao

d C a s o e s o u : i l lc d i d j d i C A t t c e s o a s e m a e a o s e m a m p a r o a u u u . S F r e m n u l f C a c r n o u u lis lt d n a r e s a o s u io A A t o r s r u  d a s o e s o u : C l f a c a r e a n o u u l f c a r a n o u C f i l i t t e n r e r a o n e g r a o v D d h ) t t e m . ( i b j d i t t r a o e o e n g r a o f i e r a g c o s C G lo t g n p u ia b je f t r o o n oA u lis lt d n a r e s a o s u C io A t o r s r u 
Andr e Duarte Bueno

Em um diagrama de caso de uso, um ator ou um caso de uso (elipse) pode ser especializado/generalizado. Uma generaliza ca o de um caso de uso mostra que este pode ser realizado de uma forma mais espec ca. Funciona da mesma forma que heran ca em classes; o caso de uso geral deve ser abstrato, e os casos de uso herdeiros, espec cos. Veja na Figura 6.3 a generaliza ca o do ator respons avel por gerar os gr acos do sistema. Neste exemplo os gr acos poder ao Programa ca o Orientada a Objeto com C++

ESPECIFICAC 6.1. CONCEPC AO AO

ser gerados pelos programas externos gnuplot, octave ou scilab. Da mesma forma como ocorre em heran cas, toda a estrutura e herdada e novas caracter sticas e varia co es comportamentais podem ser adicionadas. Figura 6.3: Diagrama de caso de uso: analisar resultados (uso de generaliza ca o).

Inclus ao

Quando um caso de uso e comum, o mesmo pode ser inclu do em outro. No exemplo da Figura 6.4, An alisar v arias fun co es, o usu ario ir a analisar v arias curvas, repetindo v arias vezes o caso de uso Analisar resultado. Observe que fazemos refer encia ao caso de uso Analisar resultados ilustrado na Figura 6.3 usando uma seta tracejada e o estere otipo < <include> >. Figura 6.4: Diagrama de caso de uso Analisar v arias fun co es (uso de inclus ao).
Analisar resultados <<include>>

d a s o e s o u : C l i l d t f i l i n a r a o s e r a c o s e n r a o z A G g A g f ) i d c m c c q e s u d f i e r a o e r c o s ( g g g d h t f d e m n r o s p m . l i l d t n a s r e s a o s u l s A l t n c a e u v , g i b o c a . i l b s c a i l i t t t m r e a r o o c a e v E io g t o r s r u lo t ? n p u A
113
Analisar vrias curvas/funes Ator-usurio

Extens ao Na Tabela 6.1, inclu mos uma excess ao, um caso de uso excepcional, o mesmo pode ser representado como uma extens ao do caso de uso da Figura 6.2. Veja na Figura 6.5, como representar uma extens ao do caso de uso Calcular area fun ca o, observe o uso do estere otipo < <extend> >, a inclus ao de uma elipse que lembra que o usu ario pode entrar com dados errados. Inclu mos ainda uma anota ca o lembrando a necessidade de se criar uma rotina para controle da entrada de dados. A seta tracejada aponta para o caso de uso que utiliza o caso de uso extendido. Um caso de uso < <extend> > pode ser descrito por uma anota ca o.

6.1.3

Senten cas para casos de uso

Os casos de uso fornecem uma vis ao externa do sistema (eventos externos) [Fowler and Scott, 2000]. Cada diagrama de caso de uso deve ter um nome u nico, indicado no canto superior esquerdo, dentro de uma nota. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

114

6.2. ELABORAC AO

Figura 6.5: Diagrama de caso de uso entrada de dados errada (uso de extens ao).
Caso de uso: Exemplo de extenso do caso de uso "Calcular rea funo" Calcular rea funo

<<extend>>

Entrada de dados errada Ator-usurio

Segundo [Blaha and Rumbaugh, 2006], um ator deve ter um prop osito u nico e coerente. Um caso de uso pode ser generalizado, pode ser extendido. Use o estere otipo < <extended> > para indicar que o caso de uso e uma extens ao de outro caso de uso, e o estere otipo < <include> > para indicar que um caso de uso inclui outro. Deve-se criar um dicion ario com o nome dos casos de uso e uma breve descri ca o. Nome do caso de uso: Nome do caso de uso: Descri ca o/Resumo Descri ca o/Resumo

Um diagrama de caso de uso pode ser ampliado para incluir intera co es entre objetos do sistema, sendo tranformado em diagrama de comunica ca o (veja se ca o 6.5.3). Uma mesma pessoa pode representar mais de um ator em um sistema, devendo ser representado separadamente. Exemplo: um coordenador de curso de uma universidade tamb em costuma ser um professor. Observe que sistemas complexos podem ser utilizados por diferentes tipos de usu ario. Se isto ocorrer, inclua nos casos de uso os diferentes tipos de usu ario. Exemplo: alguns programas modicam sua interface em fun ca o do tipo de usu ario: iniciante, intermedi ario ou avan cado. Na UML 2, os elementos de um caso de uso podem incluir multiplicidades. Verique se as especica co es atendem aos requisitos b asicos da engenharia de software. Teste: quando nalizar a etapa de concep ca o, fa ca o teste das especica co es (veja item 1 na se ca o 6.9).

6.2

Elabora c ao

Depois da deni ca o dos objetivos, da especica ca o do software e da montagem dos primeiros diagramas de caso de uso, a equipe de desenvolvimento passa por um processo de elabora ca o que envolve o estudo de conceitos relacionados ao software a ser desenvolvido, a an alise de dom nio e a identica ca o de pacotes. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.2. ELABORAC AO

115

Na elabora ca o fazemos uma an alise dos requisitos, ajustando os requisitos iniciais de forma a desenvolver um sistema u til, que atenda a `s necessidades do usu ario e, na medida do poss vel, permita seu reuso e futura extens ao. Eliminam-se os requisitos imposs veis, e ajusta-se a id eia do sistema de forma que este seja ex vel, considerando-se aspectos como custos e prazos. Veja a seguir uma lista de atividades a serem realizadas na elabora ca o (veja Figura 6.6): Realizar a an alise de dom nio (veja se ca o 6.2.1). Identicar pacotes (assuntos) (veja se ca o 6.2.2). Montar o(s) diagrama(s) de pacotes (veja se ca o 6.2.3). Revisar as especica co es/requisitos do sistema deixando-os mais precisos, sem ambig uidades e inconsist encias, [Blaha and Rumbaugh, 2006].

6.2.1

An alise de dom nio

A an alise de dom nio e uma parte da elabora ca o; seu objetivo e entender o dom nio, a abrang encia do sistema a ser desenvolvido. Envolve itens como estimar o reuso do software utilizando-se da cria ca o de bibliotecas gen ericas. Neste ponto, o analista pensa no sistema de uma forma mais gen erica, identicando conceitos fundamentais que podem ser reaproveitados em outros sistemas. Por exemplo: o uso ou o desenvolvimento de padr oes de projeto s ao etapas da an alise de dom nio (Veja Figura 6.6). Estudo dos requisitos/especica co es do sistema. Deni ca o e caracteriza ca o do dom nio a ser investigado ( area dos programas e bibliotecas a serem investigadas). Uma boa maneira de identicar os assuntos relacionados ao sistema que est a sendo desenvolvido e dar uma olhada nos livros, manuais e artigos da area. Manter contato com especialistas que tenham dom nio dos conceitos envolvidos. Segundo [Fowler and Scott, 2000], estas pessoas devem ser abertas, ter bastante conhecimento pr atico e estar dispon veis para perguntas. Deve-se fazer entrevistas com os usu arios do software (para detalhamento dos diagramas de caso de uso). Identica ca o de amostras (instalar e testar programas e bibliotecas similares). Na elabora ca o deve-se analisar a possibilidade de se reaproveitar projetos antigos (bibliotecas externas, programas existentes etc). Procurar as classes em bibliotecas existentes antes de implement a-las [Pressman, 2002]. Se a equipe de desenvolvimento j a tem experi encia com algumas bibliotecas (como a STL, bibliotecas da GNU, bibliotecas GPL), isto deve ser considerado. A id eia e reaproveitar o conhecimento legado. Identica ca o e deni ca o dos objetos gen ericos (a serem reutilizados). Talvez o aspecto mais importante da elabora ca o seja o contato com o cliente. Quando o cliente/usu ario tem uma no ca o b asica de como o sistema e desenvolvido, ele passa a fazer solicita co es que ser ao mais facilmente implementadas. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

116

6.2. ELABORAC AO

Figura 6.6: Elabora ca o e an alise de dom nio (adaptado de [Pressman, 2002]).


Anlise de Domnio: Modelo genrico, assuntos, classes, e relacionamentos genricos.

Etapas da elaborao

Universo de conhecimentos relacionados ao sistema.

Requisitos Consulta Consulta Livros, manuais, literatura tecnica

Anlise dos requisitos

Consulta a especialistas

Anlise de domnio

Consulta Bibliotecas Especialistas Entrevistas Analista Consulta Programas existentes Identificao e Montagem dos Diagramas de pacotes

Entrevistas Usurio Cliente Reviso dos requisitos

6.2.2

Identica c ao de pacotes assuntos

Um assunto e aquilo que e tratado ou abordado em uma discuss ao, em um estudo e e utilizado para orientar o leitor em um modelo amplo e complexo. Se um grupo de classes troca muitas informa co es entre si, provavelmente as classes fazem parte de um mesmo assunto. Assim, classes que se relacionam por meio de conceitos em comum fazem parte de uma mesma area, s ao reunidas e formam um assunto (pacote). Em um pacote, os nomes de classes e de associa co es devem ser semelhantes. Preste aten ca o a semelhan cas na forma de c alculo. Procedimentos semelhantes indicam polimorsmo e s ao candidatos a superclasses. Usualmente a classe mais gen erica de uma hierarquia de classes identica um assunto. Em C++ e usual um pacote ser representado como umnamespace (os namespaces ser ao descritos no Cap tulo 10 Namespace). Dica: monte um diagrama de pacotes (assuntos, m odulos) (veja se ca o 6.2.3).

6.2.3

Diagrama de pacotes assuntos, m odulos

Um diagrama de pacotes eu til para mostrar as depend encias entre as diversas partes do sistema; pode incluir: sistemas, subsistemas, hierarquias de classes, classes, interfaces, componentes, n os, colabora co es e casos de uso. O exemplo da Figura 4.2 apresenta um diagrama de pacotes para um sistema de m etodos num ericos. Observe que o diagrama de pacotes inclui um pacote bibliotecas, o qual e dividido em bibliotecas matem aticas, de estat stica e de simula ca o. A seguir o componente biblioteca de simula ca o ser a detalhado. Outro exemplo de diagrama de pacotes e apresentado na Figura 4.7. O programa grafo depende da biblioteca grafo; a biblioteca lib lmpt depende das bibliotecas confeq, stl, grafo e TReconstru ca o. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.2. ELABORAC AO

117

6.2.4

Senten cas para pacotes

Pode-se agrupar casos de uso dentro de um pacote. A refer encia a um elemento de um pacote em um diagrama deve incluir o nome do pacote (exemplo: NomeDoPacote::elemento). Dentro de um pacote n ao podem existir nomes repetidos. O nome do pacote pode ser igual ao nome da -superclasse. De um modo geral uma hierarquia de classes faz parte de um u nico pacote, e a superclasse deve ser uma classes de interface (abstrata). Depois de realizar a an alise de dom nio, identicar e montar os primeiros diagramas de pacotes, podemos montar um esbo co, um prot otipo da interface do software. Note que esta etapa e opcional.

6.2.5

Montagem de prot otipo da interface do software

O prot otipo da interface do software e uma vers ao simplicada do software que vai ser desenvolvido. No prot otipo, os cones, bot oes, menus e di alogos s ao implementados visualmente em um software do tipo RAD (como o qt-designer ). Observe que n ao existe o c odigo; existe apenas a casca externa do software, de modo que, ao pressionar um bot ao, nenhuma a ca o e realizada. Veja a seguir algumas dicas para montagem do prot otipo do software: Para iniciar a montagem do prot otipo, parta da interface de programas existentes, das especica co es do software, do conhecimento dos usu arios e procure fazer um prot otipo o mais simples poss vel. Como a interface e geradora de muitos eventos, ela deve servir de base para a montagem de diversos cen arios. Talvez seja necess ario montar novos diagramas de caso de uso. Todos os eventos identicados na elabora ca o do prot otipo foram devidamente considerados? Deve-se testar o prot otipo desenvolvido (veja se ca o 6.9, sobre teste de software). Finalizado o prot otipo, ele deve ser apresentado e testado pelos clientes. Obtenha um retorno dos usu arios, sua avalia ca o do prot otipo. Responda a quest oes como: i) ele responde ` as necessidades levantadas nas especica co es? ii) est a faltando alguma coisa? iii) a interface utilizada e adequada (usabilidade)? A Figura 6.7 mostra que os eventos gerados pelos atores (eventos do teclado, do mouse e de dispositivos externos como a entrada auxiliar) s ao tratados por um controlador. O controlador organiza a la de eventos e os distribui para os diferentes objetos do sistema. S ao mostrados ainda os eventos e mensagens gerados e trocados entre os objetos que comp oem o sistema. Teste: quando terminar a montagem do prot otipo fa ca o teste da interface (veja item 2, na se ca o 6.9.3). Ap os a etapa de elabora ca o an alise de dom nio, identica ca o e montagem dos diagramas de pacotes e a cria ca o do prot otipo da interface, eles devem ser documentados, organizados e apresentados ao cliente. Deve-se denir ainda quest oes como cronogramas, prazos e custos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

118

6.2. ELABORAC AO

Figura 6.7: Interface gr aca e eventos.


Interface e eventos. Uma interface grfica como a ilustrada ao lado, gera muitos eventos (teclado, mouse, outros dispositivos). Mensagens de outros dispositivos Mensagens do Mouse controlador Mensagens do teclado Interface grfica do programa SAIL.

Controle (recepo e distribuio) das mensagens.

Objeto

Objeto Objeto

Troca de mensagens diretas entre objetos do sistema.

6.2.6

Deni c ao de cronogramas, prazos, custos, contratos

As quest oes de prazos, montagem da equipe de desenvolvimento, custos, contrato, medi co es e controle das atividades desenvolvidas, entre outras, n ao s ao focos deste livro. Para maiores detalhes consulte as refer encias [Pressman, 2002, Martin and McClure, 1993, Emerson Rios, 2004, Sonerviile, 1993].

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

6.3. AOO ANALISE ORIENTADA A OBJETO

119

6.3

AOO An alise Orientada a Objeto

A terceira etapa do desenvolvimento de um programa e a AOO An alise Orientada a Objeto. A AOO utiliza algumas regras para identicar os objetos de interesse, as rela co es entre os pacotes, as classes, os atributos, os m etodos, as heran cas, as associa co es, as agrega co es, as composi co es e as depend encias. O modelo de an alise deve ser conciso, simplicado e deve mostrar o que deve ser feito, n ao se preocupando como isso ser a realizado. O resultado da an alise e um conjunto de diagramas que identicam os objetos e seus relacionamentos. A AOO envolve o desenvolvimento de doismodelos: O modelo estrutural (veja se ca o 6.4). O modelo din amico (veja se ca o 6.5).

6.4

AOO Modelo estrutural

O foco do modelo estrutural e a an alise da estrutura do sistema, dos objetos e de seus relacionamentos. Este modelo e desenvolvido em camadas; veja a Figura 4.2. Em uma primeira camada s ao montados os diagramas de pacotes (se ca o 6.2.3), mostrando o relacionamento dos dos m odulos e subsistemas. Em seguida, cada pacote e detalhado, incluindo-se os diagramas de componentes; em uma terceira camada s ao montados os diagramas de classes (se ca o 6.4.4, 6.4.6, 6.4.9, 6.4.11) e os diagramas de objetos (se ca o 6.4.17). Opcionalmente, em uma quarta camada, montamos os diagramas de estrutura composta (se ca o 6.4.18). Observe que a cada nova camada o n vel de detalhamento do sistema e maior. Na maioria dos programas o modelo estrutural e o mais importante, pois representa e identica os objetos e os relacionamentos que comp oem o sistema, sendo utilizado por ferramentas CASE, como o umbrello, para montar o c odigo inicial do programa. Como o modelo estrutural e constitu do de elementos que s ao facilmente reconhecidos tanto pelos clientes como pelos desenvolvedores, este modelo permite uma maior comunica ca o no desenvolvimento do programa. Veremos a seguir como identicar as classes (objetos) e como devemos montar os diagramas de classes usando UML. Nota: o modelo estrutural equivale em parte ao modelo de objetos da OMT.

6.4.1

Identica c ao de classes

Segundo a t ecnica de [Booch, 1986], podemos iniciar nossa an alise estudando as especicac o es do programa. Para encontrar candidatas a classes, pegue as especica co es e sublinhe os substantivos. Depois fa ca uma an alise mais detalhada das poss veis classes, eliminando as desnecess arias e acrescentando alguma outra que tenha surgido. Segundo [Booch, 1986], os verbos nas especica co es costumam referenciar m etodos (veja se ca o 6.4.3). Senten cas para identicar classes Veja se seguir um conjunto de dicas de [Johnson and Foote, 1998] que nos ajudam a identicar as classes. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

120

6.4. AOO MODELO ESTRUTURAL

A nova classe representa uma abstra ca o signicativa para o dom nio do problema. Modelar com classes as entidades que ocorrem naturalmente no dom nio do problema. A classe e complexa. O conjunto de m etodos da classe e freq uentemente utilizado por outras classes. Se representada como um m etodo de uma outra classe, poucos usu arios desta classe a solicitariam. Senten cas para conserva c ao das classes corretas2 Veja a seguir um conjunto de dicas de [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006] que nos ajudam a eliminar as classes desnecess arias. Se a classe n ao estiver muito clara, se n ao se encaixar bem no problema, voc e deve elimin ala, ou encaix a-la dentro de outra. Se duas classes representam a mesma informa ca o, uma delas deve ser eliminada. Em uma associa ca o, costuma-se atribuir a cada classe o seu papel. O nome a ser dado ` a classe deve representar seu conceito b asico e n ao o papel que ela exerce em uma associa ca o. Se um atributo costuma ser acessado muitas vezes isoladamente, representando um conceito, e se for independente, transforme-o em uma classe. Conceitos relacionados ` a implementa ca o das classes devem ser inclu dos apenas na etapa de projeto (veja se ca o 6.7). Dica: revise o diagrama de classes (veja se ca o 6.4.4), incluindo as classes que foram identicadas.

6.4.2

Identica c ao de atributos

Os atributos devem ter nomes signicativos, devem representar uma propriedade do objeto, do dom nio da aplica ca o ou do mundo real. Segundo [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006], os atributos podem ser identicados por substantivos seguidos por frases possessivas como a cor da cadeira ou a posi ca o do cursor. Os adjetivos muitas vezes representam valores de atributos espec cos e enumerados. Um atributo derivado e aquele que e obtido a partir de outros atributos. Por exemplo: se voc e tem o raio de um c rculo, pode obter sua area e seu per metro. Neste caso, o raio seria um atributo normal; a area e o per metro seriam atributos derivados, os quais devem ter uma nota ca o diferente, mas n ao podem ser omitidos. Na etapa de projeto eles poder ao ser especicados por meio de um m etodo (um m etodo calcular aa area e outro, o per metro). Os atributos de associa ca o devem ser claramente identicados, pois existem em fun ca o de uma associa ca o entre dois ou mais objetos (veja a se ca o 6.4.7 e a Figura 6.10). Atributos coletivos (de classes ou est aticos) podem ser substitu dos com vantagens por classes associadas. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.4. AOO MODELO ESTRUTURAL Senten cas para conserva c ao dos atributos corretos2

121

Segundo [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006], a conserva ca o dos atributos corretos envolve: Se o atributo for pouco descritivo, poder a ser eliminado da an alise e inclu do no projeto. Elimine da etapa de an alise todo e qualquer ag (valor booleano do tipo verdadeiro/falso). Se uma propriedade depende da presen ca de uma associa ca o, ent ao aquela pode ser implementada como um atributo da associa ca o (veja a se ca o 6.4.7 e a Figura 6.10). Se a classe apresenta grupos de atributos que parecem comportar-se isoladamente, pense em dividir a classe. Dica: revise o diagrama de classes, incluindo os atributos que foram identicados.

6.4.3

Identica c ao de m etodos

Se o objeto identicado na AOO e um objeto real, e f acil identicar suas opera co es, mas existem m etodos de dif cil identica ca o. Segundo [Booch, 1986], os verbos nas especica co es costumam referenciar m etodos. Adicionalmente, denir em que classe um determinado m etodo deve ser colocado nem sempre e um processo f acil. A pergunta e: onde devo colocar este m etodo? Em geral, um m etodo deve ser colocado na classe-alvo. Se existe uma classe mais afetada por determinado m etodo, o m etodo deve ser colocado nessa classe. A inclus ao de m etodos pode ser realizada a todo instante, sendo realizada com base em um dos conceitos expostos a seguir [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006]. Na etapa de modelagem, concentre-se no que o m etodo faz, n ao em como implement a-lo. Projeteos m etodos com um u nico objetivo. De modo geral, cada evento enviado a um objeto corresponde a um m etodo no objeto (veja a se ca o 6.5.2). A co es e atividades no diagrama de m aquinas de estados podem ser m etodos (veja a se ca o 6.5.5). De modo geral, cada fun ca o do diagrama de atividade corresponde a um m etodo (veja a se ca o 6.5.7). Senten cas para conserva c ao dos m etodos corretos2 Se um m etodo manipula dados externos mais do que os da pr opria classe, considere mud alo de classe. Se os m etodos realizam trabalhos semelhantes, eles podem fazer parte de uma heran ca. Projete um novo m etodo quando se defrontar com a alternativa de ampliar um j a existente. Evite m etodos extensos (m aximo 30 linhas). Armazene como atributos de classe os atributos que s ao necess arios a mais de um m etodo ou a uma classe-base. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

122

6.4. AOO MODELO ESTRUTURAL

Evite a chamada de um m etodo em fun ca o do resultado de outro m etodo. Dica: inclua no diagrama de classes os m etodos que foram encontrados (veja a se ca o 6.4.4). Verique os efeitos no diagrama de m aquina de estado (veja a se ca o 6.5.5) e no diagrama de seq u encia (eventos) (veja a se ca o 6.5.2). Dica: veja na se ca o 6.11.4 senten cas para construir m etodos robustos.

6.4.4

Diagrama de classes

Iniciaremos aqui a apresenta ca o dos diagramas de classes, os quais ser ao utilizados para a montagem da vers ao inicial do c odigo do programa pelo uso de geradores de c odigo (como o Umbrello), devendo ser bem desenvolvidos e entendidos. No diagrama de classes constam as classes (se ca o 6.4.1), seus atributos (se ca o 6.4.2), m etodos (se ca o 6.4.3) e os relacionamentos entre as diversas classes, como associa co es (se ca o 6.4.5), agrega co es (se ca o 6.4.8), heran cas (se ca o 6.4.10), restri co es (se ca o 6.4.13), realiza co es (se ca o 6.4.14), e depend encias (se ca o 6.4.15). Pode incluir ainda interfaces, colabora co es e anota co es. Observe na Figura 6.8 a representa ca o UML de uma classe. No primeiro bloco vai o nome da classe (sempre no singular); no segundo bloco, os atributos, e no terceiro,os m etodos. Uma representa ca o mais detalhada dos atributos engloba sua visibilidade (+publico, #protegido ou -privado), seu tipo e valor. Os atributos de classe aparecem sublinhados. Da mesma forma, pode-se detalhar os m etodos, incluindo os par ametros, o retorno e o tipo de acesso. Veja que os atributos e m etodos podem ou n ao ser visualizados. Da mesma forma, detalhes como tipo de retorno de um m etodo, tipo e n umero de par ametros podem ou n ao ser visualizados. Uma classe gabarito (template) representa um conceito gen erico que pode ser implementado com diferentes tipos de objetos. M etodos e classes abstratas s ao representados em it alico. Classes persistentes s ao armazenadas em disco ou em uma base de dados e s ao identicadas no diagrama de classe com o estere otipo < <persistente> >. Figura 6.8: Diagrama de classes representando classes.
Diagrama de classe simples, classe template e abstrata. Diagrama de classe persistente detalhada com atributos e mtodos.

Nome da classe

Classe
<<persistente>>

ClasseAbstrata
Nome dos atributos +atributo Nome dos mtodos +Mtodo() Assinatura

Classe
+atributoPublico: tipo = valor #atributoProtegido -atributoPrivado +atributoDeClasse +... +Metodo(P1:Tipo=valor): TipoRetorno +MetodoDeClasse()

NomeTemplate:tipo <<esteretipo>>

Classe
+atributo +Mtodo() Diagrama de classe template

Tipo de acesso (visibilidade) +publico, #protegido, -privado

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

6.4. AOO MODELO ESTRUTURAL

123

6.4.5

Identica c ao de associa c oes

As associa co es representam relacionamentos estruturais (permanentes). Segundo [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006], uma rela ca o ou conex ao entre classes e uma associa ca o. Segundo esse autor, as associa co es correspondem muitas vezes a verbos est aticos ou locu co es verbais. O que inclui a posi ca o (com, parte de, contido em), as a co es (direciona), comunica co es (fala a), a posse (tem, parte de) e rela co es diretas (como trabalha para, casado com, gerencia). Uma liga ca o e uma inst ancia de uma associa ca o. Observe que a associa ca o aparecer a no diagrama de classes, e a liga ca o, no diagrama de objetos. As associa co es podem ser implementadas de v arias maneiras, mas as decis oes de implementa ca o devem ser mantidas fora do modelo de an alise. Veja a seguir exemplos de associa co es. Um jogador de futebol e uma bola s ao dois objetos independentes, mas se desejarmos um jogo de futebol, teremos esses dois objetos se relacionando, formando uma associa ca o. Quando um gerente solicita a um funcion ario a realiza ca o de uma determinada tarefa, existe uma associa ca o entre o gerente e o funcion ario. Senten cas para associa co es2 A UML representa associa co es n- arias utilizando losangos. As associa co es podem ser tern arias ou de ordem mais elevada, mas na pr atica a maioria e bin aria. Evite associa co es tern arias. N ao amontoe os atributos de uma classe de associa ca o em uma classe-alvo. Utilize associa co es qualicadas onde for poss vel. Evite associa co es 1:1; geralmente esta e uma associa c ao 1:0 ou 1:n, signicando que o objeto associado pode ou n ao existir. Como um nome de papel pode representar um atributo do objeto, ele n ao deve ter o mesmo nome dos atributos do objeto. Geralmente as associa co es s ao implementadas com a utiliza ca o de ponteiros, mas n ao devem ser representadas no modelo de objetos com ponteiros (veja o Cap tulo 15 Ponteiros e refer encias.). Uma rela ca o de uma classe consigo mesma e chamada de associa ca o un aria. Se uma associa ca o tem um lado com muitos elementos (*), mas estes s ao ordenados, podese utilizar o estere otipo{ordered}. O estere otipo {bag} indica um conjunto de objetos com repeti co es. O estere otipo {sequence} indica um conjunto de objetos ordenados com repeti ca o (como um <multiset>). Segundo [Blaha and Rumbaugh, 2006], os estere otipos {bag} e {sequence} indicam a possibilidade de liga co es m ultiplas para um par de classes. Em uma associa ca o qualicada, o objeto do lado muitos (*) pode ser identicado pelo atributo qualicador. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

124

6.4. AOO MODELO ESTRUTURAL

Senten cas para conserva c ao das associa co es corretas2 Depois de denidas as associa co es, deve-se vericar quais foram denidas incorretamente e descart a-las segundo os crit erios a seguir, [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006]: Descreva com clareza o que e a associa ca o, e n ao o porqu e de ela ocorrer. Um evento transiente n ao pode ser confundido com uma associa ca o (exemplo: uma batida entre um carro e uma moto). Na medida do poss vel, classes, atributos e associa co es devem representar informa co es diferentes. Se faltam informa co es, os m etodos n ao percorrem a associa ca o, os pap eis s ao muito/pouco abrangentes, ent ao a associa ca o e desnecess aria. Evite associa co es tern arias (entre tr es objetos). Subdivida-as. Normalmente, uma associa ca o s o aparece em um diagrama; uma classe, por sua vez, pode aparecer em mais de um diagrama, mostrando a rela ca o entre os diferentes diagramas. Dica: revise o diagrama de classes, incluindo as associa co es que foram identicadas (veja se ca o 6.4.6).

6.4.6

Diagrama de classes com associa c oes

Veja na Figura 6.9 como representar uma associa ca o. Observe que a associa ca o recebe um nome, podendo-se ainda denir o papel de cada classe que participa da associa ca o e sua multiplicidade. Se uma associa ca o for representada com uma seta, ela s o ser a executada na dire ca o da seta (unidirecional). Figura 6.9: Diagrama de classes representando associa c oes.
NomeAssociao papel de B nb papel de A na Representao de uma associao bidirecional.

Classe A
+atributo +Mtodo()

Classe B
+atributo +Mtodo()

Representao de uma dependncia. {nomeRestrio}

Class D

NomeDependncia

Class C Class E
Representao de restries: Uma restrio impe uma dada condio ao relacionamento indicado.

A seta indica a direo de execuo da associao.

Multiplicidade A multiplicidade e um tipo de restri ca o utilizada para indicar as quantidades de cada objeto em uma associa ca o (aparece no diagrama de classes). J a a cardinalidade indica Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.4. AOO MODELO ESTRUTURAL

125

por meio de n umeros as quantidades de cada objeto em uma liga ca o (aparece no diagrama de objetos). Na Figura 6.9, a multiplicidade da classe A e nA (n umero de objetos do tipo A) e, da classe B, nB (n umero de objetos do tipo B). Os valores de multiplicidade podem ser: 1 1..n 1..* 0..1 2..7 0..* * um um a n um a innito 0 ou 1 no m nimo 2 e no m aximo 7 0 a innito innito

Papel Quando uma associa ca o n ao e clara, pode-se colocar no diagrama de classes o nome da associa ca o e/ou o nome do papel exercido por cada classe. Um papel e utilizado para indicar a forma como a classe vai atuar em uma associa ca o. Deve ter um nome un voco, normalmente um substantivo, que identique com clareza o papel que a classe exerce na associa ca o. Em alguns casos um papel e uma restri ca o ao objeto. Por exemplo: uma empresa tem tr es secret arias, uma cuida da agenda do chefe, as outras duas trabalham na recep ca o. Observe que as tr es s ao secret arias, mas o papel de cada uma e diferente. Restri co es Em um modelo de objetos as restri co es estabelecem rela c oes funcionais entre objetos, classes, atributos e associa co es. Como exemplo de restri co es, podemos citar a restri ca o de que o raio de um c rculo n ao ultrapasse determinado valor, a restri ca o de s o poder desenhar dentro da area cliente de uma janela. Um modelo de objetos bem desenvolvido deve ter muitas restri co es. Veja na Figura 6.9 que as restri co es aparecem dentro de colchetes {}. A Figura ?? mostra que o aluno s o ser a aprovado se obtiver nota maior ou igual a seis. Dica: se um atributo apresenta uma multiplicidade n, como em uma seq u encia, ent ao o mesmo poder a ser implementado utilizando um container da STL, como <vector> ou <deque>.

6.4.7

Classe de associa c ao

No relacionamento de dois objetos, pode surgir uma propriedade que n ao pertence a nenhum dos objetos originais, s o existindo quando ocorre a intera ca o. Por exemplo: na intera ca o do objeto telha (matriz s olida) com o objeto uido (chuva) surge a propriedade tens ao interfacial. A tens ao interfacial e uma propriedade da associa ca o. Veja na Figura 6.10 a ilustra ca o de uma classe de associa ca o. Em alguns casos, a classe de associa ca o n ao e criada, e seus atributos e m etodos s ao movidos para classe A ou B. Isto deve ser evitado na etapa de an alise, principalmente quando a associa ca o e do tipo *..* (muitos para muitos).

6.4.8

Identica c ao de agrega c oes e composi c oes

Quando unimos v arios objetos simples para criar um objeto mais complexo, estamos utilizando uma agrega ca o, tamb em denominada estrutura todo-parte. Diz-se todo-parte em que todo representa o objeto composto e parte, uma das partes que o comp oem. Podemos dizer ainda uma parte de ou tem um. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

126

6.4. AOO MODELO ESTRUTURAL

Figura 6.10: Diagrama de classes representando classes de associa ca o.


Classe A
nome: tipo = valor associao

Classe B
nome: tipo = valor

Representao de classe de associao.

Classe de associao
+atributo: tipo = valor +Metodo(): tipo

Uma agrega ca o e uma propriedade transitiva, isto e, se A e parte de B e B e parte de C, ent ao A e parte de C. Uma agrega ca o e uma propriedade anti-sim etrica, ou seja, se A e parte de B, ent ao B n ao faz parte de A. Em alguns casos, os dois objetos s o podem existir simultaneamente. Uma agrega ca o pode ser recursiva, isto signica que um objeto pode conter um objeto de seu tipo. Se houver d uvida em rela ca o a um objeto ser ou n ao uma agrega ca o de outro, deve-se usar uma associa ca o. Composi c ao Uma composi ca o e uma agrega ca o forte, no sentido de que as partes s o poder ao ser constru das a partir do todo. No exemplo da Figura 6.11, um volante s o existiria como parte de um carro. Senten cas para conserva c ao das agrega co es e composi co es corretas2 Ser a uma agrega ca o se voc e usar a express ao parte de. Ser a uma agrega ca o se as opera co es executadas sobre um se propagarem para o outro. A propaga ca o ocorre quando uma opera ca o aplicada sobre um objeto se estende para os demais. Ser a uma associa ca o se os dois objetos forem normalmente considerados separados.

6.4.9

Diagrama de classes com agrega c oes e composi c oes

Veja na Figura 6.11 como representar agrega co es e composi co es. Observe que uma agrega ca o e representada com um losango na classe todo e uma composi ca o e representada como um losango cheio. Observe que podemos incluir o papel e a multiplicidade de cada classe. Tamb em podemos incluir um estere otipo.

6.4.10

Identica c ao de heran cas

Vimos na se ca o 3.6 o conceito de heran ca. A abstra ca o que utiliza o conceito de heran ca e poderosa, permitindo destacar o que e comum aos diversos objetos que comp oem a heran ca, sem deixar de levar em conta as suas particularidades. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.4. AOO MODELO ESTRUTURAL

127

Figura 6.11: Diagrama de classes representando agrega c oes.


Diagrama de classes representando agregaes. No exemplo, um carro tem portas, a multiplicidade 2-6 indica que um carro pode ter de 2 a 6 portas. A composio indica que o carro obrigatoriamente deve ter um volante. papel da parte na NomeAgregao <<composio>> papel do todo nb

Porta
+atributo +Mtodo() 2-6 <<agregao>>

Volante
+atributo +Mtodo()

Parte
+atributo +Mtodo()

Todo
+atributo +Mtodo()

Carro
+atributo +Mtodo() (b)

(a)

Neste ponto, podemos renar o diagrama de classes incluindo o conceito de heran ca. Realize primeiro a generaliza ca o e depois a especializa ca o. Generaliza c ao A generaliza ca o (bottom-up ) e realizada identicando-se atributos e opera co es semelhantes. No exemplo da Figura 6.12, um rel ogio e uma generaliza ca o de rel ogio cron ometro e rel ogio alarme. Especializa c ao Especializa ca o e a cria ca o de classes-derivadas (lhas) a partir de uma classe-base (pai). As classes-derivadas t em acesso a todos os m etodos e atributos da classe-base. A especializa ca o (top-down ) pode ser vericada por meio de frases substantivas compostas por diversos adjetivos relativos ao nome da classe (exemplo: l ampada incandescente, l ampada uorescente). Uma especializa ca o pode ter um nome como e um tipo de ou e um. No exemplo da Figura 6.12, um rel ogio cron ometro e um tipo de rel ogio que foi especializado. Na especica ca o do sistema podem ter sido denidos alguns subcasos, os quais s ao candidatos a heran ` ca. Senten cas para conserva c ao das heran cas corretas2 Se uma classe inclu da na heran ca n ao e um tipo de, ent ao ela deve ser eliminada da heran ca. Se a classe foi inserida na heran ca apenas para aproveitamento de c odigo, ela deve ser eliminada. Lembre-se que modica co es na classe-base t em impacto nas classes-derivadas e devem ser feitas com cuidado. Senten cas para solucionar problemas de heran ca m ultipla2 Veja a seguir dicas de [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006] para solucionar problemas de heran ca m ultipla: Se uma classe tem mais de um pai, isto e, heran ca m ultipla, poderemos eliminar problemas utilizando mecanismos de delega ca o (transferir responsabilidades). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

128

6.4. AOO MODELO ESTRUTURAL

Nos casos em que uma das classes-base e mais importante que as demais, podemos utilizar heran ca desta e delega ca o para as demais. Se uma das classes-base e o gargalo do desempenho, esta deve ser a superclasse. Dica: revise o diagrama de classes, incluindo as heran cas identicadas (veja se ca o 6.4.11).

6.4.11

Diagrama de classes com heran cas

Veja na Figura 6.12 como a UML representa as heran cas. Observe que a classe-base e mais gen erica, e as classes-derivadas s ao especializa co es da classe-base. A classe-derivada e um tipo de classe-base. Discriminador Em um diagrama de classes, um discriminador costuma indicar qual propriedade de um objeto est a sendo generalizada.

Figura 6.12: Diagrama de classes representando heran cas.


Exemplo

Base
+atributo +Mtodo() +MetodoAbstrato() Representao de uma herana. +hora

Relogio
+Hora(): int +Hora(int:horaCerta): void

<<Discriminador>> NomeHerana

RelogioCronometro
+tempoCronometro +TempoCronometro() +ZeraCronometro()

RelogioAlarme
+horaAlarme +alarmeAtivo +HoraAlarme(): int +HoraAlarme(horaCerta:int): void

Derivada_A
+atributo +Mtodo()

Derivada_B
+atributo +Mtodo()

(a)

(b)

RelogioCronometroAlarme

6.4.12

Identica c ao de classes abstratas e classes de interface

Na Figura 3.2 da se ca o 3.2, vimos que o encapsulamento envolve a separa ca o do que e vis vel ou n ao ao usu ario de um objeto. Esta separa ca o foi chamada de encapsulamento do objeto. O analista de sistema e respons avel por esta separa ca o, a qual envolve a identica ca o e deni ca o dos m etodos da classe que o usu ario poder a acessar. Esta deni ca o deve ser gen erica e consistente, pois erros no encapsulamento s ao trabalhosos para se corrigir. Depois de separar conceitualmente o que dever a ser p ublico e o que dever a ser privado, o analista usa, nos diagramas UML, o s mbolo + para indicar que o atributo/m etodo e p ublico (vis vel) e os s mbolos # e - para indicar, respectivamente, protegido (vis vel nas classesderivadas) ou privado (invis vel). Depois de feito o encapsulamento, temos denido de forma mais clara qual ser a a interface de acesso ao objeto. Neste ponto, a modelagem orientada a objeto disponibiliza o conceito de classe de interface. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.4. AOO MODELO ESTRUTURAL

129

Uma classe de interface e uma classe gen erica, que s o tem m etodos vis veis e costuma ser utilizada como classe-base de uma hierarquia de classes. Veja na Figura 6.13 que a vis ao do engenheiro de software e mais detalhada que a vis ao do usu ario, o qual v e apenas o que n ao foi ocultado e que est a disponibilizado na classe de interface. Lembre-se, quando voc e faz um programa, voc e utiliza bibliotecas externas, feitas por outros programadores/analistas. Neste caso, voc e e o usu ario, e n ao importa os detalhes de como a biblioteca foi montada, o que interessa e sua forma de uso, sua interface. Como exemplo de classes de interface, veremos as classes <stack> (se ca o 33.1), <queue> (se ca o 33.2) e <priority_queue> (se ca o 33.3). Dica: uma superclasse e a classe mais b asica de uma hierarquia de classes; normalmente e uma classe de interface. Figura 6.13: Classe de interface.
Representao de uma classe de interface. A interface informa o que pblico e pode ser acessado pelo usurio. Eng. Software Viso do Engenheiro de software

NomeClasse
+atributoVisvel -atributoInvisvel +MtodoVisivel() -MtodoInvisvel() MtodoImplementacao ()

NomeClasse
+MtodoVisivel()

Uma classe de interface, no tem atributos, apenas mtodos pblicos. Usurio Viso do Usurio

A linguagem C++ permite a montagem de classes de interfaces e de classes abstratas. A diferen ca e que uma classe abstrata tem pelo menos um m etodo virtual puro, um m etodo que e declarado mas n ao e implementado. Como conseq u encia, uma classe abstrata n ao pode ser utilizada para criar objetos. Senten cas para elaborar classes abstratas2 Veremos a seguir dicas de [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006] para elaborar classes abstratas: Acesse todos os atributos de uma classe somente pelo envio de mensagens. As classes car ao mais abstratas quando dependerem menos das suas representa co es de dados. Identique mensagens e m etodos comuns e migre-os para uma classe-base. Isto pode criar a necessidade de quebrar m etodos e dividi-los entre classe-base e classes-derivadas. Elimineos m etodos de uma superclasse que s ao freq uentemente sobrescritos em vez de herdados por suas classes-derivadas. Isto torna a superclasse mais abstrata e conseq uentemente mais u til. Trabalhe classes-derivadas para serem especializadas. Uma classe-derivada ser a especializada se herdar todos os m etodos da clase-base e acrescentar novos a si pr opria. Uma classe-derivada sempre representa um superconjunto da classe-base. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

130

6.4. AOO MODELO ESTRUTURAL

O conceito de fatora ca o envolve a cria ca o de sub-rotinas que ser ao acessadas por um m etodo da classe-base e ser ao implementadas de forma diferente pelas classes-derivadas. Subdivida um m etodo em sub-rotinas que ser ao diferentes para as diversas classes-derivadas. Dica: revise o diagrama de classes (veja se ca o 6.4.4), incluindo as classes abstratas que foram identicadas.

6.4.13

Restri c oes

Uma restri ca o e uma condi ca o booleana aplicada a atributos, m etodos, classes, associa co es e pacotes. Por exemplo: o atributo {umAluno.nota < = 10} tem como resultado um valor 0 ou 1. A porta de uma casa pode ser aberta se n ao estiver trancada (chaveada) ou se tivermos a chave. Observe que restri co es s ao colocadas dentro de chaves {}, podendo-se ainda estar descritas dentro de notas. A linguagem de restri co es de objeto (OCL Object Contraint Language) utiliza express oes como umRelogio.Hora(horaCerta) para percorrer/navegar sobre o conjunto de classes do sistema. A OCL e utilizada para identicar falhas e inconsist encias no sistema. Veja a seguir um exemplo de uma express ao OCL extra da de [Blaha and Rumbaugh, 2006]: umaContaCart ao.Extrato.Transa co es->Select(umaDataInicial == dataTransa ca o and dataTransa ca o <= umaDataFinal).

6.4.14

Realiza c oes

Uma realiza ca o e um tipo especial de heran ca em somente os m etodos s ao herdados. Normalmente uma realiza ca o e uma classe que implementa os m etodos declarados mas n ao denidos em uma classe de interface.

6.4.15

Depend encias

Como visto, as associa co es, agrega co es e heran cas representam aspectos estruturais das rela co es entre objetos. As depend encias representam rela co es de uso. Uma depend encia e representada por uma seta tracejada que parte da classe que executa o m etodo de interesse (exemplo: MinhaJanela - - ->biblioteca Qt), assim como mostra aFigura 6.30. Observe que se a classe MinhaJanela depende da biblioteca Qt, mudan cas na biblioteca Qt podem implicar em mudan cas na classe MinhaJanela.

6.4.16

Identica c ao de objetos

um conceito, Um objeto e simplesmente algo que faz sentido no contexto de uma aplica ca o. E uma abstra ca o, algo com limites n tidos e signicativos em rela ca o ao problema. Se a exist encia independente de uma entidade for importante e n ao apenas o seu valor, ent ao ela e um objeto. Neste momento voc e pode reler as se co es 2.1, 2.2 e 2.3. Dica: monte diagramas de objetos para testar o relacionamento dos diversos objetos (veja se ca o 6.4.17). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.4. AOO MODELO ESTRUTURAL

131

6.4.17

Diagrama de objetos

O diagrama de objetos e basicamente o diagrama de classes, mas apresenta as inst ancias dos objetos criados, isto e, descreve os valores dos atributos assumidos por determinados objetos e seus relacionamentos em um dado momento. Serve para auxiliar os diagramas de comunica ca o em uma etapa de teste. Inclui itens como objetos e liga co es, notas, restri co es e pacotes. Veja na Figura 6.14 a representa ca o de um diagrama de objetos. Observe que o objeto pode estar ativo ou inativo, pode ser uma inst ancia simples ou m ultipla, pode ou n ao ter seus atributos descritos e pode incluir estere otipos. Qualicador usada na repreUm qualicador, uma qualica ca o inter-relaciona classes de objetos. E senta ca o das inst ancias da classe.

Figura 6.14: Diagrama de objetos representando objetos e inst ancias.


Representao de objetos simples, de instncias simples ou mltiplas, objetos ativos ou inativos.

Objeto

<<esteretipo>> Objeto inativo (borda fina) instncia simples [estado explcito] atributos

<<esteretipo>> Objeto inativo instncia mltipla [estado explcito] atributos

<<esteretipo>> Objeto ativo (borda grossa) instncia mltipla [estado explicito] atributos

6.4.18

Diagrama de estrutura composta

um diagrama estrutural usado O diagrama de estrutura composta foi inclu do na UML 2. E para detalhar o relacionamento dos elementos internos de uma classe, componente ou m odulo do constru sistema. E do a partir da composi ca o de elementos e pode ser utilizado para descrever o relacionamento dos atributos de classes complexas. Por exempo: dentro de uma classe Pessoa, como se relacionam as propriedades: endere co, telefone, e-mail, nome, idade, sexo etc. Veja na Figura ?? um diagrama de estrutura composta da classe de simula ca o de um reservat orio de petr oleo (SimReservat orio).

6.4.19

Resumo dos diagramas do modelo estrutural

Vimos que o diagrama de classes e um diagrama em que constam as classes, seus atributos, m etodos, e relacionamentos. O diagrama de classes e o mais importante para o desenvolvedor pois e utilizado pelos programas modeladores, como o umbrello , para montagem do c odigo inicial do programa. Veremos como montar o c odigo inicial do programa usando o umbrello na se ca o 6.8.2. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

132

6.4. AOO MODELO ESTRUTURAL

O diagrama de objetos e pouco utilizado, normalmente os diagramas de caso de uso s ao transformados em diagramas de comunica ca o, mostrando a rela ca o entre o usu ario e os objetos internos. O diagrama de estrutura composta foi introduzido a partir da UML 2 e objetiva detalhar as rela co es e comunica co es entre os atributos e m etodos de uma mesma classe, bem como os elementos internos do objeto se relacionam. Ademais, deve ser utilizado para detalhar o funcionamento de objetos complexos.

6.4.20

Itera c ao

Observe na Figura 5.1 que, ap os a cada etapa realizada, deve-se realizar uma itera ca o, a qual consiste em analisar as diversas etapas anteriormente realizadas, com o objetivo de encontrar e eliminar erros, de lembrar pontos esquecidos e de vericar a coer encia do modelo. Segundo [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006], os seguintes itens devem ser vericados: Identicados classes e objetos, voc e deve criar um dicion ario, com o nome de cada classe/objeto e a descri ca o em um par agrafo do que e e representa cada um deles. Verique se os casos de uso foram detalhados e se suas necessidades foram resolvidas. Verique se h a classes desnecess arias (sem atributos e m etodos). Verique se h a atributos e m etodos deslocados. Verique se os atributos e os m etodos s ao compat veis. Verique se os m etodos t em acesso; se n ao tiverem, est ao faltando associa co es. Verique se h a associa co es repetidas. Verique a presen ca de assimetrias nas associa co es e generaliza co es. Teste os diversos caminhos do modelo obtido para vericar sua consist encia e completude. Depois de corrigido o modelo, podemos agrupar as classes e os m odulos que t em algum sentido l ogico em comum em um diagrama (diagrama de pacotes). Se nos requisitos n ao foram inclu dos dados relativos ao desempenho do sistema, este e um bom momento. Classes, atributos, m etodos e associa co es criados foram documentados?

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

6.5. AOO MODELO DINAMICO

133

6.5

AOO Modelo din amico

O modelo din amico e utilizado na descri ca o das transforma co es dos objetos em rela ca o ao tempo, preocupando-se com o controle da execu ca o, sua seq u encia. Representa a evolu ca o da execu ca o do programa, as respostas do programa aos eventos gerados pelo usu ario. Preocupa-se com aspectos como os eventos, as mensagens e suas seq u encias, as comunica co es e colabora co es entre objetos e subsistemas, as mudan cas de estados e a realiza ca o de atividades. Todo programa que envolva intera ca o e tempo, ou ainda interface gr aca com o usu ario e controle de processos, deve ter um bom modelo din amico, o qual pode ser constru do com diagramas de seq u encia (se ca o 6.5.2), de comunica ca o (se ca o 6.5.3), diagramas de m aquina de estado (se ca o 6.5.5) e diagramas de atividade (se ca o 6.5.7). Reveja o relacionamento dos diagramas do modelo din amico na Figura 4.3. Veja a seguir como identicar os eventos e mensagens e como implementar o modelo din amico e seus diagramas.

6.5.1

Identica c ao de eventos e mensagens

Um evento pode ser um est mulo externo provocado pelo usu ario ao pressionar o mouse ou ao selecionar um item de menu. Pode ser provocado por um outro programa ou pelo sistema operacional. Um evento induz a modica ca o do estado de um ou mais objetos, representa uma a ca o que ocorre em determinado tempo e tem dura ca o zero. Os eventos incluem toda e qualquer intera ca o do usu ario com o programa (sele co es de menu, entrada de dados, pressionamento do mouse etc.), decis oes, interrup co es, transi co es, a co es de ou para usu arios de dispositivos externos. Segundo [Blaha and Rumbaugh, 2006], os eventos freq uentemente correspondem a verbos conjugados no passado ou ao come co de alguma condi ca o. Uma mensagem especica uma comunica ca o entre objetos; s ao o meio pelo qual os objetos interagem, [Pressman, 2002]. Uma mensagem pode ser enviada de um objeto para outro, transferindo informa co es (inclui o objeto destino, o m etodo a ser executado e seus par ametros). Por exemplo: quando o usu ario clica no cone impressora ele gera um evento. O sistema que controla o processamento das entradas do usu ario associa a este evento uma mensagem que efetivar a a chamada do m etodo de impress ao. Senten cas para eventos Um evento e uma ocorr encia u nica, isto e, distinta das demais. Ocorre em um determinado momento; a hora em que determinado evento ocorre e um atributo do evento. Um evento n ao retorna um valor. Os eventos simples n ao transportam par ametros, mas a maioria transporta algum tipo de par ametro. Um evento pode ser gerado por um ator e se dirigir a um objeto, a um conjunto de objetos, ou a outro ator. Tamb em pode ser gerado por um objeto e ter como destino outro objeto ou ator. Os eventos podem ser agrupados segundo propriedades comuns. Voc e deve juntar os eventos que atuam de forma semelhante sobre o uxo de controle e dar-lhes nomes semelhantes, mesmo se os valores dos par ametros diferirem. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

134

6.5. AOO MODELO DINAMICO

Se dois eventos n ao s ao relacionados de forma causal, eles s ao chamados concorrentes um n ao tem efeito sobre o outro, n ao existe uma rela ca o temporal entre eles (ordem de execu ca o).

Nossa an alise e que transforma um determinado evento em um evento de erro, ou seja, n os e que interpretamos o evento como sendo um erro.

Pode-se especicar a data e hora em que determinado evento ocorrer a, ou usar um timer para gerar eventos a cada intervalo de tempo. Pode-se descrever que um evento ocorrer a dentro de um determinado tempo (exemplo: ap os 10s).

Os eventos s ao mais expressivos que os m etodos, porque o efeito de um evento n ao depende somente da classe do objeto, mas tamb em de seu estado.

Dica: monte diagramas de seq u encia (veja a se ca o 6.5.2) e/ou diagramas de comunica ca o (se ca o 6.5.3).

6.5.2

Diagrama de sequ encia eventos e mensagens

O diagrama de seq u encia enfatiza a troca de eventos e mensagens e sua ordem temporal. Cont em informa co es sobre o uxo de controle do programa. Costuma ser montado a partir de um diagrama de caso de uso e estabelece o relacionamento dos atores (usu arios e sistemas externos) com alguns objetos do sistema. Veja o prot otipo de um diagrama de seq u encia na Figura 6.15, no qual incluimos um ator, sua linha de vida (linha vertical pontilhada), uma mensagem, um objeto que receber a a mensagem. Observe que a linha de vida do objeto ca cheia quando ele est a realizando algum processamento (ativo). Veja que uma mensagem pode incluir sua ordem de execu ca o, o evento que a gerou, condi co es (ou restri co es), itera co es (representadas pelo s mbolo *) e o retorno.

Mensagens podem ser ass ncronas (quando n ao bloqueiam o chamador).

Em um diagrama de seq u encia as mensagens de retorno s ao optativas e s ao representadas com linha tracejada. Aconselha-se a inclus ao da u ltima mensagen de retorno, de forma a deixar claro a naliza ca o da tarefa. Se existir processamento paralelo, as instru co es de retorno devem ser inclu das. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.5. AOO MODELO DINAMICO

135

Figura 6.15: Diagrama de seq u encia elementos.


Representao de um diagrama de sequncia: eventos e mensagens

Objeto O ator clica em um item de menu enviando uma mensagem para o objeto.

Linha de vida

Ator evento: {condio} Mensagem: Mtodo() Linha tracejada indica objeto inativo

evento: Mensagem de retorno: valor

Linha cheia indica processamento, o objeto esta ativo

O X indica fim da vida do objeto

Veja na Figura 6.16 um exemplo de diagrama de seq u encia. Observe que um evento gerado pelo ator, o professor, provoca o envio de uma mensagem para o objeto prova. Neste exemplo, o professor est a montando uma prova: primeiro separa uma folha de papel (cria a prova), a seguir cria mentalmente as quest oes e depois as adiciona ` a prova. Quando a prova est a pronta, o professor a entrega para o aluno. O aluno faz a prova, devolve-a para o professor e ent ao aguarda o resultado. O professor corrige a prova e ent ao mostra-a para o aluno (veja diagrama de m aquina de estado do aluno na Figura 6.20). Observe que uma mensagem pode ser enviada para o pr oprio objeto (autochamada). O aluno emite para si mesmo a mensagem, prestar aten ca o. Observe que temos uma prova, v arias quest oes e v arios alunos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

136

6.5. AOO MODELO DINAMICO

Figura 6.16: Diagrama de seq u encia montando uma prova.


Diagrama de sequncia (eventos e mensagens)

Aluno Ator Professor Mensagem <<create>> <<create>> Objeto Questo fazendo prova Prova

adiciona <<create>>

adiciona revisar e imprimir entregar prova prestar ateno

Autochamada devolver corrigir mostrar nota destruio

Na Figura 6.17 mostramos a seq u encia para c alculo da area de uma fun ca o. Depois de criar o objeto do tipo Simulador, com nome SimAreaFuncao, executamos a fun ca o pol tica Run(), respons avel pelo gerenciamento do c alculo da area da fun ca o. O simulador cria um objeto fun ca o, um objeto de integra ca o e em seguida chama o m etodo Area() do objeto de integra ca o passando como par ametro a fun ca o. A area e determinada. Por m, podemos solicitar ao programa externo Gnuplot a plotagem de gr acos da fun ca o.

Figura 6.17: Diagrama de seq u encia seq u encia para c alculo da area de uma fun ca o.
funo : Funcao : Ator-usurio : SimAreaFuncao() : Run() integral : Integral : SimAreaFuncao gnuplot : Gnuplot

: Funcao()

: Integral() : Area(ptrFuncao : Funcao*) : double

: operator()(_x : double) : double

: Gnuplot()

: Plot()

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

6.5. AOO MODELO DINAMICO

137

6.5.3

Diagrama de comunica c ao colabora c ao

No diagrama de comunica ca o o foco e a intera ca o e a troca de mensagens e dados entre os objetos. Veja na Figura 6.18 uma representa ca o do diagrama de comunica ca o equivalente ao diagrama de seq u encia da Figura 6.16. Observe que a seq u encia de execu ca o e dada por n umeros. O diagrama de comunica ca o pode ser utilizado em uma etapa de testes l ogicos ou conceituais dos modelos desenvolvidos. Observe que o diagrama de comunica ca o pode ser desenvolvido como uma extens ao do diagrama de caso de uso, detalhando o caso de uso por meio da inclus ao dos objetos, mensagens e par ametros trocados entre os objetos. O diagrama de comunica ca o inclui atores, objetos, mensagens e componentes do sistema. Objetos podem ser conectados por rela co es de associa ca o ou depend encia. As depend encias entre os n os representam rela co es de comunica ca o (podendo ser unidirecionais ou bidirecionais). Um diagrama de comunica ca o pode ser detalhado usando-se uma numera ca o como em 1; 1.1; 1.2; e assim por diante. Algumas ferramentas CASE podem gerar o diagrama de comunica ca o a partir do diagrama de eventos e vice-versa. [Fowler and Scott, 2000] consideram que o estudo de alternativas, isto e, varia co es nos diagramas de comunica ca o e seq u encia podem ser exploradas com o uso de cart oes CRC (veja se ca o 6.10.2).

Figura 6.18: Diagrama de comunica ca o montando uma prova.


5: prestar ateno Diagrama de comunicao. Use para fazer testes lgicos do funcionamento do programa. Professor Prova 2: adicionar questes a prova 3: revisar e imprimir a prova 7: corrigir a prova 1: criar questes 9: destruir questes Questo

4: entregar prova ao aluno 6: receber prova do aluno 8: mostrar nota

<<esteretipo>> Aluno veja diagrama de estado lista de atributos

Veja na Figura 6.19 uma representa ca o de um diagrama de comunica ca o equivalente ao diagrama de seq u encia da Figura 6.17. O diagrama de comunica ca o ilustrado na Figura 6.19 mostra a seq u encia para c alculo da area de uma fun ca o. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

138

Figura 6.19: Diagrama de comunica ca o seq u encia para c alculo da area de uma fun ca o.

6.5.4

Os valores assumidos pelos atributos de um objeto ao longo do tempo, a realiza ca o de uma atividade, ou a espera de um evento representam o estado do objeto. Segundo [Blaha and Rumbaugh, 2006], o estado e uma abstra ca o dos valores e liga co es de um objeto, normalmente correspondem a verbos no ger undio (esperando, discando). Um estado pode representar tanto caracter sticas ativas como passivas. Considere apenas atributos relevantes ao denir um estado. D e a cada estado um nome signicativo. O nome pode n ao ser necess ario se o estado for diretamente identicado.

i d i a g r m a e c o m n c a o u D : l I t n e g r a l d f c o r a e m n u u : . C F n c a o u : l ( ) I t n e g r a : 2 b i d ( ) d b l * A F F s e r q e a s e q n c a a p o r v u u t r e a p r n c a o n c a o o e u u u O : : : : ( ) F 3 n c a o u i j f t a o o n o : 1 . C i t g r l ) G t n p o u : l 4 G t p l c u . i l d s m a r l ( P r g n p : f P t o a r c o s 5
6.5. AOO MODELO DINAMICO

Identica c ao dos estados assumidos pelo objeto

Para ajudar na identica ca o dos estado, fa ca uma an alise de cada atributo do objeto. Por exemplo: o atributo temperatura da agua indica se a agua est a no estado s olido, l quido ou gasoso. Um estado pode sofrer altera co es qualitativas (transi ca o de estado) e quantitativas (transi co es internas). Uma altera ca o quantitativa representa qualquer altera ca o em um dos atributos do objeto, por exemplo, a altera ca o da temperatura da agua de 55 C para 54 C. J a uma altera ca o qualitativa representa uma altera ca o conceitual do objeto, como a altera ca o da temperatura da agua de 55 C (l quida) para -5 C (s olida). O estado depende de uma condi ca o (a temperatura da agua). Uma transi ca o de estado pode estar associada a um evento/mensagem ou a uma atividade que altere um atributo (por exemplo, uma atividade que altere a temperatura da agua). A transi ca o de estado e representada por uma seta. Transi co es internas s ao ocorr encias que podem alterar o valor de um atributo, mas n ao mudam o estado do objeto. Depois de considerar os eventos normais (default ), considere as exce co es (casos de erro). Se a seq u encia puder ser repetida indenidamente, ela formar a um la co. Sempre que poss vel, substitua seq u encias nitas por la cos. Um estado depende dos eventos anteriores, mas de modo geral os eventos anteriores s ao ocultados pelos posteriores. Lembre-se de que uma instru ca o fa ca: Xem um objeto pode ser um evento para outro objeto, ou seja, verique as instru co es, fa ca nos diversos objetos e verique se esta n ao representa um evento para outro objeto; caso represente, desenhe no outro objeto. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.5. AOO MODELO DINAMICO

139

Prepare um diagrama de m aquina de estado para cada classe de objetos com comportamento din amico importante (n ao trivial), mostrando os eventos que o objeto recebe e envia. Isto e, s o construa diagramas de m aquina de estados para classes de objetos com comportamento din amico signicativo (veja a se ca o 6.5.5 e a Figura 6.20).

6.5.5

Diagrama de m aquina de estado

Um diagrama de m aquina de estado representa os diversos estados que o objeto assume e os eventos que ocorrem ao longo de sua vida ou mesmo ao longo de um processo (hist orico do objeto). E usado para modelar aspectos din amicos do objeto. Elementos presentes em um diagrama de m aquina de estado s ao: Estado indica de forma abreviada o estado do objeto. Um exemplo de estado e a realizac a o de uma atividade demorada. Por exemplo: realizando entrada de dados, processando integra ca o, processando montagem dos gr acos (veja a Figura 6.21). Veja na Figura 6.20 (a) o prot otipo de representa ca o de um estado, o qual inclui: o nome do estado, a a ca o de entrada(entry), a atividade a ser realizada(do) e a a ca o de sa da(exit). Nome indica o nome do estado/atividade e deve ser u nico. entry a ca o de entrada, a ser executada quando entra no estado. do/atividade indica uma atividade em andamento. exit a ca o de sa da a ser executada quando sai do estado. Evento causa a transi ca o de estado (provoca execu ca o da a ca o que muda o estado do objeto). Condi c ao de guarda (guard condition) uma condi ca o de guarda imp oe algum tipo uma restri de restri ca o ` a transi ca o de estado. E ca o booleana, se verdadeira a a ca o que provoca a transi ca o de estado e executada. Uma condi ca o e representada entre colchetes {}. Por exemplo: um aluno s o ser a considerado aprovado se tiver obtido m edia nal maior que 6 (veja a Figura 6.20). A c ao todo m etodo que e executado quase instantaneamente e que est a associado a um evento e denominado a ca o (action ). As a co es podem representar opera co es internas de controle. A co es internas n ao mudam o estado do objeto. Quando as transi co es de um estado executam a mesma a ca o, pode-se vincular o estado ` a a ca o. A co es est ao associadas a transi co es. Veja na Figura 6.20 (b) um exemplo de diagrama de m aquina de estado para um aluno. Observe que este e formado por n os que representam os estados e setas que representam as transi co es entre os estados; observe tamb em como s ao representados o estado inicial e nal. Inicie a constru ca o do diagrama de m aquina de estado a partir dos diagramas de seq u encia; use os eventos oriundos dos casos de uso. Todo caso de uso corresponde a um caminho a ser seguido no diagrama de m aquina de estado, ou seja, deve-se comparar os diversos casos de uso e vericar os pontos em que eles divergem (e que precisam ser codicados no diagrama de m aquina de estados). Lembre-se de que dois caminhos em um diagrama de m aquina de estado ser ao os mesmos se o objeto esquecer os valores passados. Veja na Figura ?? os estados de uma thread e na Figura ?? os estados de um processo. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

140

6.5. AOO MODELO DINAMICO

Figura 6.20: Diagrama de m aquina de estado um aluno.


Diagrama de estado. Exemplo, diagrama de mquina de estado para um aluno matrcula recusada Notao para estado Fazendo Matrcula

incio

estado

mensagem preparao Estudando assistir aula

{matricula ok}

Nome do estado entry/entrada do/atividades exit/sada

Assistindo aula

rematricular realizar prova {mdia < 6} Reprovado aguardar

Diagrama de estados compostos ou subestados

Pode-se representar mais detalhadamente um estado, usando-se diagramas de estados compostos. Cada estado composto representa um subestado, semelhante a sub-rotinas. Compare as Figuras 6.21 e 6.22, observe que o estado processando integra ca o pode ser detalhado em sub-estados. No caso, inclu mos os sub-estados iniciando dados, calculando area e retornando resultados. Figura 6.22: Diagrama de m aquina de estado: Estados compostos do objeto simulador.

Programa ca o Orientada a Objeto com C++

i d i d a g r m a e m q n a e u D d t e s o : d I t r o c e s a n o n e g r a o P l i l e s o r u i ( ) / A t > n g r . C D l i d d d E D t e a n o n r a a o s z R d f i t r o c e s a n o m n a g e m g r c o s i> f / o c c o u D lo lo ( ) / P t > o g p u e g rP D ia d in d d d l i l d C t t t g r m a e m q a e s a o c m e s a o s c m p o s a s e m a o r u u : . D d f i t l i d d d E D t r o c e s a n o m n a g e m g r c o s e a n o n r a a o s z P R l l ( ) / P t iIn f / > o g p o o u > o c c o u D D e g r d t s a o d l d t t E e o r n a o r e s a o u ic d d a n o a o s R t c o m p s : D d P r e n o lu d c a a n o r a in g , a


fim Esperando resultado Fazendo prova descansar {3 < mediaParcial < 6} {mdia >= 6} Aprovado (a) (b) Fazendo recuperao

Figura 6.21: Diagrama de m aquina de estado estados do objeto simulador.

Andr e Duarte Bueno

6.5. AOO MODELO DINAMICO Diagramas de estados concorrentes

141

Podemos representar concorr encias e sincroniza ca o no interior de um objeto utilizando diagramas de m aquinas de estado. Uma concorr encia dentro de um estado subdivide o estado. Observe na Figura 6.23 que o processo de c alculo da area foi subdividido em dois processos concorrentes, podendo ser utilizado processamento paralelo. Veremos uma introdu ca o ao uso de cluster e a programa ca o paralela usando m ultiplas threads ou m ultiplos processos a partir do Cap tulo ?? Introdu ca o ` a Utiliza ca o de Clusters de Computadores. Figura 6.23: Diagrama de m aquina de estado estados concorrentes do objeto simulador.

Senten cas para diagramas de m aquina de estado2

Veja a seguir dicas de [Rumbaugh et al., 1994] para a constru ca o de um diagrama de m aquinas de estados. Um cen ario pode ajud a-lo a encontrar novos estados.

d l d t p e r s a o c a a n o r e a u u : S i d i d d t a g r m a e m q n a e s a o u : d l d t s a o c a a n o r e a u : D , E l d t e p o s a o s c o r n e s x d d t t r e p e n o c m s o E l P I P t o c n e r s s v ( ) p s c o n r . . b d s s a o u i d d I n c a n o a o s D d l P I I t r o c e a n o e r s m p a r e s v d l d t t e o r n a o r e s a o u R l i d E t e a n o r z R i> f / o c n c a o u b d s a oP u D d e g rs d f i t r o c e s a n o m n a g e m g r c o s lo lo ( ) / P t > o g p u D
Andr e Duarte Bueno

O diagrama de m aquina de estado da classe-base deve ser separado do diagrama de m aquina de estado da classe-derivada, o qual deve descrever os seus atributos. Verique a consist encia dos diversos diagramas de m aquina de estado e verique se os eventos compartilhados est ao coerentes. As liga co es entre os diversos diagramas de m aquina de estado s ao realizadas pelas mensagens e eventos compartilhados. Um diagrama de m aquina de estado pode representar ciclos de vida. No caso em que um objeto e criado, realiza determinados procedimentos e e eliminado. Pode representar la cos cont nuos quando o objeto e persistente (n ao e destru do). Um estado complexo pode ser dividido em diagramas de n vel inferior, denominados estados compostos ou subestados. Algumas simula co es de engenharia podem demorar v arios dias. Como os computadores falham (ocorrem quedas de energia), e importante criar mecanismos que permitam o rein cio da simula ca o do ponto em que parou. Para facilitar a cria ca o destes pontos, os diagramas de m aquina de estado acrescentaram o conceito de estado de hist oria, representado pela letra H. As informa co es do sistema s ao armazenadas de tal forma que permitam o rein cio da simula ca o a partir deste ponto. Releia a se ca o 1.3.3. O controle da interface do usu ario pode ser descrito em um diagrama de m aquina de estado. Programa ca o Orientada a Objeto com C++

142

6.5. AOO MODELO DINAMICO

Observe nas guras apresentadas que os gr acos de estado costumam ser descritos no ger undio (exemplo: mostrando, calculando, gerando). Concorr encias e sincroniza co es, conceitos utilizados em processamento paralelo, podem ser representados em diagramas de m aquina de estado (veja a Figura 6.23). Teste verique a consist encia do diagrama de m aquina de estado. Compare eventos entre objetos para vericar se o diagrama est a completo. Verique os erros de sincroniza ca o, por exemplo, quando uma entrada ocorre em um momento inadequado.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

6.5. AOO MODELO DINAMICO

143

6.5.6

Identica c ao de atividades

Como vimos nos diagramas de m aquinas de estado (se ca o 6.5.5), uma atividade e uma opera ca o que demora um determinado tempo, como, por exemplo, a solu ca o de um sistema de equa co es, o processamento de transa co es em um grande banco de dados, a simula ca o de um reservat orio de petr oleo, o processamento de sinais etc. Como uma atividade pode ser complexa, precisamos detalhar por meio de um uxograma como esta atividade vai ser realizada. Normalmente uma atividade e implementada por um m etodo de um determinado objeto, e detalhar o funcionamento da atividade corresponde a detalhar o funcionamento de determinada m etodo/fun ca o. Um m etodo deve ter precondi co es para seus dados de entrada e de sa da. Comece vericando os par ametros de entrada (tipo, valor-padr ao, valores m aximos e m nimos). Em seguida, verique se o retorno e adequado. Verique a l ogica de c alculo/processamento utilizada. Verique as estruturas de controle utilizadas (if, for, switch, case, do, while) (veja o Ap endice D). Verique as restri co es entre objetos. Uma restri ca o e uma depend encia funcional entre objetos. Dica: o detalhamento das atividades pode ser descrito com o uso dos diagramas de atividades (veja a se ca o 6.5.7).

6.5.7

Diagrama de atividades

O diagrama de atividades tamb em se preocupa com quest oes din amicas, mas em um n vel mais detalhado, sendo utilizado para descri ca o dos diversos m etodos das classes. Segundo [Blaha and Rumbaugh, 2006], um diagrama de atividades mostra a seq u encia de etapas que comp oem um processo complexo, como um algoritmo ou uxo de trabalho; seu enfoque s ao os m etodos e n ao os objetos. Isto e, o objetivo do diagrama de atividades e descrever algoritmos e funcionalidades complexas, detalhando um estado de atividade do diagrama de m aquina de estados. O diagrama de atividades se preocupa com os valores de entrada e sa da dos m etodos, como os atributos s ao alterados, as depend encias entre os m etodos. Em um diagrama de atividades os n os representam a co es ou atividades, e as linhas representam transi co es (uma transi ca o pode ocorrer quando a a ca o/atividade anterior foi completada). Os diagramas de atividades s ao especialmente importantes em areas como engenharia. O diagrama de atividades e baseado em redes de petri; e semelhante a um uxograma, a diferen ca e que ele permite que atividades sejam executadas paralelamente. Os elementos presentes em um diagrama de atividades s ao: Estado de a c ao descreve a atividade que est a sendo executada. Transi co es s ao setas que indicam que a atividade anterior terminou e que a nova atividade vai ser executada. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

144

6.5. AOO MODELO DINAMICO

Barra de sincroniza c ao (bifurca c ao/separa c ao) quando o m etodo admite processamento paralelo, utilizamos barras de sincroniza ca o para indicar uma separa ca o dos processos. Barra de sincroniza c ao (aglutina c ao/jun c ao) a barra de sincroniza ca o e utilizada ainda para representar a aglutina ca o de uma atividade. Losangos losangos s ao utilizados para indicar tomadas de decis ao, uso de estruturas de controle, como um if, um switch. Uma breve descri ca o sobre a decis ao pode ser inclu da utilizando-se anota co es.

A Figura 6.24 mostra em (a) o prot otipo de um diagrama de atividades. Observe que est ao presentes os indicadores de in cio e m da atividade (os mesmos do diagrama de m aquinas de estado), losangos para tomada de decis ao, bifurca co es e aglutina co es (utilizadas para indicar processamento concorrente) e as atividades. A Figura 6.24 (b) mostra o diagrama de atividades de um m etodo de binariza ca o (transforma uma imagem em tons de cinza ou colorida em imagem preto/branco). Observe que se a imagem j a estiver binarizada o m etodo n ao faz nada. Se a imagem e em tons de cinza, chama o m etodo que binariza imagens em tons de cinza e, se for imagem colorida, chama o m etodo que binariza imagens coloridas. Observe que e um m etodo pol tico e envolve apenas tomadas de decis oes. O processamento ser a feito em m etodos auxiliares.

Figura 6.24: Em (a) o prot otipo de um diagrama de atividades. Em (b) o diagrama de atividades de um m etodo de binariza ca o.
O diagrama de atividades se preocupa com os detalhes de implementao dos mtodos. O que ocorre dentro de cada mtodo importante. incio Atividade No exemplo um mtodo de binarizao.

separao bifurcao [ Imagem Binarizada ] Tomada de deciso Atividade [ Imagem Cinza ] [false] [true] [ Iterativo ] Atividade Atividade Executa mtodo iterativo Executa mtodo direto [ Direto ] Executa binarizao de imagem Cinza [ Imagem Colorida ]

aglutinao unio, juno fim (a) (b)

A Figura 6.25 mostra o diagrama de atividades para o m etodo do Trap ezio. O mesmo e utilizado para calcular a area de uma fun ca o. Observe que toda seq u encia de c alculo e detalhada. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.5. AOO MODELO DINAMICO

145

Figura 6.25: Diagrama de atividades m etodo do Trap ezio para c alculo da area.
Diagrama de Atividades: Classe: IntTrapezio Mtodo: Area() Mtodo de clculo Recebe intervalo integrao e funo f,xmax,xmin,numeroIntervalos dx=(xmax-xmin)/numeroIntervalos

faz x=xmin, Area=f(x).dx/2

x >= xmax x < xmax

Area = Area +f(x).dx/2

x = x + dx

y=f(x)

Area = Area + y.dx

Diagrama de atividades com raias de nata c ao O diagrama de atividades pode apresentar linhas verticais (raias de nata ca o) separando os diferentes objetos. O uso de raias de nata ca o permitem a visualiza ca o da execu ca o de seq u encias de troca de mensagens e dados entre objetos. Como pode incluir barras de bifurca ca o e aglutina ca o, pode ser utilizado para representar processamentos paralelos. Veja o exemplo na Figura 6.26. Nele, o usu ario externo cria um objeto simulador e em seguida roda a simula ca o. O objeto simulador cria um objeto fun ca o e um objeto integrador, dene seus atributos e logo ap os inicia o c alculo da area da fun ca o. O simulador identica a presen ca de dois n os (de um cluster) e separa o calculo da area em dois intervalos, i e j. Depois de calculada a area, o simulador envia para o programa externo gnuplot o comando para gerar e plotar os gr acos. O resultado nal e analisado pelo usu ario. Figura 6.26: Diagrama de atividades uso de raios de nata ca o.

Programa ca o Orientada a Objeto com C++

i l t 2 1 g n p o s r o u u U N N i l d S l i l d m a o r u a c a p r m e r o a c a s e g n o u u u C C i i t t n e r o n e r o v v i l d S r a m a o r u C d i i b j f o t r a o e o n o u R C i e g r a f i l t t e n r e r a o n o v D l F a c e u u C l i I t l j I r e a n e r a o t v r e a n e r a o v A A l f i f i t o a r g c o s e r a g r c o s P G lis lt d t n a r e s a o s o s u A R M
Andr e Duarte Bueno

146

6.5. AOO MODELO DINAMICO

Diagrama de atividades e envio de sinal para dispositivos externos O diagrama de atividades pode incluir ainda ret angulos com pontas triangulares, os quais s ao utilizados para indicar o envio/recebimento de sinais de/para sistemas externos. Veja na Figura 4.5 os elementos utilizados pela UML para representar o envio/recebimento de sinais.

6.5.8

Diagrama de tempo

Mostra mudan cas no estado ou papel de uma classe ao longo do tempo; e util para descrever processos temporais.

6.5.9

Diagrama de intera c ao geral

um diagrama que mistura elementos do diagrama de m E aquinas de estado, de seq u encia, de comunica ca o e de pacotes, objetivando detalhar toda intera ca o de um determinado cen ario de uso do programa.

6.5.10

Resumo dos diagramas do modelo din amico

Observe que com os diagramas din amicos temos representadas todas as caracter sticas din amicas do sistema e dos objetos. Os diagramas de seq u encia e de comunica ca o se preocupam com a troca de dados entre objetos e atores do sistema, a intera ca o dos objetos em um n vel mais macro. O diagrama de m aquinas de estado e focado nos estados assumidos pelo objeto e suas transi co es (valores dos atributos), os poss veis comportamentos do objeto. O diagrama de atividades se preocupa com o que ocorre dentro de cada m etodo da classe, detalhando seu funcionamento (a microdin amica do sistema, os algoritmos). O diagrama de tempo mostra varia co es de um objeto ao longo do tempo. J a o diagrama de intera ca o geral e uma mescla de v arios diagramas, sendo usado para detalhar um determinado cen ario.

6.5.11

Itera c ao

Observe na Figura 5.1 que, ap os cada etapa realizada, deve-se realizar uma itera ca o. Os seguintes itens devem ser vericados: Revise os diagramas de seq u encia e de comunica ca o. Voc e incluiu diagramas de m aquinas de estados para as classes complexas? Algoritmos complexos foram montados utilizando os diagramas de atividades? A estrutura de um modelo din amico e estreitamente relacionada com o modelo estrutural. Os eventos podem ser representados como m etodos no modelo estrutural. A hierarquia de estados de um objeto e equivalente a um conjunto de restri co es do modelo estrutural. Voc e vericou o efeito da modelagem din amica nos diagramas estruturais? Conra as rela co es entre os diagramas din amicos e os m etodos nas classes. Voc e incluiu nos diagramas os casos excepcionais? As entradas erradas? Falhas no sistema? Problemas com hardware? Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.5. AOO MODELO DINAMICO

147

Teste terminado o modelo din amico, fa ca o teste l ogico (veja o item 3, na se ca o 6.9). Dica: otimiza ca o o modelo din amico deve incluir a identica ca o dos pontos do programa que merecem ser otimizados. Isto pode ser feito baseando-se na an alise dos diagramas de atividade (veja a se ca o 6.5.7) e na an alise dos algoritmos que precisam ser implementados. Identique pontos concorrentes e que podem ser executados em paralelo. Comece fazendo uma pesquisa na internet por bibliotecas similares; veja como os outros resolveram a quest ao da otimiza ca o de determinado algoritmo. Na etapa de implementa ca o, voc e pode utilizar um proler (veja o Cap tulo ?? Auditoria e Otimiza ca o de Programas) para identicar os gargalos de desempenho.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

148

6.6. PROJETO DO SISTEMA

6.6

Projeto do sistema

Depois da an alise orientada a objeto desenvolve-se o projeto do sistema, qual envolve etapas como a deni ca o dos protocolos, da interface API, o uso de recursos, a subdivis ao do sistema em subsistemas, a aloca ca o dos subsistemas ao hardware e a sele ca o das estruturas de controle, a sele ca o das plataformas do sistema, das biblitoecas externas, dos padr oes de projeto, al em da tomada de decis oes conceituais e pol ticas que formam a infraestrutura do projeto. Deve-se denir padr oes de documenta ca o, padr oes para o nome das classes, padr oes de retorno e de par ametros em m etodos, caracter sticas da interface do usu ario e caracter sticas de desempenho. Segundo [Rumbaugh et al., 1994, Blaha and Rumbaugh, 2006], o projeto do sistema e a estrat egia de alto n vel para resolver o problema e elaborar uma solu ca o. Voc e deve se preocupar com itens como: 1. Protocolos Deni ca o dos protocolos de comunica ca o entre os diversos elementos externos (como dispositivos). Por exemplo: se o sistema envolve o uso dos n os de um cluster, devem ser considerados aspectos como o protocolo de comunica ca o entre os n os do cluster. Deni ca o dos protocolos de comunica ca o entre os diversos elementos internos (como objetos). Deni ca o da interface API de suas bibliotecas e sistemas (veja a se ca o 6.6.1). Deni ca o do formato dos arquivos gerados pelo programa. Por exemplo: prera formatos abertos, como arquivos txt e xml. 2. Recursos Identica ca o e aloca ca o dos recursos globais, como os recursos do sistema ser ao alocados, utilizados, compartilhados e liberados. Implicam modica co es no diagrama de componentes (veja a se ca o 6.7.1). Identica ca o da necessidade do uso de banco de dados. Implicam em modica co es nos diagramas de atividades e de componentes. Identica ca o da necessidade de sistemas de armazenamento de massa. Por exemplo: um storage em um sistema de cluster ou sistemas de backup. 3. Controle Identica ca o e sele ca o da implementa ca o de controle, seq uencial ou concorrente, baseado em procedimentos ou eventos (veja a se ca o 6.6.2). Implicam modica co es no diagrama de execu ca o (veja a se ca o 6.7.2). Identica ca o das condi co es extremas e de prioridades. Identica ca o da necessidade de otimiza ca o. Por exemplo: prera sistemas com grande capacidade de mem oria; prera v arios hds pequenos a um grande. Identica ca o e deni ca o de loops de controle e das escalas de tempo. Identica ca o de concorr encias quais algoritmos podem ser implementados usando processamento paralelo (veja a se ca o ??). 4. Plataformas Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.6. PROJETO DO SISTEMA

149

Identica ca o das estruturas arquitet onicas comuns. Identica ca o de subsistemas relacionados ` a plataforma selecionada. Podem implicar em modica co es no diagrama de pacotes (veja a se ca o 6.2.3) e no diagrama de componentes (veja a se ca o 6.7.1). Identica ca o e deni ca o das plataformas a serem suportadas: hardware, sistema operacional e linguagem de programa ca o (veja a se ca o 6.6.3). Sele ca o das bibliotecas externas a serem utilizadas (veja a se ca o 6.6.4). Sele ca o da biblioteca utilizada para montar a interface gr aca do programa GDI (veja a se ca o 6.6.5). Sele ca o do ambiente de desenvolvimento para montar a interface de desenvolvimento IDE (veja a se ca o 6.6.6). 5. Padr oes de projeto Normalmente os padr oes de projeto s ao identicados e passam a fazer parte de uma biblioteca de padr oes da empresa. Mas isto s o ocorre ap os a realiza ca o de diversos projetos. Nota: uma das maiores preocupa co es de simula co es de engenharia e o desempenho. A necessidade de se aliar desempenho, interface gr aca amig avel e reuso de bibliotecas limita o n umero de linguagens a serem utilizadas, de modo que C++ tem sido a mais indicada (veremos a otimiza ca o de programas no Cap tulo ?? Auditoria e Otimiza ca o de Programas, e t ecnicas de processamento paralelo a partir do Cap tulo ?? Introdu ca o ` a Utiliza ca o de Clusters de Computadores).

6.6.1

Deni c ao da interface de programa c ao API

Quando estamos desenvolvendo uma classe, um m odulo ou um sistema, precisamos denir sua interface de acesso. Uma API Application Programming Interface ou interface de programa ca o de aplica ca o e um conjunto de instru co es e informa co es sobre a forma como a biblioteca deve ser acessada. A API separa o que e p ublico (acess vel) do que e protegido ou privado (inacess vel). Na se ca o 3.2 e por meio da Figura 3.2, mostramos que a vis ao do que e publico e do que e privado depende da audi encia, isto e, de quem vai utilizar a classe/m odulo/sistema. Na pr atica isto signica que, quando formos denir as interfaces de nossos sistemas, precisamos denir claramente quem s ao seus usu arios (a audi encia). Por exemplo: a API de bibliotecas como Qt, GTK, MFC, VCL s ao desenvolvidas para programadores medianos. O protocolo e o conjunto de m etodos que podem ser acessados pelo usu ario, o conjunto de mensagens a que o objeto responde; ou seja, o protocolo e o conjunto de m etodos p ublicos da classe. Veja a seguir dicas de [Winblad et al., 1993] para melhorar os protocolos. Senten cas para melhorar os protocolos D e nomes similares ou id enticos a mensagens e m etodos quando uma classe se comunica com outras classes para realizar opera co es similares. Desenhe classes onde uma mensagem possa ser enviada diretamente para um objeto e manipulada corretamente pelos m etodos nele contidos. Finalmente, e importante montar a interface API de seu programa de modo que ela seja extens vel, reaproveit avel e que considere requisitos futuros. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

150

6.6. PROJETO DO SISTEMA

6.6.2

Sele c ao da implementa c ao de controle

O sistema ou subsistema de controle da execu ca o do software pode ser implementado de diferentes formas. Veja a seguir alguns exemplos: Se o sistema realiza seq u encias predenidas como em arquivos de lote (por exemplo, autoexec.bat, init.d), ou c alculos seq u enciais, ent ao o controle pode ser feito por arquivos ASCII, os quais determinam a seq u encia a ser realizada. Sistemas de reinicializa ca o do sistema podem ser inclu dos (veja a se ca o 1.3.1 e 1.3.2). Este tipo de sistema utiliza uma estrutura de controle chamada de transforma ca o em lote, bastante utilizada em procedimentos de engenharia, no processamento de transa co es banc arias (cheques) e transa co es agendadas. Um sistema com controle do tipo transforma ca o cont nua permite a realiza ca o de etapas de simula co es. Para cada bloco de tarefas executadas, o usu ario analisa os resultados obtidos e toma decis oes a respeito da seq u encia de execu ca o do sistema, ou seja, o usu ario pode alterar o uxo de execu ca o do programa. Veja a se ca o 1.3.3. Em uma interface interativa os usu arios interagem o tempo todo com o sistema (geralmente utilizando uma interface gr aca). De maneira geral, este tipo de controle e baseado em eventos e permite a execu ca o concorrente (pelo uso de m ultiplas threads e/ou processos). O acesso compartilhado aos recursos pode ser controlado por bloqueadores de acesso (mutex). Sistemas de software modernos com controle do tipo interface interativa utilizam listas e podem ter macros para execu ca o de atividades repetitivas (veja a se ca o 1.3.4). Sistemas cient cos e simula co es de engenharia (como processamento de dados, sinais e imagens, simula co es qu micas e ambientais) podem utilizar um dos tipos de controle acima denidos. Se a simula ca o e fechada (dados de entrada e sa da previamente denidos), pode-se utilizar tranforma ca o em lote. Se existem poucas necessidades de intera ca o com o usu ario use transforma ca o cont nua. Sistemas modernos de engenharia utilizam interface interativa, possibilitando um controle mais renado das simula co es a serem realizadas.

6.6.3

Sele c ao das plataformas a serem suportadas

Uma plataforma de programa ca o envolve o hardware, o sistema operacional e a linguagem de programa ca o. Veja a seguir alguns exemplos: Computador do tipo Macintosh sistema operacional Mac Os X linguagem C. Computador do tipo PC/Intel sistema operacional Windows linguagem C++. Computador do tipo Workstation/AMD - Opteron sistema operacional GNU/Linux linguagem C++. Um programa em ANSI C++ pode ser compilado em diversas plataformas. O procedimento e simples; basta copiar o c odigo-fonte para a plataforma-alvo e, em seguida, compilar os programas usando um compilador padr ao Ansi C++. Para facilitar a compila ca o de um programa em m ultiplas plataformas, as equipes de desenvolvimento da GNU desenvolveram os programas autoconf, automake e libtool (os quais ser ao descritos no Cap tulo ?? Introdu ca o ` a Programa ca o Multiplataforma com Software Livre). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.6. PROJETO DO SISTEMA

151

6.6.4

Sele c ao das bibliotecas externas

No projeto do sistema e necess ario denir quais bibliotecas externas ser ao utilizadas. A dica e utilizar bibliotecas reconhecidas e bem-documentadas, como as bibliotecas da GNU. Segundo [Korson and Macgregor, 92], uma biblioteca orientada a objeto deve: ter protocolos uniformes (nomes e assinaturas), focar um tema completo (fechado), mas considerando generalidades (aliando, na medida do poss vel, uniformidade, completude e generalidade). Tamb em deve permitir sua extens ao e ser eciente. Veremos na se ca o ?? as vantagens e as desvantagens do uso de bibliotecas externas. Veja a seguir alguns exemplos de bibliotecas externas. Exemplos de bibliotecas externas Bibliotecas da GNU, veja http://www.gnu.org. Bibliotecas disponibilizadas no site Scientic Applications on Linux (SAL), veja http://sal.linet.gr.jp/index.shtml. Bibliotecas disponibilizadas no site The Object-Oriented Numerics Page, veja http://www.oonumerics.org/oon/. Biblioteca magick++, apresentada na se ca o ??, veja http://www.simplesystems.org/Magick++/ . Biblioteca commom C++, apresentada na se ca o ??, veja http://www.gnu.org/directory/GNU/commoncpp.html . Biblioteca boost, apresentada na se ca o ??, veja http://www.boost.org/. Biblioteca de m etodos num ericos, veja http://users.physik.tu-muenchen.de/gammel/matpack/. Depois de selecionar as bibliotecas externas que utilizar a, e necess ario fazer o download/instala ca o da biblitoteca, ler os manuais do usu ario e a documenta ca o API, al em de estudar os exemplos que acompanham a biblioteca. A apresenta ca o das bibliotecas, seus conceitos, vantagens e desvantagens, como montar e como usar nossas pr oprias bibliotecas e como usar bibliotecas conhecidas ser ao vistas nos cap tulos e se co es abaixo: A se ca o 6.6.5 mostra a sele ca o da biblioteca gr aca a ser utilizada GDI. Na se ca o 6.11.5 apresentaremos algumas senten cas para montagem de bibliotecas. Na se ca o 6.11.6 veremos senten cas para montagem de frameworks. No Cap tulo ?? Bibliotecas, veremos como implementar nossas pr oprias bibliotecas. No Cap tulo ?? O Programa Libtool, veremos como implementar nossas pr oprias bibliotecas em sistemas multiplataforma. Veremos a partir do Cap tulo ?? Bibliotecas Uteis, exemplos de bibliotecas externas. Para desenvolver programas em um ambiente de janelas como o Windows, o Mac OS X, o GNOME ou o KDE, voc e ter a que escolher uma biblioteca gr aca. Veja na se ca o 6.6.5 uma discuss ao sobre a sele ca o de bibliotecas gr acas. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

152

6.6. PROJETO DO SISTEMA

6.6.5

Sele c ao da biblioteca gr aca a ser utilizada GDI

H a alguns anos desenvolvia-se um programa em computadores PC XT/AT, utilizando-se um ambiente em modo texto, pois n ao existiam janelas e cones. Mais recentemente, praticamente todos os programas utilizam janelas, cones, menus etc. e s ao desenvolvidos para plataformas computacionais como o PC/Windows Vista, esta co es de trabalho rodando Unix, GNU/Linux com interface gr aca padr ao MOTIF, GNOME, KDE, ou mesmo Macintosh rodando MAC OS System X. Desenvolver um programa For Windows, assim que se lan cou o Windows 3.0, era uma verdadeira calamidade, pois a API do Windows s o fornecia algumas fun co es b asicas, e o programador tinha que escrever praticamente tudo o que ia utilizar. Situa ca o semelhante ocorria com os demais ambientes de janelas. Desenvolver um programa para um ambiente de janelas tornou-se mais f acil, gra cas a bibliotecas de interfaces gr acas orientadas a objeto (GDI), como a Qt, a GTK, a VCL, a MFC, entre outras. Essas interfaces fornecem toda uma hierarquia de classes que podem ser imediatamente herdadas pelo seu programa. Voc e pode criar janelas, menus, bot oes, barras de ferramentas, entre outros objetos, com muita facilidade. Entretanto, para que se possa desenvolver um programa para um ambiente gr aco, e preciso aprender programa ca o orientada a objeto. Voc e s o conseguir a herdar e utilizar os objetos fornecidos pelas bibliotecas gr acas se compreender a programa ca o orientada a objeto e a sintaxe de C++ (veremos a sintaxe de C++ em detalhes a partir do Cap tulo 7 Introdu ca o ao C++.). Em 2007, as bibliotecas gr acas mais utilizadas no ambiente Windows s ao a VCL, do Builder, Delphi e a MFC, do Microsoft Visual C++. No ambiente GNU/Linux, as mais utilizadas s ao as bibliotecas Qt (da TrollTech/KDE) e a biblioteca GTK (da GNU/GNOME). Dica: d e prefer encia a bibliotecas que sejam livres e multiplataforma. Veremos no Cap tulo ?? A biblioteca Qt 4, exemplos de uso da biblioteca Qt.

6.6.6

Sele c ao do ambiente de desenvolvimento integrado IDE

Uma IDE e uma interface integrada para o desenvolvimento de programas e softwares avanc ados. Ela facilita a vida do programador, pois as diversas ferramentas a serem utilizadas compilador, editor de texto, linker, debuger, sistema de controle de vers oes, entre outros est ao integrados em uma u nica ferramenta. A seguir ser ao descritos alguns ambientes de desenvolvimento integrados utilizados nas plataformas Windows, Mac OS X, Unix e GNU/Linux. Windows Em se tratando de ambientes de desenvolvimento, pode-se dizer que o Borland C++, o Builder C++ e o Microsoft Visual C++ s ao programas bastante seguros e completos. Contam com geradores autom aticos de c odigo e visualizadores de classes. Um programa GPL (software livre) simples e bom e o Dev C++. Mac OS System X O Mac OS System X e um sistema operacional compat vel com os sistemas Unix e GNU/Linux, de forma que programas feitos utilizando bibliotecas multiplataforma, como a Qt ou GTK, rodar ao no seu Mac OS X. Um ambiente de desenvolvimento bastante conhecido pelo pessoal que usa Mac e o Code Warrior Metroworks. GNU/Linux (Unix) Nos u ltimos anos os ambientes de desenvolvimento do GNU/Linux sofreram diversos Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.6. PROJETO DO SISTEMA

153

aperfei coamentos. Distribui co es do GNU/Linux incluem diversos pacotes para aux lio ao desenvolvimento de software em C++, podendo-se citar: controle de vers oes (cvs, subversion, cervisia ), auditoria de software (gprof, callgrind, oreport, valgrind, kcachegrind, chainsaw ), debugagem (gdb, ddd ), interfaces integradas de desenvolvimento (kdevelop, Eclipse, glade, QtDesigner), e utilit arios (Kbabel, emacs, kbugbuster ). A programa ca o para software livre e GNU/Linux ser a discutida na parte IV do livro. Dica: veja na Revista Linux, edi ca o 29, uma lista auxiliar de ambientes de desenvolvimento para GNU/Linux. Procure o endere co: http://www.revistadolinux.com.br/ed/029/assinantes/desenvolvimento.php3. A Linux Magazine, n umero 12, apresenta a reportagem Ferramentas de Desenvolvimento An alise. Ambientes de desenvolvimento A seguir ser a apresentada uma lista de ambientes de desenvolvimento. Abra o site indicado e verique quais s ao as plataformas suportadas. Microsoft Visual C++ .NET 2003 uma IDE completa que usa a biblioteca de classes MFC (Microsoft Foundation Classes). E Veja a seguir as principais caracter sticas do Visual C++, as quais foram extra das do site da Microsoft. Conformidade do C++ com as normas ISO; otimiza co es atualizadas do compilador; verica co es aperfei coadas de seguran ca do buer; Windows Forms Designer; melhor diagn ostico do compilador; depura ca o aperfei coada no C++; documenta ca o expandida e amostras; e bibliotecas revisadas para maior seguran ca . Para maiores detalhes consulte o site http://msdn.microsoft.com/visualc/. Borland Enterprise Studio C++ uma IDE completa que usa a biblioteca de classes VCL (Visual Class Library). E Para maiores detalhes consulte o site http://www.borland.com.br/estudiocpp/. Borland C++ Builder Ambiente completo, do tipo RAD, que utiliza a biblioteca VCL Visual Class Library. Tem suporte ` a UML 1.5 ou 2.0, e, com o LiveSource, pode-se alternar entre o desenvolvimento da modelagem UML ou da implementa ca o. Tamb em permite a cria ca o de novos padr oes. Veja o que diz o site da Borland: Para o desenvolvedor C++ prossional, que exige aplica co es con aveis e de alta-performance. Enm o IDE que voc e esperava! O C++Builder R 2006 atualiza e rena o popular IDE do C++Builder R com as mais recentes fun co es RAD e ALM para o desenvolvimento C e C++ cr tico ` a miss ao. Desenvolva robustas aplica co es GUI, de base de dados e Web em tempo recorde, com desenvolvimento de aplica co es Web WYSIWYG, poderosos novos provedores de dados, as mais recentes fun co es de produtividade IDE, e uma profunda integra ca o de IDE com controle de vers ao, acompanhamento de bugs e colabora ca o de equipe. Alavanque uma grande variedade de componentes de terceiros com o mais recente VCL (Visual Component Library). Parte do Borland Developer Studio, o C++Builder 2006 tamb em inclui suporte completo ao desenvolvimento Web, de base de dados e GUI utilizando C, C++, C#, Delphi Win32 e Delphi .NET. Para maiores detalhes consulte o site http://www.borland.com/us/products/cbuilder/. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

154

6.6. PROJETO DO SISTEMA Nota: o kylix foi uma tentativa frustada da borland de desenvolver um ambiente para plataforma GNU/Linux.

Dev C++ Ambiente visual pequeno, simples de usar e que utiliza as ferramentas da GNU. Veja na Figura 6.27 a tela do programa Dev C++. Para maiores detalhes, como instala ca o, siga as instru co es do site http://www.bloodshed. net/dev/.

Figura 6.27: A tela do programa Dev C++ .

Code Warrior Metroworks Ambiente completo com uso da biblioteca Code Warrior. Muito utilizada no Mac Os System X. Para maiores detalhes consulte o site http://www.metrowerks.com. Kdevelop O kdevelop tornou-se um ambiente multilinguagem, podendo ser utilizado para desenvolver programas em Ada, C, C++ (biblioteca GDI Qt ou GTK), banco de dados, Fortran, Haskell, Java, Pascal, Perl, PHP, Python, Ruby e Shell. Ou seja, voc e aprende a usar um ambiente de desenvolvimento e faz programas utilizando diferentes linguagens. Adaptou o Qt-designer para funcionamento integrado, tem interface integrada para acesso a debuger e a diferentes sistemas de controle de vers oes. Permite visualizar os arquivos e as classes de diferentes formas. Muito bem documentado. Veja na Figura 6.28 a tela do kdevelop. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.6. PROJETO DO SISTEMA Para maiores detalhes consulte o site http://www.kdevelop.org. Figura 6.28: A tela do programa kdevelop.

155

Qt-designer Ambiente do tipo RAD, completo e de uso simplicado. Veja uma pequena reportagem sobre o Qt-designer na Revista Linux, edi ca o 31, dispon vel em http://www. revistadolinux.com.br/ed/031/assinantes/programacao.php3. Exemplos de uso da biblioteca Qt, utilizada pelo Qt-designer, est ao dispon veis na se ca o ??. Para maiores detalhes consulte o site http://www.trolltech.com. Glade o Ambiente completo que utiliza o toolkit do gtk++ (veja http://www.gtk.org/). E ambiente ideal para o desenvolvimento de programas para o GNOME. Para maiores detalhes consulte o site http://glade.gnome.org/. Eclipse um o eclipse e uma plataforma completa para constru ca o e integra ca o de software. E software livre desenvolvido pela IBM, escrito em Java, mas que tem suporte para C e C++. Veja o que diz o site http://www.eclipse.org/: O Eclipse e um projeto da comunidade de software aberto focado na construc a o de uma plataforma de desenvolvimento composta de bibliotecas extens veis e ferramentas para desenvolvimento, constru ca o e gerenciamento, em tempo de execu ca o, de softwares ao longo de seu ciclo de vida. Uma grande e entusiasmada equipe, formada pelos maiores vendedores de tecnologias e iniciativas inovadoras, como universidades, institui co es de pesquisa e indiv duos, tem extendido, complementado e dado suporte a plataforma do Eclipse Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

156

6.6. PROJETO DO SISTEMA

Figura 6.29: A tela do programa qt-designer.

Anjuta Outro ambiente de desenvolvimento para o GTK/GNOME. Para maiores detalhes consulte o site http://anjuta.sourceforge.net. Source navigator Dispon vel em algumas distribui co es Redhat. Para maiores detalhes consulte o site http://sources.redhat.com/sourcenav/. Sistema GNU Pode-se desenvolver os programas com editores de texto simples (emacs, vi ), compilar os programas com o gcc/g++, linkar com o ld, e usar o make para compila ca o automatizada. Tem o cvs para controle de vers oes. O programa doxygem e utilizado para gerar documenta ca o embutida. O sistema da GNU tem ainda os pacotes automake, autoconf e libtool que permitem o desenvolvimento de sistemas multiplataforma. Todos esses sistemas ser ao vistos em detalhes a partir do Cap tulo ?? Introdu ca o ` a Programa ca o Multiplataforma com Software Livre. Para maiores detalhes consulte o site http://www.gnu.org. Observe que o sistema GNU garante maior portabilidade e uniformidade no desenvolvimento de seus programas, pois esse sistema est a presente em praticamente todas as plataformas. As bibliotecas gr acas mais interessantes s ao a Qt e a GTK pois s ao livres e multiplataforma. Os sistemas GNU ser ao discutidos na Parte?? Programa ca o Multiplataforma com Software Livre. Nota: se o sistema que vai ser desenvolvido e grande, ent ao a etapa de projeto pode ser feita em paralelo ` a an alise e deve considerar as experi encias da equipe de desenvolvimento. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.7. PROJETO ORIENTADO A OBJETO POO

157

6.7

Projeto orientado a objeto POO

O projeto orientado a objeto e a etapa posterior ao projeto do sistema (veja a Figura 5.1). Baseia-se na an alise, mas considera as decis oes do projeto do sistema. Acrescenta a an alise desenvolvida e as caracter sticas da plataforma escolhida (hardware, sistema operacional e linguagem de programa ca o). Passa pelo maior detalhamento do funcionamento do programa, acrescentando atributos e m etodos que envolvem a solu ca o de problemas espec cos n ao identicados durante a an alise. Envolve a otimiza ca o da estrutura de dados e dos algoritmos, a minimiza ca o do tempo de execu ca o, de mem oria e de custos. Existe um desvio de enfase para os conceitos da plataforma selecionada. Exemplo: na an alise voc e dene que existe um m etodo para salvar um arquivo em disco, dene um atributo nomeDoArquivo, mas n ao se preocupa com detalhes espec cos da linguagem. J a no projeto, voc e inclui as bibliotecas necess arias para acesso ao disco, cria um objeto espec co para acessar o disco, podendo, portanto, acrescentar novas classes ` aquelas desenvolvidas na an alise. Efeitos do projeto no modelo estrutural Adicionar nos diagramas de pacotes as bibliotecas e subsistemas selecionados no projeto do sistema (exemplo: a biblioteca gr aca selecionada). Novas classes e associa co es oriundas das bibliotecas selecionadas e da linguagem escolhida devem ser acrescentadas ao modelo. Estabelecer as depend encias e restri co es associadas ` a plataforma escolhida. Efeitos do projeto no modelo din amico Revisar os diagramas de seq u encia e de comunica ca o considerando a plataforma escolhida. Vericar a necessidade de se revisar, ampliar e adicionar novos diagramas de m aquinas de estado e de atividades. Efeitos do projeto nos atributos Atributos novos podem ser adicionados a uma classe, como, por exemplo, atributos espec cos de uma determinada linguagem de programa ca o (acesso a disco, ponteiros, constantes e informa co es correlacionadas). Estruturas de dados avan cadas podem ser montadas utilizando-se os containers e algoritmos gen ericos de C++ (a STL ser a discutida a partir do Cap tulo 31 Introdu ca o ` a Biblioteca Padr ao de Gabaritos de C++ STL ). Efeitos do projeto nos m etodos Em fun ca o da plataforma escolhida, verique as poss veis altera co es nos m etodos. O projeto do sistema costuma afetar os m etodos de acesso aos diversos dispositivos (exemplo: hd, rede). De maneira geral os m etodos devem ser divididos em dois tipos: i) tomada de decis oes, m etodos pol ticos ou de controle; devem ser claros, leg veis, ex veis e usam polimorsmo. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

158

6.7. PROJETO ORIENTADO A OBJETO POO ii) realiza ca o de processamentos, podem ser otimizados e em alguns casos o polimorsmo deve ser evitado.

Algoritmos complexos podem ser subdivididos. Verique quais m etodos podem ser otimizados. Pense em utilizar algoritmos prontos como os da STL (algoritmos gen ericos). Responda a pergunta: os m etodos da classes est ao dando resposta ` as responsabilidades da classe? Revise os diagramas de classes, de seq u encia e de m aquina de estado. Efeitos do projeto nas heran cas Reorganiza ca o das classes e dos m etodos (criar m etodos gen ericos com par ametros que nem sempre s ao necess arios e englobam m etodos existentes). Abstra ca o do comportamento comum (duas classes podem ter uma superclasse em comum). Utiliza ca o de delega ca o para compartilhar a implementa ca o (quando voc e cria uma heran ca irreal para reaproveitar c odigo). Usar com cuidado. Revise as heran cas no diagrama de classes. Efeitos do projeto nas associa co es Deve-se denir na fase de projeto como as associa co es ser ao implementadas, se obedecer ao um determinado padr ao ou n ao. Se existe uma rela ca o de muitos, pode-se implementar a associa ca o com a utiliza ca o de um dicion ario, que e um mapa das associa co es entre objetos. Assim, o objeto A acessa o dicion ario fornecendo uma chave (um nome para o objeto que deseja acessar) e o dicion ario retorna um valor (um ponteiro) para o objeto correto. Veja o Cap tulo 29 Implementando Associa co es em C++. Evite percorrer v arias associa co es para acessar dados de classes distantes. Pense em adicionar associa co es diretas. Efeitos do projeto nas otimiza co es Fa ca uma an alise de aspectos relativos ` a otimiza ca o do sistema. Lembrando que a otimiza ca o deve ser desenvolvida por analistas/desenvolvedores experientes. Identique pontos a serem otimizados em que podem ser utilizados processos concorrentes. Pense em incluir bibliotecas otimizadas. Se o acesso a determinados objetos (atributos/m etodos) requer um caminho longo (exemplo: A->B->C->D.atributo), pense em incluir associa co es extras (exemplo: A-D.atributo). Atributos auxiliares podem ser inclu dos. A ordem de execu ca o pode ser alterada. Revise as associa co es nos diagramas de classes. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.7. PROJETO ORIENTADO A OBJETO POO

159

Depois de revisados os diagramas da an alise voc e pode montar dois diagramas relacionados ` a infraestrutura do sistema. As depend encias dos arquivos e bibliotecas podem ser descritos pelo diagrama de componentes (veja a se ca o 6.7.1), e as rela c oes e depend encias entre o software e o hardware podem ser ilustradas com o diagrama de implanta ca o (veja a se ca o 6.7.1).

6.7.1

Diagrama de componentes

O diagrama de componentes mostra a forma como os componentes do programa se relacionam, suas depend encias. Inclui itens como: componentes, subsistemas, execut aveis, n os, associa co es, depend encias, generaliza co es, restri co es e notas. Exemplos de componentes s ao bibliotecas est aticas, bibliotecas din amicas, dlls, componentes Java, execut aveis, arquivos de disco, c odigo-fonte. Veja na Figura 6.30 um exemplo de diagrama de componentes. Observe que este inclui muitas depend encias, ilustrando as rela co es entre os arquivos. Por exemplo: o subsistema biblioteca inclui os arquivos das classes A e B, e a gera ca o dos objetos A.obj e B.obj depende dos arquivos A.h, A.cpp, B.h e B.cpp. A gera ca o da biblioteca depende dos arquivos A.obj e B.obj. O subsistema biblioteca Qt, um subsistema exerno, inclui os arquivos de c odigo da biblioteca Qt e a biblioteca em si. O subsistema banco de dados representa o banco de dados utilizado pelo sistema e tem uma interface de acesso que e utilizada pelo programa para acesso aos dados armazenados no banco de dados. O programa execut avel a ser gerado depende da biblioteca gerada, dos arquivos da biblioteca Qt, do m odulo de arquivos MinhaJanela e do banco de dados. Algumas observa co es u teis para o diagrama de componentes: De posse do diagrama de componentes, temos a lista de todos os arquivos necess arios para compilar e rodar o programa. Observe que um assunto/pacote pode se transformar em uma biblioteca e ser a inclu do no diagrama de componentes. A liga ca o entre componentes pode incluir um estere otipo indicando o tipo de relacionamento ou algum protocolo utilizado.

Figura 6.30: Diagrama de componentes.


Diagrama de componentes, mdulos do programa. Mostra os componentes necessrios para montagem do programa. <<arquivo>> MinhaJanela.h MinhaJanela.cpp <<lib>> biblioteca dependncia <<BancoDeDados>> Sub-sistema banco de dados *postgresql <<arquivo>> B.obj <<executvel>> meuPrograma Um receptculo e uma observao mostrando a conexo do programa com o banco de dados. <<lib>> Arquivos biblioteca Qt

<<biblioteca>> MtodosNumricos

<<arquivo>> A.h A.cpp

<<arquivo>> A.obj

<<arquivo>> B.h B.cpp

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

160

6.7. PROJETO ORIENTADO A OBJETO POO

6.7.2

Diagrama de implanta c ao execu c ao

O diagrama de implanta ca o e um diagrama de alto n vel que inclui rela co es entre o software e o hardware e que se preocupa com os aspectos da arquitetura computacional escolhida. Seu enfoque e o hardware, a congura ca o dos n os em tempo de execu ca o. O diagrama de implanta ca o deve incluir os elementos necess arios para que o sistema seja colocado em funcionamento: computador, perif ericos, processadores, dispositivos, n os, relacionamentos de depend encia, associa ca o, componentes, subsistemas, restri co es e notas. Veja na Figura 6.31 um exemplo de diagrama de implanta ca o de um cluster. Observe a presen ca de um servidor conectado a um switch. Os n os do cluster (ou clientes) tamb em est ao conectados ao switch. Os resultados das simula co es s ao armazenados em um servidor de arquivos (storage ). Pode-se utilizar uma anota ca o de localiza ca o para identicar onde determinado componente est a residente, por exemplo {localiza ca o: sala 3}. Figura 6.31: Diagrama de implanta ca o.

Diagrama de implantao, inclui aspectos de hardware, conexes, drives. Mostra o hardware e as ligaes necessrias para rodar o programa.

switch Giga <<Cliente cluster-01>>

<<Servidor>>

<<Processador1>> <<Processador1>> Servidor Lgico OpenMosix HD <<Processador2>> <<Core_1>> <<Core_2>> <<Core_3>> <<Core_4>> Demais clientes repetem configurao do cluster-01. Programa simulao

<<Core_1>> <<Core_2>> <<Core_3>> <<Core_4>>

<<Processador2>>

Servidor de arquivos, armazenamento de dados

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

6.8. IMPLEMENTAC AO

161

6.8

Implementa c ao

Nesta se ca o veremos como nos preparar para a implementa ca o, algumas dicas para implementa ca o da interface gr aca do programa, e como montar o c odigo inicial do programa com o umbrello.

6.8.1

Antes de iniciar a implementa c ao

Dica de UP fa ca um planejamento da implementa ca o (monte um plano). ` medida que se modelam as diversas classes e m A etodos, deve-se testar cada classe e cada m etodo desenvolvido (teste l ogico). A dica e criar classes de teste para testar as classes e subsistemas criados (veja o item 4 da se ca o 6.9). Antes de iniciar a implementa ca o de um m etodo complexo, voc e deve concluir o seu diagrama de atividades. Mantenha contato constante com os usu arios do sistema e esteja atento a custos e prazos.

6.8.2

Roteiro para montar o c odigo inicial do programa com o Umbrello

Softwares modeladores como o umbrello, o dia e o Visual-Paradigm podem ser utilizados para montagem do c odigo inicial do programa. De modo geral, o c odigo e gerado a partir do diagrama de classes, e a maioria dos modeladores implementa uma casca inicial do programa que inclui as classes, seus atributos, m etodos, associa co es e documenta co es. Vimos na se ca o 4.4.2 o programa umbrello, o qual pode ser utilizado para gerar o c odigo inicial do programa. Uma das vantagens do umbrello e que ele e software livre e tem a capacidade de gerar os c odigos para diversas linguagens. C++, Actionscript, Ada, IDL, Java, JavaScript, Pascal, Perl, PHP, Python, Ruby, SQL, TCL, XMLschema. Nota: se voc e ainda n ao tem o programa umbrello instalado, veja na se ca o 4.4.2 como obter o umbrello. Leia o manual de instala ca o e instale o programa. Em seguida leia o manual do usu ario do umbrello para se familiarizar com o programa. Aprenda em detalhes como criar os diagramas de classe. Veja a seguir um roteiro para montar o c odigo inicial do programa com o umbrello. 1. Abra o programa umbrello. 2. Monte os diagramas de classes para seu sistema. Inclua todos os atributos, m etodos e associa co es necess arias. Como exemplo, voc e pode reproduzir o exemplo da Figura 4.8. 3. Revise o diagrama de classe. A id eia e s o gerar o c odigo depois que o diagrama de classe esteja correto. 4. Inclua as considera co es do projeto e revise novamente o diagrama. 5. Selecione o item de menu C odigo->Linguagem Ativa e logo ap os selecione C++. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

162

6.9. TESTE DE SOFTWARE

6. Selecione o item de menu C odigo->Assistente de Gera ca o de C odigo. No di alogo Assistente de Gera ca o de C odigo, selecione as classes que devem ter seu c odigo gerado e em seguida pressione o bot ao Pr oximo. 7. No di alogo Op co es de Gera ca o de C odigo temos 3 abas: (a) Geral voc e dene a linguagem a ser utilizada, al em da pasta onde o programa vai ser armazenado e a pol tica de substitui ca o de arquivos. (b) Formata ca o dene caracter sticas dos coment arios, tipo e quantidade de indenta ca o. (c) Op co es de linguagem dene caracter sticas espec cas da linguagem selecionada. Depois de fazer suas op co es pressione o bot ao Pr oximo. 8. Conra as classes selecionadas e ent ao pressione Gerar. O c odigo gerado estar a disponibilizado no diret orio informado. 9. Use o editor ou IDE de sua prefer encia para editar os c odigos gerados. Com o c odigo inicial do programa gerado por uma ferramenta CASE (como o umbrello ou o Visual-Paradigm ), parte-se para a implementa ca o do programa. Nesta etapa s ao essenciais n ao s o os conhecimentos da modelagem orientada a objeto, mas da linguagem de programa ca o, ou seja, as regras de sintaxe e a forma como a linguagem implementa a programa ca o orientada a objeto.

6.8.3

Dicas para implementa c ao da interface gr aca

Para implementar a interface gr aca do programa, o engenheiro de software deve considerar aspectos como: Padroniza ca o (consist encia; opera co es semelhantes t em interfaces semelhantes). Na medida do poss vel, a interface deve ser orientada a objeto, isto e, os elementos visuais da interface devem representar objetos internos. Use threads (processamento paralelo). Por exemplo: e interessante ter uma thread separada respons avel pela atualiza ca o da interface gr aca do sistema, enquanto outras threads est ao realizando as atividades solicitadas. Di alogos devem lembrar as u ltimas op co es selecionadas. Voc e pode incluir um bot ao default. Veja um conjunto de instru co es para construir interfaces gr acas amig aveis no documento http://developer.gnome.org/projects/gup/hig/.

6.9

Teste de software

Apresenta-se nesta se ca o o teste de software: o que e, porque devemos testar nossos softwares, a equipe de teste e uma metodologia simplicada para o teste de software. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.9. TESTE DE SOFTWARE

163

6.9.1

Por que testar?

O teste se preocupa com o funcionamento l ogico do programa, se o software cumpre com seus objetivos, se os requisitos de qualidade, usabilidade e performance foram atendidos, com o controle dos bugs. Segundo [Pressman, 2002], o objetivo do teste e encontrar o maior n umero poss vel de erros, com um m nimo de esfor co aplicado, durante um intervalo de tempo real stico. O objetivo prim ario do teste de software e diminuir as falhas de um software, tendo como conseq u encia uma redu ca o no custo e no tempo de desenvolvimento do software. Entre as vantagens de um software bem testado est ao o aumento da qualidade, da funcionalidade e a redu ca o das falhas. Outras conseq u encias de um software bem testado ea redu ca o na necessidade de suporte. Incluir no cronograma de desenvolvimento do sistema as atividades de teste. Controle o processo de teste. Voc e precisa denir o rigor, o n vel de detalhamento dos testes a serem realizados. Por exemplo: um programa para controle de v oo requer um sistema de testes extremamente rigoroso. Use procedimentos automatizados para execu ca o do teste (como check-list e programas de teste). Use uma metodologia de teste adaptada ` a sua equipe. Dica de XP: o planejamento e execu ca o do teste deve ser integrado ao projeto de desenvolvimento do sistema. Isto e, os testes do software devem ser realizados ao longo de todas as etapas de desenvolvimento.

6.9.2

Equipe de teste

O tamanho da equipe de teste depende do tamanho da equipe envolvida no projeto. Em alguns casos a equipe de teste e uma equipe separada. A seguir, ser ao brevemente apresentadas as responsabilidades de cada membro da equipe: Gerente respons avel pela infraestrutura do sistema de teste, pela montagem da equipe e pela sele ca o das ferramentas a serem utilizadas. Analista respons avel pelo planejamento do teste, estrutura l ogica do teste, cria ca o de check-list e an alise dos resultados obtidos. Testador realiza os testes e emite relat orios. Dica de XP: a metodologia eXtreme Programming indica a montagem de duas equipes, uma implementa as classes e a outra, o sistema de testes.

6.9.3

Metodologia de teste

Segundo [Sonerviile, 1993], o processo de teste evolue: teste de unidade, teste de m odulos, teste de subsistemas, teste do sistema e teste de aceita ca o. Existem diferentes metodologias de teste. Veja a seguir uma poss vel metodologia para o teste de seu software: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

164 1. Teste das especica co es:

6.9. TESTE DE SOFTWARE

O teste come ca na an alise dos requisitos, das especica co es O sistema especicado est a fechado (completo)? Teste dos casos de uso Eles fazem sentido? Est ao completos? Teste da interface (prot otipo) amig A interface satisfaz as necessidades do cliente? E avel? Montar uma equipe com dois a tr es usu arios que far ao testes com o prot otipo gerado, dando uma resposta a quesitos como funcionalidade, facilidade de uso, e sugest oes para melhoria da interface do sistema. 2. Teste da estrutura do sistema: Os assuntos/pacotes foram identicados? Eles fazem sentido? Os diagramas de classes est ao completos? 3. Teste da din amica do sistema (teste l ogico): Todos os diagramas de caso de uso foram considerados? Foram utilizados para montagem dos diagramas de comunica ca o? O teste l ogico e realizado sem nenhum c odigo; para tanto, partimos dos diagramas de casos de uso e criamos os diagramas de comunica ca o. No teste l ogico e vericada a integra ca o entre pacotes, componentes e classes. Quando necess ario os diagramas de m aquina de estado foram montados? Voc e montou os diagramas de atividade para os m etodos complexos? 4. Teste do projeto: A arquitetura e a plataforma escolhidas s ao adequadas? S ao multiplataforma? S ao extens veis? O sistema suportar a m ultiplos processos? O sistema permite o uso de processamento paralelo? 5. Teste de unidade (classes, atributos, m etodos e subsistemas): Utilizado para vericar se cada unidade (classe, subsistema) est a consistente. Deve ser realizado antes e depois da implementa ca o de cada classe. Classes: A classe tem sentido l ogico? Ela representa uma abstra ca o signicativa do problema? Testar a classe utilizando diagramas de comunica ca o. O programador implementa as diferentes classes e, para cada classe importante, cria uma classe de teste. A classe de teste deve testar toda interface da classe-alvo (m etodos p ublicos). Atributos: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.9. TESTE DE SOFTWARE O tipo e a precis ao s ao adequados? O atributo foi inicializado? O intervalo de valores e respeitado? M etodos:

165

Vericar as entradas, tipo dos par ametros, limites, precis ao. L ogica do m etodo/algoritmo (montar diagrama de atividade). Vericar aloca ca o/desaloca ca o de mem oria, uso de ponteiros. Vericar tipo de retorno, valores retornados. Cada m etodo deve ser testado com um conjunto de dados que inclua dadospadr ao e dados de exce co es (valores inv alidos). Primeiro, deve-se testar os casos simples, mais usuais; depois, os casos complexos, com os m etodos assumindo valores pr oximos aos extremos admitidos.

Pacotes: Pode-se criar pequenos programas para teste das classes de um pacote. 6. Teste de integra ca o: Consiste em testar a integra ca o entre as diversas partes do sistema (classes <-> subsistemas, subsistema<->subsistema). Testar a integra ca o entre as classes que fazem parte de um pacote/assunto ou hierarquia. Acesso, comunica ca o, funcionalidade (usar diagramas de comunica ca o, de atividades, de componentes). Testar integra ca o dentro de uma hierarquia. Testar as rela co es e integra co es entre pacotes/subsistemas: 7. Teste de compila ca o: Mensagens de warning. Verique todas essas mensagens, pois elas precisam ser eliminadas. Como os compiladores t em evolu do rapidamente, e normal aparecerem erros diferentes quando se compila o software com compiladores diferentes. A dica e compilar o programa em diferentes plataformas com diferentes compiladores. 8. Teste de sistema (usu ario <-> sistema): Teste de opera ca o normal com alguns usu arios (teste do sistema como um todo). Um cliente ou usu ario experiente pode ajudar um membro da equipe de desenvolvimento a montar uma estrutura de dados que ser a utilizada nos testes. Coloque usu arios para testar o sistema, avaliar sua qualidade, sua usabilidade (facilidade de uso do software). Deve-se usar a mesma equipe utilizada no teste da interface, mas agora testando o sistema em funcionamento. Os usu arios devem avaliar novamente a interface, o tempo de resposta do programa. Verique os seguintes aspectos: o programa produz os resultados esperados? Os dados incorretos s ao corretamente tratados? O programa e f acil de usar? A performance e satisfat oria? Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

166 Teste de estresse/desempenho

6.9. TESTE DE SOFTWARE

Consiste em testar os limites do sistema (opera co es extremas). Os atributos e par ametros assumem valores extremos. Testar o desempenho do sistema, sua performance. Veja como aumentar a performance de seus programas e testar o desempenho de cada m etodo/fun ca o usando prolers no Cap tulo ?? Auditoria e Otimiza ca o de Programas. Teste de compatibilidade (multiplataforma) Teste de interoperabilidade. Verique se o sistema pode ser compilado e linkado em outras m aquinas, com outros sistemas e compiladores. A id eia e vericar se o sistema respeita o conceito multiplataforma. Testar/vericar o formato dos arquivos gerados. Vericar se o arquivo gerado em uma plataforma pode ser aberto em outra (a dica e usar padr oes abertos). Teste de seguran ca O sistema tem prote ca o contra ataques externos? Teste de aceita ca o Teste de instala ca o. O programa de instala ca o funciona? Teste dos manuais, tutoriais. Os manuais foram feitos? Foram revisados? Os links est ao corretos? Teste de vers oes Consiste em distribuir o sistema e receber o retorno dos usu arios (vers ao alfa e beta ). 9. Teste de regress ao: Toda vez que alteramos uma parte do sistema que estava funcionando, podemos adicionar novos bugs. O teste de regress ao e realizado para vericar se o programa continua funcionando. Para reduzir o n umero de testes de regress ao procure deixar suas classes completas. Deve ser realizado sempre que uma classe e alterada. Quando temos certeza de que programa est a correto, usamos o programa de teste para gerar uma sa da-padr ao, que e armazenada no disco (exemplo: NomeClasse.padrao.out). A cada nova execu ca o do teste, uma nova sa da e gerada (exemplo: NomeClasse.regressao.out). As duas vers oes s ao ent ao comparadas com o programa di. Se existirem diferen cas, ent ao o programa n ao passou no teste, e o c odigo precisa ser corrigido.
2

Dica: podemos incluir dentro dos arquivos Makele as instru co es para rodar o programa de teste e vericar se as sa das est ao iguais.

6.9.4

Senten cas para teste de software

Manter uma lista enumerada com os bugs encontrados no arquivo bugs. Marcar os solucionados e os n ao-solucionados. Descrever o bug e as condi co es em que ocorre, al em de sua localiza ca o. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.9. TESTE DE SOFTWARE

167

O programa checker da GNU, obtido no endere co http://www.gnu.org/software/checker/, pode ser utilizado para vericar o acesso ` a mem oria realizado pelo seu programa. Segundo o site da GNU, o checker e uma ferramenta que procura erros de mem oria em tempo de execu ca o. Sua fun ca o prim aria e emitir mensagens de warning quando o programa realiza acesso a vari aveis n ao inicializadas, ou quando o programa acessa mem oria n ao alocada. Quando uma classe e enviada para o reposit orio, o sistema de controle das vers oes pode executar um programa auxiliar, este programa auxiliar pode ser o programa de teste (veja se ca o ??). Para realizar o teste de unidade, procure no google por Objetct Oriented Software and test. D e uma olhada no programa da GNU cppUnit, dispon vel em http://cppunit. sourceforge.net. Veja as refer encias: [Pressman, 2002, Emerson Rios, 2004, Winblad et al., 1993, Martin and McClure, 1993].

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

168

DO PROGRAMA 6.10. DOCUMENTAC AO

6.10

Documenta c ao do programa

A documenta ca o de um programa e essencial pelos seguintes motivos: Compreens ao do funcionamento do programa e de seu planejamento. Acompanhamento da execu ca o das atividades de implementa ca o, testes e depura ca o. Compreens ao e controle das atividades desenvolvidas. Prepara ca o dos manuais e da ajuda [help ]do programa. Permite a manuten ca o e a altera ca o do programa por terceiros. A Figura 5.1 ilustra as diversas etapas de desenvolvimento de um programa e os documentos que devem ser gerados. Observe que a documenta ca o e gerada ao longo do desenvolvimento do programa e deve servir de base para a elabora ca o dos manuais (estes devem ser desenvolvidos somente ap os a conclus ao do programa). Deve-se criar um diret orio onde ser ao armazenados os arquivos do programa a ser desenvolvido. Neste diret orio ser ao inclu das todas as informa co es relativas ao programa, ou seja, a documenta ca o da an alise orientada a objeto, do projeto do sistema, do projeto orientado a objeto, das bibliotecas desenvolvidas, dos testes realizados, o arquivo de help do programa (tutoriais e manuais). No diret orio-raiz crie um arquivo README/LEIAME, com informa co es b asicas sobre o sistema, um arquivo com instru co es para instala ca o do programa (INSTALL), um arquivo com a lista das modica co es (ChangeLog), um arquivo com as novidades da vers ao (NEWS), um arquivo com os bugs identicados/solucionados (BUGS), um arquivo com instruc o es sobre a licen ca do programa (COPYING), um arquivo com a lista de autores (AUTHORS) e um arquivo com questionamentos sobre poss veis mudan cas, tarefas (TODO). No arquivo INSTALL voc e precisa incluir a lista de bibliotecas externas (de terceiros) que ser ao utilizadas, informando tamb em como estas bibliotecas podem ser obtidas e instaladas (pr e-requisitos). Nota: para o desenvolvedor existe um efeito secund ario associado ` a documenta ca o do sistema, que e o estudo, a compreens ao e a descri ca o do pr oprio c odigo.

6.10.1

Itens a serem documentados

Veremos a seguir um conjunto de itens que devem estar presentes na documenta ca o de um software. Dentro de [] colocamos os itens opcionais. Esta lista de itens tem como base o sistema ao descritos na de documenta ca o JAVA DOC (o sistema JAVA DOC e o programa doxygen s se ca o ??) e o programa umbrello (veja a Figura 4.7). Podemos dividir a documenta ca o em duas partes, uma relacionada aos aspectos estruturais e outra, aos aspectos din amicos. Observe que dentro do sistema temos subsistemas e dentro dos subsistemas temos pacotes. Em alguns casos, temos componentes externos (como programas externos) e artefatos externos (como arquivos e tabelas). Veremos no cap tulo de programa ca o multiplataforma que podemos organizar nosso programa em pastas/subdiret orios, por isso, existe um item pasta. A seguir temos a documenta ca o das classes normais e classes de interface, al em de suas poss veis associa co es, atributos e m etodos. Podemos documentar ainda as enumera co es. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

DO PROGRAMA 6.10. DOCUMENTAC AO Documenta c ao do sistema Nome do sistema: [Subsistemas:] [Formas de acesso:] [Bibliotecas externas utilizadas:] Descri ca o: breve descri ca o do sistema (inclui suas responsabilidades). Documenta c ao dos subsistemas Nome do subsistema: [Nome do estere otipo:] [Visibilidade: p ublico, protegido, privado, de implementa ca o.] Descri ca o: breve descri ca o do subsistema, o que representa. Documenta c ao dos assuntos/pacotes Nome do assunto/pacote: [Nome do estere otipo:] [Visibilidade: p ublico, protegido, privado, de implementa ca o.] [Bibliotecas relacionadas:] [Classes relacionadas:] Descri ca o: breve descri ca o do pacote, o que representa. Documenta c ao dos componentes externos Nome do componente: [Nome do estere otipo:] [Execut avel: S/N.] [Visibilidade: p ublico, protegido, privado, de implementa ca o.] Descri ca o: breve descri ca o do componente, o que representa. Documenta c ao dos artefatos externos Nome do artefato: [Nome do estere otipo:] Desenhar como: padr ao, arquivo, biblioteca, tabela. [Visibilidade: p ublico, protegido, privado, de implementa ca o.] Descri ca o: breve descri ca o do artefato. Programa ca o Orientada a Objeto com C++

169

Andr e Duarte Bueno

170 Documenta c ao das pastas (diret orios) Nome da pasta: [Nome do estere otipo:]

DO PROGRAMA 6.10. DOCUMENTAC AO

[Visibilidade: p ublico, protegido, privado, de implementa ca o.] Descri ca o: breve descri ca o da pasta. Documenta c ao das classes Nome da classe: [Nome do arquivo:] Autor: Data: Copyright: Licen ca: [Nome do estere otipo:] [Nome do pacote: assunto a que est a relacionada.] [Abstrata?] [Visibilidade: p ublico, protegido, privado, de implementa ca o.] [Superclasse:] [Concorr encia:] [Bugs identicados:] [See ou veja tamb em: link para informa co es externas.] Descri ca o: inclui descri ca o do objetivo da classe (tarefas, responsabilidades, colaboradores): Documenta c ao das classes de interface Nome da classe de interface: Autor: Data: Copyright: Licen ca: [Nome do estere otipo:] [Nome do pacote: assunto a que est a relacionada.] [Visibilidade: p ublico, protegido, privado, de implementa ca o.] Descri ca o: inclui descri ca o do objetivo da classe, sua forma geral de uso. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

DO PROGRAMA 6.10. DOCUMENTAC AO Documenta c ao das associa co es Nome da associa ca o: Tipo: [Multiplicidades:] [Atributo(s) de associa ca o:] Descri ca o: breve descri ca o da associa ca o. Documenta c ao dos atributos Nome: Tipo: [Valor inicial: valor m nimo: valor m aximo:] [Visibilidade]: p ublico, protegido, privado, de implementa ca o. [Restri co es:] [Derivado (S/N):] [Linguagem/escopo]: friend, const, static. [Nome do estere otipo:] Descri ca o: breve descri ca o do atributo. Documenta c ao dos m etodos Nome: Acesso: p ublico, protegido, privado. Retorno: Tipo Par ametros: Tipo [Nome do estere otipo:] [Precondi co es:] Tipo: virtual, est atico, normal, const. [Exce co es:] [Concorr encia:] Descri ca o: breve descri ca o da forma de uso. Programa ca o Orientada a Objeto com C++

171

Andr e Duarte Bueno

172 Documenta c ao das enumera co es Nome da enumera ca o: [Nome do estere otipo:]

DO PROGRAMA 6.10. DOCUMENTAC AO

[Visibilidade]: p ublico, protegido, privado, de implementa ca o. Descri ca o: breve descri ca o da enumera ca o. Relacionados aos aspectos din amicos temos a documenta c ao dos casos de uso, dos atores, das associa co es entre atores e casos de uso. Documenta c ao dos casos de uso Nome do caso de uso: [Nome do estere otipo:] [Abstrato?] [Visibilidade: p ublico, protegido, privado, de implementa ca o.] Documenta ca o: breve descri ca o do caso de uso. Documenta c ao dos atores Nome do atores: [Nome do estere otipo:] [Visibilidade]: p ublico, protegido, privado, de implementa ca o. Documenta ca o: breve descri ca o do ator. Dica: para documenta ca o embutida, utilize o formato JAVA DOC (veja a se ca o ??), e, para montar os manuais do usu ario, o sistema DOCBOOK (sgml/xml, usando o programa LYX).

6.10.2

Cart oes CRC

Alguns desenvolvedores utilizam cart oes CRC (Classe/Responsabilidade/Colabora ca o). Um cart ao CRC e dividido em tr es se co es: no topo, o nome da classe; na coluna da esquerda, as responsabilidades; e na coluna da direita, os colaboradores. Veja a Tabela 6.32. Figura 6.32: Cart oes CRC: cClasse, responsabilidade, colabora ca o. Nome da classe: Responsabilidades Colaboradores

6.10.3

Dicion ario de classes

usual a cria E ca o de um arquivo de texto ou planilha em que constam os nomes das classes criadas e uma breve descri ca o. Funciona como um dicion ario das classes criadas. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

E REUSO DE SOFTWARE 6.11. MANUTENC AO

173

6.11

Manuten c ao e reuso de software

A manuten ca o do programa envolve a corre ca o dos bugs remanescentes e a necessidade de se extender o programa. A quest ao da manuten ca o envolve ainda aspectos como custo da manuten ca o, custo para desenvolvimento de novas vers oes, al em de como manter a equipe de desenvolvimento. A reutiliza ca o consiste em elaborar um programa com a preocupa ca o de este ser posteriormente reaproveitado. A id eia por tr as do reuso do software e simples: construir m odulos, bibliotecas e classes que possam ser reaproveitados por voc e, sua equipe de desenvolvimento e por terceiros. Para conseguir o reuso devemos melhorar os protocolos e aumentar o empacotamento, viabilizando a constru ca o de bibliotecas e frameworks. Benef cios do reuso de software Redu ca o de custo. Software mais testado e debugado. Economia de tempo. Veja a seguir um conjunto de dicas, algumas extra das de [Winblad et al., 1993] e [Rumbaugh et al., 1994], para aumentar a reusabilidade.

6.11.1

Senten cas e dicas para conseguir o reuso de software

Senten cas diversas: Documente e teste todos os sistemas desenvolvidos (veja a se ca o 6.9 e 6.10). Coloque os c odigos em reposit orios (veja o Cap tulo 6.11.1 Controle de Vers oes o cvs ). Sempre que poss vel use delega ca o. Como outras pessoas podem ter interesse em partes de seu c odigo, monte-o utilizando sistemas multiplataforma, mesmo que voc e sempre trabalhe com a mesma plataforma.

6.11.2

Senten cas para aumentar o empacotamento

O conceito de empacotamento envolve a necessidade de se unir dois ou mais programas desenvolvidos por pessoas diferentes. Pode ocorrer que dois programadores desenvolvam classes com o mesmo nome e voc e ter a a necessidade de alterar o nome de uma delas. Uma linguagem que permite um bom empacotamento eliminar a esta necessidade. Felizmente C++ fornece o conceito de namespace (veja Cap tulo 10 Namespace), facilitando um bom empacotamento.

6.11.3

Senten cas para conseguir o reuso de classes

Na elabora ca o use abstra ca o; procure deixar o sistema gen erico. Deixe a interface de acesso ` a classe simples de usar (use oculta ca o). Elimine interfaces duplicadas. Existe a necessidade de se deixar o programa mais gen erico. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

174

E REUSO DE SOFTWARE 6.11. MANUTENC AO

A interface de acesso deve ser testada por outros usu arios ( e simples? faz sentido? obedece a um mesmo padr ao?). Se a estrutura das classes e id entica e pouco mut avel, use templates. Se a estrutura das classes e din amica, polim orca, use heran ca. O objeto se comporta como um objeto padr ao de C++? Os operadores foram sobrecarregados?

6.11.4

Senten cas para conseguir o reuso de m etodos

Construa m etodos reutiliz aveis. Deixe o m etodo o mais gen erico poss vel. Mantenha os m etodos pequenos, com menos de 30 linhas de c odigo. Mantenha os m etodos coerentes, por exemplo, executar uma u nica tarefa ou tarefas estreitamente relacionadas. Mantenha os m etodos consistentes, por exemplo, m etodos semelhantes devem ter nomes e formatos semelhantes. Separe m etodos pol ticos, aqueles que envolvem a tomada de decis oes, dos de implementa ca o, aqueles que realizam um procedimento espec co. Os par ametros dos m etodos devem ser passados de forma uniforme. Elimine par ametros n ao utilizados. N ao acesse informa co es globais em um m etodo. Evite m etodos que mudam seu comportamento drasticamente em fun ca o de altera co es no estado dos objetos ou que tenham inu encia do hist orico da execu ca o do sistema. C odigos legados (antigos) feitos por terceiros poder ao ser reaproveitados. Mas neste caso, voc e vai ter de fazer uma reengenharia neste c odigo. Comece encapsulando o c odigo de forma a deixar o acesso transparente, com os mesmos protocolos utilizados em seus sistemas. Abuse dos m etodos privados e evite m etodos p ublicos. Se parte de um algoritmo e repetida em dois m etodos diferentes (fA, fB), pense em criar um m etodo auxiliar, no qual o c odigo duplicado vai ser colocado. Se for uma heran ca, este m etodo auxiliar deve ser colocado na classe-base. Senten cas para construir m etodos robustos Um m etodo e robusto se ele n ao falha, mesmo quando recebe par ametros errados. Somente otimize o programa depois de este funcionar e ter sido testado. Valide argumentos de m etodos acessados pelo usu ario. N ao inclua atributos que n ao podem ser validados. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

E REUSO DE SOFTWARE 6.11. MANUTENC AO Evite limites predenidos. D e prefer encia ` a aloca ca o din amica de mem oria.

175

Reduza o n umero de par ametros, dividindo uma mensagem em v arias (n umero de argumentos <= 6). Reduza o tamanho dos m etodos para at e 30 linhas.

6.11.5

Senten cas para montagem de bibliotecas

A montagem de bibliotecas ser a vista no Cap tulo ?? Bibliotecas e no Cap tulo ?? O Programa Libtool. Construa sua biblioteca utilizando a STL (descrita a partir do Cap tulo 31 Introdu ca o a Biblioteca Padr ` ao de Gabaritos de C++ STL). N ao coloque numa mesma biblioteca tens n ao correlacionados, ou seja, crie tantas bibliotecas quantas forem necess arias. Se for necess ario usar bibliotecas/vari aveis que n ao s ao multiplataforma, crie uma classe gen erica, multiplataforma, e crie classes herdeiras com c odigos espec cos para determinada plataforma. Veja a seguir dicas de [Winblad et al., 1993] para montagem de bibliotecas. muito importante que um objeto seja completo, para que possa ser utilizado como uma E biblioteca expans vel. Uma biblioteca de classes e algo gen erico, com a classe-base (superclasse), as classesderivadas, os atributos e os m etodos b asicos, al em da estrutura de liga ca o das classes. Uma biblioteca de classes precisa ser desenvolvida, planejada, pois n ao surge espontaneamente. Para facilitar o uso de uma biblioteca, podemos criar mais de uma interface de acesso, isto e, uma nova interface pode ser desenvolvida para atender um determinado tipo de uso. Depois de montar a vers ao 1.0 de sua biblioteca, preocupe-se em eliminar bugs, em sua otimiza ca o, antes de incluir novas funcionalidades.

6.11.6

Senten cas para montagem de framework

Uma framework e uma biblioteca de classes que foi aprimorada, aperfei coada para solucionar os problemas espec cos de uma determinada area. As frameworks s ao o objetivo fundamental do projeto orientado a objeto, uma vez que representam o n vel mais alto de abstra ca o.Veja a seguir dicas de [Winblad et al., 1993] para montagem de frameworks. Identique classes-derivadas que implementem o mesmo m etodo de diferentes maneiras. Se um m etodo e sempre redenido, reconsidere onde estes m etodos poderiam estar mais bem localizados. Envie mensagens para outras classes em vez de para a pr opria classe. Substitua frameworks baseadas em hereditariedade por frameworks baseadas em componentes, sobrepondo m etodos com mensagens enviadas para os componentes. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

176

E REUSO DE SOFTWARE 6.11. MANUTENC AO

Identique conjuntos de m etodos combinados em uma classe somente para acessar um atributo de inst ancia comum. Considere a migra ca o de um ou mais m etodos para outras classes; mude os m etodos para passar par ametros expl citos. Isto facilitar a a divis ao de classes. Segundo Kent Beck (autor do modelo XP) [Teles, 2006], frameworks s ao arriscadas quando s ao desenvolvidas cedo demais, pois nesse caso ser ao dif ceis de usar. Se voc e estiver usando XP, primeiro voc e constr oi duas ou mais aplica co es e ent ao abstrai aquilo que e comum, fazendo com que aplica co es semelhantes sejam constru das mais facilmente no futuro. Note que esta dica e valida para qualquer metodologia, e n ao apenas XP.

6.11.7

Senten cas para facilitar a extens ao de um programa

` medida que o tempo passa, novas exig A encias (especica c oes) s ao realizadas pelos usu arios, e o analista/programador deve modicar o programa com o objetivo de dar resposta ` as novas necessidades do usu ario [Winblad et al., 1993]. Encapsular classes. Ocultar estruturas de dados. Evite percorrer muitas associa co es para executar determinada tarefa. Evite instru co es case sobre o tipo de objeto. Distinga m etodos p ublicos dos privados.

6.11.8

Senten cas para programa c ao em grande escala

Veja a seguir um conjunto de senten cas para o desenvolvimento de programas em grande escala [Winblad et al., 1993, Rumbaugh et al., 1994]. N ao inicie o programa prematuramente. Mantenha os m etodos compreens veis. Fa ca m etodos leg veis. Utilize os mesmos nomes do modelo de objetos. Escolha os nomes cuidadosamente. Utilize diretrizes (regras) de programa ca o. Procure criar m odulos empacotando as classes. Documente as especica co es, classes, m etodos, atributos e as associa co es. Deixe o usu ario ter acesso a essas informa co es. Fa ca um documento de uso do programa pelo usu ario. Embora o texto apresentado nesta parte do livro seja introdut orio, considero-o suciente para a maioria dos sistemas a serem desenvolvidos por engenheiros ou novatos da area de Ci encias da Computa ca o, Inform atica ou Sistemas de Informa ca o. Para maiores informa co es sobre engenharia de software veja as refer encias: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.12. RESUMO DO CAP ITULO

177

[Blaha and Rumbaugh, 2006, Teles, 2004, Guedes, 2004, Kruchten, 2003, Pressman, 2002, Fowler and Scott, 2000, Booch et al., 2000, Martin and McClure, 1993, Winblad et al., 1993, Booch, 1986, Coad and Yourdon, 1993].

6.12

Resumo do cap tulo

Neste cap tulo aprendemos as diversas etapas para o desenvolvimento de um software. Desde a especica ca o at e a documenta ca o e a manuten ca o. Vimos que a especica ca o do programa deve ser feita textualmente e pode incluir cen arios de uso do programa, exemplos de uso. Os cen arios s ao visualizados com ajuda dos diagramas de caso de uso, os diagramas mais simples da UML. Em seguida, aprendemos que precisamos fazer uma elabora c ao do problema, um estudo do problema, envolvendo a an alise de dom nio, a identica ca o de pacotes e seus diagramas. Na etapa de an alise orientada a objeto, vimos que o modelo estrutural se preocupa com a identica ca o de classes, dos atributos, dos m etodos e com a montagem do diagrama de classe. Vimos como identicar as associa co es, agrega co es, composi co es, heran cas, restri co es, realiza co es e depend encias e como descrev e-las gracamente com os diagramas de classes. Pelo modelo din amico descrevemos a din amica do sistema, tanto do ponto de vista do usu ario (diagramas de caso de uso) quanto do ponto de vista do sistema. O macrosistema e representado pelos diagramas de sequ encia e de comunica ca o (eventos e mensagens). O comportamento das classes e descrito pelos diagramas de m aquinas de estado. J a a microdin amica, que ocorre dentro dos m etodos, e descrita pelos diagramas de atividade. Na etapa de projeto do sistema denimos conceitos como os protocolos API, a aloca ca o de recursos, a deni ca o do tipo de controle e a especica ca o das plataformas. Inclui ainda a sele ca o de bibliotecas e de ambiente de desenvolvimento. De posse do diagrama de implanta ca o identicamos todos os equipamentos necess arios para colocar o sistema em funcionamento. No projeto orientado a objeto aprendemos a montar os diagramas de componentes e de implanta ca o (execu ca o). Na implementa ca o aprendemos que podemos usar o umbrello para montagem do c odigo inicial utilizando os diagramas de classe. Aprendemos a import ancia do teste de software. Vimos que a documenta ca o e uma etapa fundamental para o desenvolvimento de programas com qualidade. Finalmente, a manuten ca o envolve tanto a adapta ca o do programa ` as novas solicita co es dos usu arios quanto a montagem de bibliotecas reutiliz aveis. Uma maneira de prever o futuro e estar sempre atualizado, ler revistas de programa ca o, inscrever-se em sites de discuss ao das APIs que for utilizar e inscrever-se em sites de desenvolvimento de software. Nota: deve-se ressaltar que os seus primeiros programas utilizando POO consumir ao o mesmo tempo que os desenvolvidos utilizando t ecnicas estruturadas. As vantagens do reaproveitamento aparecem ` a medida que os programas v ao sendo desenvolvidos, ou quando voc e j a disp oe de uma biblioteca OO e pode desenvolver o programa com ela.

6.13

Exerc cios
// Vari aveis float x,y,z, a,b,c;

1. Um programa antigo, escrito em C, tem as seguintes vari aveis e fun co es:

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

178 float media,desvioPadrao; double area, perimetro, volume; double limiteInferior, limiteSuperior; float vetorDados [100]; // Fun c~ oes // Calcula area de uma figura double Area(..); double Perimetro(..); double Volume(..); // Calcula area de uma fun c~ ao double IntegralSimpson(..); double IntegralTrapezio(..); // Fun c~ ao de uma vari avel float Fy(float x); // Fun c~ ao de duas vari aveis float Fz(float x, float y); float FormulaBasca(..); // Calcula m edia de um grupo de dados, de um vetor float Media(..); float DesvioPadrao(..);

6.13. EXERC ICIOS

Monte o diagrama UML de um programa equivalente em C++ (diagrama de classes com atributos, m etodos e associa co es). Dica: voc e deve agrupar atributos e m etodos que se relacionam dentro de classes. 2. Para o diagrama de classes a seguir, acrescente alguns atributos e m etodos (e eventualmente classes) e estabele ca as rela co es entre as classes (associa co es, agrega co es e heran cas). Exemplos de atributos: nome, n umero, capacidade, valor, data, dimens oes, sexo, idade, extens ao, entre outros. Exemplos de m etodos: Contratar(), Despedir(), Abastecer(), Limpar(), PrepararPouso(), ConferirPassagem(), Manuten ca o(), ApertarCinto(), MoverFlaps(), CheckIn(), entre outros. Monte um diagrama de eventos para o piloto. Monte um diagrama de comunica ca o para o passageiro. 3. Descreva, de forma resumida, as etapas para o desenvolvimento de um programa. Diga quais s ao as quatro etapas mais importantes e justique. 4. Fa ca as especica co es de um programa que calcula o ajuste de um conjunto de pares ordenados x,y a uma fun ca o polinomial. Isto e, como determinar uma curva (polinomial, 1D = reta, 2D = par abola) usando m etodos como m nimos quadrados? (a) Monte um diagrama de caso de uso ilustrando cen arios de intera ca o do usu ario com o programa. (b) Monte os diagramas de classe incluindo os conceitos de associa ca o, agrega ca o e heran ca (generaliza ca o/especializa ca o). Justique suas decis oes. (c) Monte diagramas de m aquina de estado para alguma classe. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

6.13. EXERC ICIOS

179

Figura 6.33: Exerc cio modelagem sistema aeroporto.

(d) Monte diagramas de atividade para algum m etodo. Dica: crie classes de fun co es 1D, 2D, de estat stica, de ajuste de curvas, de um simulador.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

180

6.13. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Parte II

POO usando C++

181

Cap tulo 7

Introdu c ao ao C++
Neste cap tulo veremos um pouco da hist oria de C++ (se ca o 7.1), exemplos de aplica co es em C+ (se ca o 7.2), o que e o ANSI C++ (se ca o 7.3) e quais as novidades de C++ (se ca o 7.4). Ademais, veremos quais s ao os tipos de programas em C++ (se ca o 7.5), as diferen cas de nomenclatura entre POO e C++ (se ca o 7.6), os conceitos de pr e-processamento, compila ca o, linkagem, debugagem e otimiza ca o (se ca o 7.7). Por m, veremos como e o layout de um programa em C++ com m ultiplos arquivos (se ca o 7.8).

7.1
C

Um pouco de hist oria

A linguagem C foi desenvolvida por Denis Richard, em 1972, e teve origem na linguagem B, desenvolvida por Ken Thompson, em 1970. O ano de 1978 foi hist orico para a linguagem C, uma vez que naquele foi editado o livro The C Programming Language, o qual teve grande vendagem e foi o respons avel pela divulga ca o de C [Kernighan and Ritchie, 1988]. Veja a seguir algumas caracter sticas de C: O sucesso da linguagem C se deve ao fato de C ser independente de hardware. C tem sido utilizada em programas estruturados. A linguagem C e o sistema operacional Unix foram desenvolvidos conjuntamente. Isto signica que C/C++ e ambientes operacionais como Unix, GNU/Linux e Mac OS X t em uma intera ca o muito ntima. C++ Em 1980, Bjarne Stroustrup desenvolveu a linguagem de programa ca o C++, um superconjunto de C inicialmente chamado C com classes. Observe que o operador ++ e o operador de incremento; assim, C++ e o C incrementado. Isto signica que C++ apresenta uma s erie de vantagens em rela ca o ao C e tem se mostrado extremamente eciente nos mais variados campos de programa ca o, e por isso quase todas as grandes empresas que desenvolvem softwares utilizam C++. Mas, anal de contas, devo aprender C e depois C++, ou ir direto para C++? O criador do C++, Bjarne Stroustrup, arma: Estou rmemente convencido de que e melhor ir direto para C++ [Bjarne, 1999]. 183

184

7.2. EXEMPLOS DE APLICAC OES EM C++

Veja a seguir algumas caracter sticas de C++: E classicada como uma linguagem moderna, de quinta gera ca o. de alto n E vel, orientada a objeto. fortemente tipada. E linguagem de prop E osito geral, ou seja, pode ser utilizada para desenvolver praticamente utilizada nos mais variados tipos de computadores, sistemas todo tipo de programa. E operacionais, aplica co es e em todos os pa ses do mundo [Stroustrup, 2005]. a mais utilizada para montagem de sistemas complexos e grandes, como os sistemas E operacionais Windows, GNU/Linux, e programas como o Oce e o OpenOce. Nota: segundo o IDC International Data Corporation( http://www.idc.com/), a linguagem C++ tem mais de tr es milh oes de programadores; e esse n umero est a crescendo.

7.2

Exemplos de aplica c oes em C++

C++ e uma linguagem de programa ca o de m ultiplos prop ositos, podendo ser utilizada para cria ca o de v arios tipos de aplica co es. Veja a lista de exemplos de aplica co es em C++ no endere co http://www.research.att.com/~bs/applications.html. Desenvolvimento de sistema operacional (kernel, ferramentas, device drivers, rede etc) Microsoft Windows Vista, XP, NT, 98; BeOS (sistema operacional) Internet Internet Explorer; Mozilla, Firefox, Thunderbird Aplica co es com interface gr aca elaborada Microsoft Oce, FrontPage, Money, Project, Exchange, AppleWorks Sistemas gr acos, ambientes de janela, jogos Adobe Photoshop, Illustrator, Acrobat, CDE desktop. KDE. Banco de dados MySQL Sistemas CAD/CAM Autocad Ambientes de desenvolvimento, bibliotecas, linguagens derivadas Qt-designer, kdevelop; CORBA, MICO; C#, Java. Programa ca o cient ca Imago, Sail Veja a seguir alguns exemplos de empresas que usam C++: Amazon, Ericsson, Bloomberg, Google, IBM, Intel, Microsoft, Metrowerks, SGI, Autodesk. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

O ANSI C++? 7.3. O QUE E

185

7.3

O que e o Ansi C++?

O ANSI C++ American National Standards Institute e um comit e que estabelece os conceitos b asicos da linguagem C++, principalmente os referentes ` a sintaxe. Se voc e desenvolver um programa compat vel com o ANSI C++, pode ter certeza de que ele poder a ser compilado por diferentes compiladores de C++ para diferentes plataformas. Note que o compilador tamb em deve estar dentro dos padr oes de C++. Em 1990 foi publicado o ANSI/ISO/IEC:9899:1990, que e o ANSI C ou [C90]. Em 1998 foi aprovado o ANSI/ISO/IEC:14882:1998[E], que e o ANSI C++ ou [C++98]. Em 1999 foi aprovado o ANSI/ISO/IEC:9899:1999[E], que e o ANSI C revisado ou [C99]. Em 2003 foi aprovado o ANSI/ISO/IEC:14882:2003[E], que e o ANSI C++ revisado inclu ndo o TR1 Technical Corrigendum 1, tamb em conhecido como [C++03]. Para 2009 est a prevista a aprova ca o do ANSI/ISO/IEC:14882:2009, que e o ANSI C++ com as inova co es do C++0x. Este livro cobre as deni co es estabelecidas pelo comit e ANSI C++. Nota: voc e encontra maiores informa co es do ANSI C++ no site http://www.open-std.org/ jtc1/sc22/wg21/. As inova co es do C++0x ser ao apresentadas no Cap tulo ?? C++0x O que vem por a ?

7.4

Quais as novidades e vantagens de C++ em rela c ao a C?

A linguagem C++ e uma das melhores linguagens de programa ca o existentes, porque agrupa formula co es altamente abstratas como classes (que permitem um trabalho de alto n vel) e formula co es de baixo n vel (como o uso de ponteiros, aloca ca o din amica de mem oria e at e a utiliza ca o de chamadas de interrup co es que realizam tarefas altamente espec cas). Com C++ um u nico programador consegue gerenciar uma quantidade maior de c odigo. Veja a seguir algumas novidades e vantagens de C++. Como novidades de C++ em rela c ao ao C podemos citar a utiliza ca o de classes, fun co es inline, convers ao de tipo, verica ca o de par ametros de fun ca o, operadores para gerenciamento de mem oria (new/delete), refer encias, constantes, sobrecarga de operador, sobrecarga de fun co es, polimorsmo, templates (gabaritos), tratamento de exce co es e namespaces. Destes novos conceitos, os que mais se destacam s ao o uso de classes, do polimorsmo e os templates. Como vantagens de C++ em rela c ao ao C podemos citar aumento da produtividade, maior reaproveitamento de c odigo, maior qualidade geral do projeto, facilidade de extens ao e manuten ca o. Maior compreens ao geral por toda a equipe de desenvolvimento. importante notar que essas vantagens s E ao compreendidas na medida em que se usa C++. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

186

7.5. QUAIS OS TIPOS DE PROGRAMAS EM C++

7.5

Quais os tipos de programas em C++

Como dito, C++ e um superconjunto de C que foi desenvolvido para dar suporte ` a programa ca o orientada a objeto. A implica ca o dessa heran ca de C em C++ e que voc e ir a se deparar com programas nos seguintes formatos: Programa estruturado escrito em C utiliza os conceitos b asicos de C, dados e fun co es separados. Programa estruturado escrito em C++ utiliza alguns conceitos de C++, como cin/cout, switch, fun co es inline, const e refer encias, ou seja, utiliza algumas novidades de C++ (exemplos nos ap endices). Programa baseado em objeto escrito em C++ utiliza os conceitos de classes e heran cas. Inclui controle de acesso (public, protected e private), fun co es friend e o conceito fundamental de classes (exemplos a partir do Cap tulo 11 Classe). Programa orientado a objeto escrito em C++ inclui o conceito de polimorsmo e pode incluir a utiliza ca o de conceitos da STL, como containers e iteradores (exemplos a partir do Cap tulo 19 Polimorsmo). Programa gen erico escrito em C++ inclui os conceitos de programa ca o gen erica. Inclui a utiliza ca o de algoritmos gen ericos da STL, uso intensivo de containers e iteradores (exemplos na Parte III: Introdu ca o a STL). Este livro tem enfoque na programa ca o orientada a objeto em C++ e na programa ca o gen erica.

7.6

Diferen cas de nomenclatura POO e C++

A Tabela 7.1 mostra as diferen cas entre a nomenclatura da programa ca o orientada a objeto (Parte I Filosoa e modelagem orientada a objeto) e a nomenclatura de C++. Neste livro procurei usar sempre os nomes objeto, atributo e m etodo. Chamarei de fun ca o apenas as fun co es globais e fun co es de C, e chamarei de m etodo as fun co es que s ao implementadas como parte de uma classe. O objetivo e aproximar os conceitos da POO aos de programa ca o em C++. Tabela 7.1: Diferen cas na nomenclatura da POO e de C++. Nomenclatura POO Nomenclatura C++ Objeto Objeto Classe Classe M etodo M etodo/Fun ca o Atributo Atributo, vari avel Mensagem Chamada de fun ca o Subclasse Classe-derivada Superclasse Classe-base Hereditariedade Hereditariedade, deriva ca o

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

7.7. EDITAR, PRE-PROCESSAR, COMPILAR, LINKAR, DEBUGAR E OTIMIZAR

187

7.7

Editar, pr e-processar, compilar, linkar, debugar e otimizar

S ao descritos a seguir alguns conceitos gerais e a seq u encia usual para montagem de um programa. Etapa de edi c ao Um programa em C++ e composto por um ou mais arquivos de texto com as extens oes .h (declara ca o de classes) e .cpp (deni ca o de m etodos da classe). Um arquivo do programa e formado por um conjunto de instru co es de programa ca o que s ao organizadas logicamente para realizar determinadas tarefas. Veja na Figura 7.1 os arquivos de texto Class1.h, Class1.cpp, Class2.h, Class2.cpp e Prog.cpp. Etapa de pr e-processamento a primeira fase da compila E ca o de um programa. Nela o compilador verica as instru co es passadas com o sinal #. Primeiro s ao inclu dos os arquivos externos, depois s ao processadas as macros. Na fase de pr e-processamento, cada letra do arquivo de disco e mapeada para o padr ao Unicode (ISO/IEC 10646) e posteriormente para o conjunto de caracteres de execu ca o. O resultado da fase de pr e-processamento e uma seq u encia de s mbolos que chamamos de unidade de tradu ca o. A unidade de tradu ca o e independente de outros arquivos (veja Figura 7.1). Note ainda que cada arquivo do programa e compilado separadamente. No exemplo a seguir a unidade de tradu ca o vai incluir o arquivo <iostream>. Exemplo: // Arquivo Prog.cpp #include <iostream> int main() { std::cout < < "Oi tudo bem!";

return 0; }

Para gerar o arquivo de pr e-processamento digite: g++ -E Prog.cpp > Prog.ii . Note que o arquivo gerado e muito grande. Etapa de compila c ao o compilador O compilador e o programa respons avel pela convers ao do programa (texto) escrito usando uma linguagem de programa ca o, em c odigo bin ario (linguagem de m aquina); ou seja, o compilador realiza a tradu ca o do c odigo em linguagem de m aquina. Adicionalmente, o compilador encontra os erros de sintaxe do programa e, depois de compilado, o programa passa a ter um arquivo objeto *.obj (*.o no Unix, GNU/Linux). Observe na Figura 7.1 que cada classe tem dois arquivos (Class1.h e Class1.cpp) e que, ap os a compila ca o do Class1.cpp, e gerado o arquivo Class1.o. Etapa de liga c ao o linker O linker e o programa que agrupa um ou mais arquivos objeto *.obj (*.o) em um arquivo execut avel, resolvendo as depend encias (entre os arquivos) e fazendo as liga co es necess arias. Os erros de liga ca o s ao detectados pelo linker. Os arquivos que ser ao agrupados s ao relacionados em um arquivo de projeto ou em um arquivo Makele. Depois de linkado um programa tem um arquivo execut avel (*.exe no Windows, a.out no GNU/Linux). Na Figura 7.1, o linker e utilizado para gerar o programa nal. Veja na Tabela 7.2 as extens oes dos arquivos gerados nas Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

188

7.7. EDITAR, PRE-PROCESSAR, COMPILAR, LINKAR, DEBUGAR E OTIMIZAR

Figura 7.1: Seq u encia de montagem de um programa.


pr-processador Definio da classe

Class1.h Class1.ii Class1.cpp

compilador

[opcional]

Definio dos mtodos da classe

Class1.o

lib Biblioteca

Class2.h Class2.ii Class2.cpp Arquivo com a funo int main()

Class2.o

Prog

Prog.ii Prog.cpp Prog.o linker

diferentes plataformas. Observe que diversos arquivos objeto .o podem ser agrupados em uma biblioteca. Etapa de debugagem o debuger O debuger e um programa que ajuda o programador a encontrar os erros de programa ca o os famosos bugs. Com um debuger podemos analisar a execu ca o do programa passo a passo (ou linha a linha), e a cada passo podemos vericar o que est a acontecendo. Etapa de otimiza c ao o proler O proler e um programa que ajuda o programador a identicar os pontos do programa que consomem mais tempo (ou seja, onde o programa est a lento). De posse dessa informa ca o podese melhorar a qualidade do programa e a sua velocidade;. para isso, apenas rode o programa de dentro do proler e analise os resultados de tempo de execu ca o de cada fun c ao. Tabela 7.2: Extens oes usuais dos arquivos nas diferentes plataformas. Situa ca o DOS/Windows Unix, GNU/Linux Mac antes de compilar nome.h/nome.cpp nome.h/nome.cpp nome.h/nome.cpp depois de pr e-processar nome.ii nome.ii nome.ii depois de compilar nome.obj nome.o nome.o depois de linkar nome.exe a.out ou nome a.out ou nome Veremos as diretrizes de pr e-processador no Ap endice A Diretrizes de pr e-processador. Veremos em detalhes o compilador da GNU, o g++, no Cap tulo ?? Compilando com gcc e g++. Veremos a debugagem de programas no Cap tulo ?? Uma introdu ca o aos bugs e a debugagem de programas e no Cap tulo ?? Os programas gdb, ddd e o bugzilla. Por m, veremos o uso de prolers no Cap tulo ?? Auditoria e otimiza ca o de programas. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

7.8. LAYOUT DE UM PROGRAMA ORIENTADO A OBJETO EM C++2

189

7.8

Layout de um programa orientado a objeto em C++2

Veremos nesta se ca o o layout e uma estrutura-padr ao para os arquivos de um programa orientado a objeto em C++; j a no pr oximo cap tulo, veremos nossos primeiros exemplos. A implementa ca o de um programa inicia com a deni ca o do arquivo de projeto. Ele lista todos os arquivos que fazem parte do projeto (veja se ca o 7.8.1). Depois de criado o arquivo de projeto, s ao criados os arquivos de cabe calho (*.h) com a deni ca o da classe, e os arquivos de implementa ca o (*.cpp) com a deni ca o dos m etodos da classe. Note na Figura 7.1 que, para cada classe criada, s ao gerados dois arquivos, CNomeClasse.h e CNomeClasse.cpp. O programa principal, aquele que tem a fun ca o main(), deve estar em um arquivo separado, com a extens ao .cpp (exemplo: Programa.cpp). Nas se co es que seguem apresentaremos o prot otipo e a em seguida um exemplo de cada tipo de arquivo. O arquivo de cabe calho da classe (*.h) e apresentado na se ca o 7.8.2, e um exemplo, a declara ca o da classe CAplicacao, e apresentado na listagem 7.1. O arquivo de implementa ca o da classe (*.cpp) e apresentado na se ca o 7.8.3, e um exemplo, a implementa ca o dos m etodos da classe CAplicacao, e apresentado na listagem 7.2. O arquivo de implementa ca o da fun ca o main() e apresentado na se ca o 7.8.4, e um exemplo e apresentado na listagem 7.3.

7.8.1

Arquivo de projeto

A organiza ca o dos programas separando o c odigo em diversos arquivos facilita sua manutenc a o e possibilita um maior entendimento da estrutura dos programas; conseq uentemente, todo o processo de compila ca o/recompila ca o ca mais r apido. O arquivo de projeto dene quais arquivos fazem parte do programa e em que seq u encia devem ser compilados. Ademais, ele cont em uma lista com os nomes dos arquivos de cabe calho (*.h) e de implementa ca o (*.cpp) e a forma como os mesmos ser ao compilados e linkados. Vimos na se ca o 6.6.6 os diferentes compiladores e ambientes de desenvolvimento de C++. Cada ambiente de desenvolvimento gera um arquivo de projeto pr oprio. Por exemplo: um arquivo de projeto do Borland C++ tem a extens ao *.ide ou *.prj; um arquivo do Microsoft Visual C++, por sua vez, tem a extens ao *.mfc. No kdevelop a extens ao e *.kdevelop, e no Dev C++, *.dev. No Unix e no GNU/Linux, o arquivo de projeto costuma ser um arquivo Makele. Nota: veremos, no Cap tulo ?? Make, como montar arquivos de projeto Makele e, no Cap tulo ?? Montagem de um programa multiplataforma com ferramentas da GNU, como montar arquivos de projeto independente de plataforma. Veja exemplo de arquivo Makele na se ca o ??.

7.8.2

Arquivo de cabe calho da classe CNomeClasse.h

A deni ca o da classe e armazenada em arquivos de cabe calho com a extens ao *.h. Observe no prot otipo a seguir que inclu mos a documenta ca o. No primeiro bloco de coment arios inclu mos informa co es gerais sobre o programa, o nome do arquivo e dos autores. Depois inclu mos as bibliotecas padr oes de C++ que ser ao utilizadas e iniciamos a deni ca o da classe com um breve coment ario sobre o que a classe e e representa. Em seguida denimos a forma de acesso a cada atributo/m etodo. Por m, declaramos os atributos e m etodos da classe colocando um breve coment ario sobre o que cada atributo/m etodo representa. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

190

7.8. LAYOUT DE UM PROGRAMA ORIENTADO A OBJETO EM C++2

Prot otipo: /** Cabe calho do programa Documenta ca o geral do programa, do sistema como um todo. @autor nome do(s) autor(es) @le CNomeClasse.h */ /// Inclus ao das bibliotecas padr oes de C++ #include <iostream> /// Documenta ca o da classe CNomeClasse /// O que a classe e e representa... class CNomeClasse { /// Especica ca o do controle de acesso public: /// Declara ca o de atributo Tipo nomeAtributo; /// Declara ca o de m etodo TipoRetorno NomeM etodo(Par ametros); }; Apresenta-se na listagem 7.1 o arquivo de cabe calho da classe. Al em da declara ca o e deni ca o da classe, inclu mos uma breve documenta ca o da classe e uma descri ca o do m etodo Run(). Procurou-se incluir a maioria dos itens presentes em um programa real. Listing 7.1: Exemplo b asico: Arquivo de cabe calho da classe.
// Este p r o g r a m a e x e m p l i f i c a a e s t r u t u r a / layout de um // p r o g r a m a t pico em C ++ /* * D e c l a r a uma classe minimalista , a classe C A p l i c a c a o A mesma inclui apenas um m e todo , o m e todo Run () . * */ class CAplicacao { public : // / M e todo de e x e c u c~ a o da a p l i c a c~ ao. void Run () ; };

Nota: vimos informa co es b asicas sobre documenta ca o de programas na se ca o 6.10. Veremos, ent ao, como implementar a documenta ca o em C++ no Cap tulo ?? Documenta ca o de programas.

7.8.3

Arquivo de implementa c ao da classe CNomeClasse.cpp

As deni co es dos m etodos da classe s ao armazenadas em arquivos de implementa ca o com a extens ao (*.cpp). Observe, no prot otipo a seguir, que sempre incluiremos o arquivo com o nome da classe #include "CNomeClasse.h". Prot otipo: /** Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

7.8. LAYOUT DE UM PROGRAMA ORIENTADO A OBJETO EM C++2 Cabe calho do programa Documenta ca o geral do programa, do sistema como um todo. Implementa os m etodos da classe CNomeClasse,... @autor nome do(s) autor(es) @le CNomeClasse.cpp */ /// Inclus ao das bibliotecas .padr ao de C++ #include <iostream> /// Inclus ao das bibliotecas do grupo de programadores #include CNomeClasse.h /// Deni ca o dos m etodos da classe TipoRetorno CNomeClasse::NomeM etodo(Par ametros) { ..Conjunto de tarefas a serem realizadas..; }

191

Apresenta-se na listagem 7.2 o arquivo de implementa ca o da classe CAplicacao. Observe que depois de incluir o arquivo CAplicacao.h, implementamos o c odigo do m etodo Run(). Listing 7.2: Exemplo b asico: Arquivo de implementa ca o da classe.
Este p r o g r a m a e x e m p l i f i c a a e s t r u t u r a / layout de um p r o g r a m a t pico em C ++ */ # include < iostream > // / Inclui a d e c l a r a c~ a o da classe # include " CAplicacao . h " // / I m p l e m e n t a os m e t o d o s da classe // / O m e todo Run () e s c r e v e uma m e n s a g e m na tela void CAplicacao :: Run () { // std :: cout e s c r e v e na tela o texto " Bem - vindo ao C ++!" std :: cout << " Bem - vindo ao C ++! " << std :: endl ; } /* *

Nota: em Java todo c odigo da classe ca em um u nico arquivo. Prero o formato usado por C++; a separa ca o da implementa ca o em um arquivo *.cpp deixa o arquivo de cabe calho mais enxuto e mais claro.

7.8.4

Arquivo de implementa c ao da fun c ao main() programa.cpp

Al em do arquivo de deni ca o *.h e do arquivo de implementa ca o *.cpp, voc e vai precisar de um arquivo com a deni ca o da fun ca o main(), a qual e chamada quando o programa e executado. O arquivo programa.cpp usa as classes denidas pelo programador. Veja o prot otipo a seguir: Prot otipo: /** Cabe calho do programa Documenta ca o geral do programa, do sistema como um todo. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

192 @autor nome do(s) autor(es) @le programa.cpp */ /// Inclui as classes que ser ao utilizadas #include CNomeClasse.h /// Implementa a fun ca o principal, main() int main() { TipoPar ametro par ametro; // Cria par ametro CNomeClasse objeto; // Cria objeto objeto.NomeM etodo(par ametro); // Usa m etodo do objeto criado return 0; }

7.9. SENTENCAS

Veja na listagem 7.3 a implementa ca o da fun ca o main(). O programa inicia com a fun ca o main(), na qual um objeto do tipo CAplicacao com nome ap e criado. O objeto ap executa o m etodo Run() que envia para a tela a mensagem "Bem-vindo ao C++". Ap os a execu ca o do m etodo Run(), o controle volta para a fun ca o main() e termina ao nal desta fun ca o com um return 0;. Para compilar o programa no GNU/Linux g++ Programa.cpp CAplicacao.cpp Para executar o programa no GNU/Linux /a.out Listing 7.3: Exemplo b asico: Arquivo de implementa ca o da fun ca o main().
/* * Este p r o g r a m a e x e m p l i f i c a a e s t r u t u r a / layout de um p r o g r a m a t pico em C ++ */ // Inclui o a r q u i v o " C A p l i c a c a o . h " que tem a d e c l a r a c~ a o da classe C A p l i c a c a o # include " CAplicacao . h " // A fun c~ a o main () , r e t o r n a um inteiro , se chama main () e // n~ a o tem nenhum p a r ^ ametro int main () { CAplicacao ap ; // Cria objeto do tipo C A p l i c a c a o com nome ap ap . Run () ; return 0; } Bem vindo ao C ++! // E x e c u t a o m e todo Run () do objeto ap // A fun c~ a o main () deve r e t o r n a r um i n t e i r o // o zero indica que o p r o g r a m a t e r m i n o u bem .

7.9

Senten cas

Observe que, de modo geral, arquivos de programa ca o em C t em a extens ao .c, e arquivos de programa ca o em C++ t em a extens ao .cpp (de C plus plus ou C mais mais). C++ e extensivamente utilizado em aplica co es cient cas, em programas com interface gr aca e em programas com muita intera ca o com o usu ario. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

7.10. RESUMO DO CAP ITULO

193

Programas de engenharia, f sicos e matem aticos s ao bem representados em C++, pois as diferentes areas da matem atica s ao facilmente modeladas como classes em C++. Isto e, faz-se uma associa ca o clara entre conceitos matem aticos e classes de C++. Se voc e utilizou uma ferrramenta UML como o umbrello (veja se ca o 4.4.2), pode gerar automaticamente a estrutura inicial dos arquivos *.h e *.cpp. Assim, para cada classe criada, o umbrello gera os respectivos arquivos .h e .cpp.

7.10

Resumo do cap tulo

Neste cap tulo aprendemos um pouco sobre a hist oria da linguagem C++, a qual tem origem na linguagem C, que, por sua vez, e derivada da linguagem B. Ser a que existiu uma linguagem A? Vimos que a linguagem C++ e derivada da linguagem C e que, em fun ca o das transforma co es ocorridas nos u ltimos anos, podemos ter programas C++ em diferentes formatos: estruturado, baseado em objeto, orientado a objeto, ou, ainda, utilizando programa ca o gen erica. Aprendemos que o ANSI C++ e o comit e respons avel pela padroniza ca o de C++ e que, ao fazermos um programa usando ANSI C++, esse deve compilar e rodar em centenas de plataformas. Vimos as diferen cas na nomenclatura de POO e C++. Aprendemos os conceitos b asicos de compila ca o, gera c ao do c odigo objeto, e a linkagem montagem do programa execut avel. Vimos que os debugers s ao utilizados para localiza ca o dos bugs do programa e que os prolers s ao utilizados para melhorar a performance do programa. Por m, vimos o layout de um programa em C++. Dica: ao nal de cada cap tulo dedique cerca de 5-10 minutos para fazer uma r apida revis ao dos conceitos apresentados.

7.11

Exerc cios

1. Fa ca uma pesquisa na internet sobre a hist oria de C++. 2. Quais as vantagens da padroniza ca o do Ansi C++? 3. V a at e o site do Ansi C++ (procure por Ansi C++) e veja quais novidades est ao previstas para os pr oximos anos. 4. Procure na biblioteca por livros de C/C++. Coloque-os em ordem de data de publica ca o e, em seguida, compare os c odigos. Veja que a forma como os programas s ao desenvolvidos tem modicado constantemente (veja se ca o 7.5). 5. Quais s ao as tarefas do compilador? 6. Quais s ao as tarefas do pr e-processador? 7. Quais s ao as tarefas do linker? 8. O que s ao e para que servem os debugers e os prolers? 9. Quantos arquivos t em um programa OO m nimo em C++. Qual e sua extens ao e conte udo?

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

194

7.11. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 8

Conceitos b asicos de C++


Veremos neste cap tulo alguns conceitos b asicos de C++: a sintaxe (se ca o 8.1), as palavraschave do C++ (se ca o 8.2) e como voc e deve nomear (se ca o 8.3), declarar (se ca o 8.4) e denir os seus objetos (se ca o 8.5). Veremos ainda uma s erie de introdu co es, incluindo: introdu ca o ` a fun ca o main() (se ca o 8.6), alguns exemplos de programas em C++ (se ca o 8.7), introdu ca o ` a entrada e sa da de dados com cin e cout (se ca o 8.7), introdu ca o ` as diretrizes de pr e-processador (se ca o 8.8), introdu ca o ` as estruturas de controle (se ca o 8.9), introdu ca o aos operadores de C++ (se ca o 8.10), introdu ca o as fun co es (se ca o 8.11), e a rela ca o entre declara co es e escopo (se ca o 8.12). No nal do cap tulo veremos algumas senten cas (se ca o 8.13).

8.1

Sobre a sintaxe de C++

Veremos a seguir alguns conceitos b asicos da sintaxe de C++. Esses conceitos ser ao mais bem compreendidos posteriormente, com as listagens de programas que ser ao apresentadas. Arquivo e um texto que cont em c odigo-fonte em C++ e diretrizes para o pr e-processador. Coment arios s ao utilizados para descrever/detalhar o funcionamento de determinadas partes do c odigo. Um coment ario em C utiliza os caracteres /* para iniciar o coment ario e */ para encerrar o coment ario. Um coment ario em C++ utiliza duas barras //; tudo o que estiver ap os as duas barras e coment ario. Note que o arquivo e composto por linhas de texto e que o coment ario de C++ e v alido apenas para linha em que foi inclu do. Exemplo: /* Aqui e coment ario */ Aqui e programa ; // Aqui e coment ario. S mbolos existem cinco tipos de s mbolos em um programa C++: palavras-chave, identicadores, operadores, literais e separadores. Esses tipos de s mbolos s ao brevemente descritos a seguir. Palavras-chaves s ao de uso interno do C++, t em signicado para a linguagem, para o processo de compila ca o, e n ao podem ser utilizados para nomear objetos. Veja se ca o 8.2. Identicadores um identicador e uma seq u encia de letras usadas pelo programador para dar nome aos objetos, atributos e m etodos. Um nome denota um objeto, uma 195

196

8.1. SOBRE A SINTAXE DE C++ fun ca o, um enumerador, um tipo, um membro de classe, um modelo, um valor ou um label (veja se ca o 8.3). Al em disso, pode estar denido em uma biblioteca externa. No exemplo a seguir criamos tr es n umeros inteiros com os nomes x, y, z. Exemplo: int x,y,z; char nomeDaPessoa[50]; // x,y e z s~ ao identificadores // nomeDaPessoa e um identificador

Operadores o s mbolo + e o operador soma, sendo utilizado para somar dois objetos. J a o operador ++ e utilizado para incrementar o valor de uma vari avel, ou seja, operadores s ao s mbolos cuja utilidade j a e denida pelo C++. Os operadores de C++ est ao listados na Tabela C.1. Veremos os operadores em detalhes no Ap endice C Operadores. No exemplo a seguir temos tr es exemplos de operadores: operador soma (+), que e bin ario (atua sobre dois objetos); operador incremento (++), que e un ario (atua sobre um u nico objeto); e o operador de compara ca o maior que (>) . Neste exemplo, se x for maior do que y retornar a verdadeiro. Exemplo: + e o operador de soma ( e um operador bin ario). ++ e o operador de incremento ( e um operador un ario). x > y; o s mbolo > e o operador maior que. Literais tipos de vari aveis previamente denidas pela linguagem C++ para representar objetos de uso corrente. Como exemplo podemos citar: um booleano, um caracter, um n umero inteiro, um n umero em ponto utuante, uma string constante. Exemplo: int x = 5; char c = a; float y = 5.3; char* nome = "Vinicios"; // // // // O n umero 5 e um literal A letra a e um literal O n umero 5.3 e um literal Vinicios e um literal

Declara c ao diz que existe um objeto com nome fulano de tal, mas n ao cria o objeto. Uma declara ca o pode ser repetida (veja se ca o 8.4). A partir de sua declara ca o um objeto pode ser utilizado. Exemplo: extern int a; extern const int c; int f(); struct S; class C; // // // // // Declara Declara Declara Declara Declara um inteiro a inteiro constante C que existe uma fun c~ ao f() que existe uma estrutura S que existe uma classe C

Deni c ao uma deni ca o cria um ou mais objetos e reserva mem oria. Uma deni ca o n ao pode ser repetida (veja se ca o 8.5). Veremos o uso de extern na se ca o B.2.1. Exemplo: int b; extern const int c = 1; int f(){ return 5; }; // Cria/define um n umero inteiro b // Atribue valor para c // Define a fun c~ ao f()

Atribui c ao quando se armazena algum valor no objeto. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

8.1. SOBRE A SINTAXE DE C++ Exemplo: int x = 5;

197

// Atribui o valor 5 para x

Classes de armazenamento denem o tempo de vida de um objeto, podendo ser est atico (existe durante toda execu ca o do programa) ou din amico (existe por um determinado per odo de tempo). Veja nas se co es B.1 e B.3 informa co es sobre classes de armazenamento e modicadores de acesso. Escopo dene onde um objeto e vis vel. O escopo pode ser local {bloco}, de fun ca o, de arquivo, de classe ou global (veja se co es 8.12 e B.4). Blocos um bloco se inicia com { e termina com }. Objetos criados dentro do bloco est ao no escopo do bloco e n ao podem ser acessados externamente. Objetos criados dentro do bloco s ao objetos autom aticos, e estes s ao automaticamente destru dos quando o bloco e encerrado. Exemplo: { ... } // Inicio do bloco // Fim do bloco

Tipos predenidos tipos de objetos previamente denidos pela linguagem C++ (veja Cap tulo 9 Tipos). Exemplo: int x; long int r; unsigned int s; float y; double z; // // // // // N umero N umero N umero N umero N umero inteiro, com nome x inteiro longo com sinal, com nome r inteiro sem sinal, com nome s flutuante, com nome y com dupla precis~ ao, com nome z

Tipos derivados tipos denidos pelo programador, como estruturas, enumera co es e uni oes (veja Cap tulo 9 Tipos). No exemplo a seguir denimos a classe CPessoa, com os atributos nome e idade. Exemplo: class CPessoa { public: string nome; int idade; }; // CPessoa e um tipo do usu ario

Especicador e uma palavra-chave da linguagem que e utilizada para denir o tipo do objeto ou modicar determinado tipo. Por exemplo: um especicador inline e utilizado para modicar a forma com que a fun ca o/m etodo ser a compilada. Um especicador de tipo informa o tipo do objeto. Um especicador typedef e usado para criar um apelido para um tipo conhecido (veja Cap tulo 9 Tipos). Exemplo: int x; inline void f() { cout < < "saida" < < typedef float racional; // int e o especificador // inline e o especificador endl; } // typedef e float s~ ao o especificador Andr e Duarte Bueno

Programa ca o Orientada a Objeto com C++

198

8.2. PALAVRAS-CHAVE DO C++

Lvalues um objeto e uma regi ao de armazenamento de mem oria. Um lvalue e uma express ao que se refere a um objeto ou fun ca o (o retorno e algo ativo). Pode aparecer ` a esquerda do sinal igual (=), podendo ser alterado. Objetos especicados como const n ao s ao lvalues. Exemplo: int x = 3; const int y = 3; // x e um lvalue. // y N~ AO e um lvalue.

Diretrizes de pr e-processador s ao informa co es/instru co es que s ao passadas para o compilador com o s mbolo #. Veremos o uso das diretrizes de pr e-processador no Ap endice A Diretrizes de pr e-processador.

8.2

Palavras-chave do C++

Uma linguagem de programa ca o faz uso extensivo de determinadas palavras, denominadas palavras-chave. Essas palavras foram denidas para a linguagem C++ e s ao utilizadas pelo programador com algum objetivo espec co. Como essas palavras j a t em um signicado predenido para a linguagem, voc e n ao pode declarar um objeto com o mesmo nome de uma palavra-chave, pois o compilador faria uma confus ao e acusaria erro. Com o objetivo de economizar palavras, algumas palavras-chave t em mais de uma utilidade, por exemplo, a palavra-chave virtual, que pode especicar um m etodo virtual ou uma heran ca virtual. Outro exemplo e void, que, para ponteiros, e um ponteiro para qualquer coisa e, para m etodos, signica aus encia de par ametros ou aus encia de retorno. Veja as palavraschave do ANSI C++ na Tabela 8.1. As palavras-chave est ao classicadas de acordo com seu uso. Tabela 8.1: Palavras chaves do ANSI C++. Tipos Modicadores de tipos Controle L ogicos Mem oria Controle de acesso Convers oes Exce co es Diversos bool, char, wchar_t, short, int, long, float, double, long double, void auto, const, extern, mutable, register, signed, static, typedef, unsigned, volatile break, case, continue, default, do, else, for, goto, if, return, switch, while and, and_eq, bitand, bitor, compl, false, not, not_eq, or, or_eq, true, xor, xor_eq delete, new private, protected, public const_cast, dynamic_cast, reinterpret_cast, static_cast try, throw, catch asm, class, enum, explicit, export, friend, inline, namespace, operator, sizeof, struct, template, this, typeid, typename, union, using, virtual

Dica: a linguagem C/C++ reservou alguns identicadores para uso futuro voc e deve evitar o seu uso. S ao eles: is (exemplo: isblank), mem, str (exemplo: strtof), to, wcs. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

8.3. NOME DOS OBJETOS IDENTIFICADORES

199

8.3

Nome dos objetos identicadores

O nome de um objeto deve come car com uma letra (a-z, A-Z) ou sublinhado ( ). A linguagem C++ difere mai usculas e min usculas, ou seja, AA e diferente de aa. A especica ca o-padr ao de C++ tamb em permite o uso de caracteres especiais como . Embora possa ser utilizado no in cio de um nome, ele deve ser evitado. O uso de dois underscores, como em nome objeto, e reservado, devendo ser evitado. Caracteres v alidos a-z A-Z 0-9 + - * / = , . : ; ? \ | ! # $ & ( ) [ ] { } Caracteres inv alidos ++ = *= /= ?: :: /** == && // << >> >= <= += -

8.3.1

Conven c ao para nomes de objetos

Para facilitar a leitura do programa, e usual a ado ca o de uma conven ca o para nomear os objetos. Veja na Tabela 8.2 um exemplo. Veremos a seguir como declarar e denir objetos em C++. Tabela 8.2: Conven ca o para nomes de objetos. Tipo de Objeto Vari aveis #dene Nome de classes Nome de estruturas Nome de uni oes Nome de enumera co es Nome de m etodos/fun co es Atributos Atributos est aticos Formato do Nome #dene MAIUSCULA; CNomeClasse; SNomeEstrutura UNome ENome InicialMai uscula(); inicialMin uscula min usculas Exemplos #dene SIZE 100 class CNormal{...}; struct SData{}; union UPressao{}; enum ESemana{}; int MediaPonderada(); int mediaPonderada; static int contador;

8.4

Declara c oes

Uma declara ca o introduz um ou mais nomes em um programa e especica como esses nomes devem ser interpretados. Uma declara ca o n ao reserva mem oria para o objeto, apenas diz que ele existe. Al em disso, declara ca o pode ser uma fun ca o, um tipo, um objeto (constante ou vari avel), um namespace, um template ou uma entidade relacionada, [Lischner, 2003]. Veja no prot otipo a seguir que uma declara ca o tem tr es componentes: os qualicadores, os especicadores e os declaradores. Prot otipo Qualicadores Especicadores Declarador; Qualicador especica o tipo de linkagem, est atica ( static ), externa ( extern ), ou export (veja se ca o B.2), ou modica o tipo de acesso com const , volatile e mutable (veja se ca o B.3). A ordem dos qualicadores n ao importa, isto signica que extern const volatile int x; e o mesmo que const extern volatile int x;. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

200

8.5. DEFINIC OES Especicador indica o tipo fundamental, a classe de armazenamento ou outras propriedades dos objetos declarados. Declarador especica o nome dos objetos e opcionalmente modica o tipo com um * . Um declarador pode especicar um valor inicial para o identicador que est a sendo declarado ( = ). Exemplo: static int x1; int x2; class CPonto; typedef int I; int * ptr; int& ref = &x1;

// // // // // //

Declara Declara Declara Declara Declara Declara

um objeto int est atico, com nome x1 um objeto do tipo int com nome x2 um nome de classe um sin^ onimo para int (um apelido) um objeto ponteiro para int uma refer^ encia para x1.

Ao longo do livro veremos como declarar e usar tipos mais elaborados, como vetores, arrays, tipos do usu ario e tipos denidos em bibliotecas externas.

8.4.1

Exemplos de declara c oes e deni c oes2

Veja na Tabela 8.3 exemplos de declara co es e deni co es de objetos. Inclu mos declara co es de matrizes, fun co es e ponteiros. Tabela 8.3: Exemplos de declara co es e deni co es. Sintaxe da declara ca o Tipo nome[]; Tipo nome[3]; Tipo* nome; Tipo* nome[]; Tipo* (nome[]); Tipo (*nome)[]; Tipo& nome; Tipo nome[nx][ny]; Tipo nome[nx][ny][nz]; Tipo nome(); Tipo*nome(); Tipo*( nome()); Tipo (*nome)(); Tipo efetivo Vetor do Tipo Vetor do tipo com tr es elementos Ponteiro para tipo Vetor de ponteiros para tipo Vetor de ponteiros para tipo Ponteiro para vetor do tipo Refer encia para o tipo Matriz 2D com nx por ny elementos Matriz 3D com nx por ny por nz elementos Fun ca o que retorna o tipo Fun ca o que retorna ponteiro tipo* Fun ca o que retorna ponteiro Tipo* Ponteiro para fun ca o que retorna o Tipo Exemplo int cont[]; int cont[3]; //0,1,2 int* ptr; int* cont[]; int* (cont[]); int (*cont)[]; int& cont; int m[5][6]; int m[5][6][4]; int cont(); int* cont(); int*(cont()); int (*cont)()

8.5

Deni c oes

Uma deni ca o dene o tipo de armazenamento, o valor, o corpo e o conte udo de uma declara ca o. Enquanto uma declara ca o informa que algo existe (interface), uma deni ca o a implementa e especica como aquela funciona. A deni ca o de uma fun ca o, por exemplo, inclui o corpo da fun ca o [Lischner, 2003]. Al em disso, uma deni ca o faz com que seja reservada a quantidade adequada de mem oria para o objeto e seja feita qualquer inicializa ca o apropriada. Uma declara ca o de uma deni ca o, por sua vez, a menos que contenha um extern e n ao tenha um inicializador. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A ` FUNC MAIN() 8.6. INTRODUC AO AO Exemplo: extern int x; // Declara c~ ao: informa que existe um int x int y; // Defini c~ ao: reserva espa co de mem oria para y Deni c ao simples consiste em declarar um objeto de cada vez. Exemplo: int x;

201

// Define objeto do tipo int, com nome x

Deni c ao m ultipla consiste em declarar v arios objetos de uma u nica vez. A deni ca o m ultipla deve ser evitada, pois o ideal e declarar um objeto por linha e incluir um coment ario sobre o objeto. Exemplo: float r,s,t;

// Define objetos do tipo float, com nome r,s,t

Deni c ao com inicializa c ao consiste em declarar um objeto e, ao mesmo tempo, atribuir um valor a esse objeto. Exemplo: int x = 7; float y = 5.2; int r(30); int s[4];

// // // //

O mesmo que int x(7); Inicializa y com o valor 5.2 Inicializa r com o valor 30 Cria array com 4 elementos, valores = 0

8.6

Introdu c ao ` a fun c ao main()

Quando voc e roda um programa, o sistema operacional carrega-o na mem oria e em seguida inicia na fun ca o principal, que inicia a execu ca o do programa. Em programas em C e C++, a fun ca o inicial de um programa e chamada main(). Veremos a seguir dois prot otipos para fun ca o main(), e nas listagens 8.1 e 8.3, veremos exemplos de uso. Prot otipo int main() {..... return 0;} A fun ca o retorna um n umero inteiro e n ao recebe nenhum par ametro. int main(int argc, const char *argv[]) {...... return 0;} A fun ca o retorna um n umero inteiro e recebe dois par ametros. O par ametro argc e o n umero de elementos digitados na linha de comando e argv[] o vetor para as strings digitadas na linha de comando. Nota: veremos detalhes e exemplos de uso da fun ca o main() na se ca o E.1.

8.7

Introdu c ao ` a entrada e sa da de dados com cin e cout

Apresenta-se nesta se ca o uma breve introdu ca o ` a entrada e sa da de dados em C++ usando os objetos cin e cout. Isto e suciente para os nossos primeiros exemplos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

202

A ` ENTRADA E SA 8.7. INTRODUC AO IDA DE DADOS COM CIN E COUT

8.7.1

Usando cout

Veja na listagem 8.1 nosso primeiro exemplo de programa em C++, o qual mostra como enviar textos para tela. O programa inicia-se incluindo um coment ario na linha // Arquivo listagens/Cap-08/novaLinha-tab-beep.cpp Em seguida, inclui um arquivo da biblioteca-padr ao de C++, a <iostream>, na linha #include <iostream> A <iostream> e uma biblioteca utilizada para entrada e sa da de dados. Ela fornece o objeto std::cout, utilizado para enviar uma mensagem para a tela (cout = C out ). Esse exemplo inclui ainda a fun ca o inicial de um programa em C++. int main() { Dentro da fun ca o main(), o objeto std::cout envia para a tela a mensagem Bem std::cout < < "Bem" < < \t < < "Vindo!\n"; O caractere \t e utilizado para colocar uma tabula ca o entre a palavra "Bem" e a palavra "Vindo". Em seguida, o programa envia para a tela a mensagem "Bem Vindo ao C++!", std::cout < < "B\ne\nm\n\nVindo ao C++!\a" < < std::endl; incluindo, entre cada caractere da palavra "Bem", uma nova linha \n. O caractere \n e utilizado para colocar uma quebra de linha. O caractere \a e usado para emitir um beep. O trecho std::endl e usado para incluir uma linha nova e enviar o texto imediatamente para tela. O manipulador std::endl; e fornecido pelo arquivo <iostream>. Au ltima linha da fun ca o main() ea return 0; } utilizada para nalizar a fun ca o main() e o programa, retornando para o sistema operacional o valor 0. O retorno do valor 0 indica para o sistema operacional que o programa terminou com sucesso sua execu ca o. Observe ap os a listagem como cou a sa da. Listing 8.1: Usando sa da para tela, nova linha, tabula ca o e beep.
// A r q u i v o l i s t a g e n s/ Cap -08/ novaLinha - tab - beep . cpp # include < iostream > int main () { std :: cout << " Bem " << \ t << " Vindo !\ n " ; std :: cout << " B \ ne \ nm \ n \ nVindo ao C ++!\ a " << std :: endl ; return 0; }

Vindo!

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

A ` ENTRADA E SA 8.7. INTRODUC AO IDA DE DADOS COM CIN E COUT


bash -3.00 $ ./ a . out Bem Vindo ! B e m Vindo ao C ++!

203

Os caracteres \n(nova linha), \a (beep) e \t (tabula c~ ao) s ao conhecidos como caracteres de escape. Um caracter de escape e composto de uma barra invertida e uma letra que indica a a ca o a ser executada. Veja na Tabela 22.3 os caracteres de escape de C/C++. Nota: veremos no Ap endice K Arquivos de cabe calho, uma lista com o nome dos diversos arquivos de cabe calho da biblioteca-padr ao de C e C++.

8.7.2

Usando cin

Veja na listagem 8.2 um exemplo com declara ca o de objetos, entrada e sa da de dados. A Figura 8.2 ilustra a execu ca o do programa. Figura 8.1: Diagrama mostrando entrada e sa da de dados em C++.

soma 5

temporria 5

Entre com o valor de a: 2 Entre com o valor de b: 3 Soma = 5

<<objeto>> std::cout

a 2

b 3

cin >> a;
<<objeto>> std::cin

cin >> b;

2 enter 3 enter

Novamente, o programa inicia-se com um coment ario e, em seguida, inclui a bibliotecapadr ao de C++ para entrada e sa da de dados, a <iostream>, a qual, como dito anteriormente, fornece o objeto std::cout, que e utilizado para escrever na tela usando o operador de inser ca o < <. Na linha 7 int a; criamos um n umero inteiro com nome a, e, em seguida, enviamos para a tela uma mensagem solicitando o valor de a. std::cout < < "Entre com o valor de a: "; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

204 Na linha 13

A ` ENTRADA E SA 8.7. INTRODUC AO IDA DE DADOS COM CIN E COUT

std::cin > > a; o valor digitado pelo usu ario e armazenado no objeto a. O arquivo de cabe calho <iostream> fornece o objeto std::cin, utilizado para entrada de dados. O operador de extra ca o > > extrai um objeto do teclado e move-o para o objeto ` a direita do sinal > >, no caso o n umero a. Na linha 16 std::cin.get(); o objeto std::cin e usado para pegar do teclado o enter digitado pelo usu ario e, em seguida, desconsider a-lo. O mesmo procedimento e repetido para a var avel b. Posteriormente, criamos na linha int soma; a vari avel soma, que ser a utilizada para armazenar o resultado da soma de a e b. . Na linha 29 soma = a + b; os valores de a e b s ao somados e o resultado e armazenado em soma. A linha 32 std::cout < < "Soma = " < < soma; e usada para enviar para a tela o resultado da soma. std::cout < < std::endl; e usada para enviar para a tela um caracter de nova linha, evitando-se que a u ltima mensagem enviada pelo programa que sem quebra de linha. Outros coment arios est ao embutidos no texto. A sa da e ilustrada na Figura 8.2. Listing 8.2: Declara ca o de objetos e uso de cin e cout.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // A r q u i v o: ../ l i s t a g e n s / Cap -08/ cout - cin . cpp # include < iostream > int main () { // Um int e um tipo pr e - definido , serve para a r m a z e n a r n umeros inteiros // Na linha a seguir o tipo do objeto e int e seu nome a int a ; // E s c r e v e na tela " Entre com o valor de a :" std :: cout << " Entre com o valor de a : " ; // A r m a z e n a o valor d i g i t a d o no objeto a std :: cin >> a ; // Pega o enter e d e s c o n s i d e r a std :: cin . get () ; int b ; std :: cout << " Entre com o valor de b : " ; std :: cin >> b ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

AS ` DIRETRIZES DE PRE-PROCESSADOR 8.8. INTRODUC AO


21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 std :: cin . get () ; // O b s e r v e que os o b j e t o s s~ a o d e c l a r a d o s perto de onde eles // c o m e c a m a ser usados . int soma ; // V e r i f i c a o tipo de a , o tipo de b , se c o m p a t veis realiza a opera c~ ao+ // o r e s u l t a d o e a r m a z e n a d o na v a r i a v e l soma ( o p e r a d o r =) soma = a + b ; // E s c r e v e na tela o r e s u l t a d o de soma std :: cout << " Soma = " << soma ; // O c o m a n d o std :: endl envia para a tela um final de linha ( linha nova ) std :: cout << std :: endl ; return 0; }

205

Os programas foram compilados e executados em um PC utilizando GNU/Linux e em um PC usando Windows, ambos com software livre. O compilador utilizado e o g++, da GNU. Por default, o compilador da GNU gera um execut avel com nome a.out. Para compilar o programa, abra um terminal, v a para o diret orio onde o programa est a localizado e digite g++ cout-cin.cpp . Para executar o programa, digite ./a.out (no GNU/Linux) e cout-cin.exe (no Windows). Veja a Figura 8.2. Para compilar e executar o programa no ambiente Windows consulte os manuais de seu ambiente de desenvolvimento. Figura 8.2: Compilando e executando programas no shell.

8.8

Introdu c ao ` as diretrizes de pr e-processador

Vimos, na se ca o 7.7, conceitos b asicos de pr e-processamento, compila ca o, linkagem, debugagem e otimiza ca o. Nesta se ca o veremos uma breve introdu ca o ` as diretrizes de pr e-processador de C++ e um pequeno exemplo (listagem 8.3).

8.8.1

Usando #ifdef..#endif

Agora que j a vimos como escrever na tela usando cout e como ler o conte udo de uma vari avel usando cin, podemos apresentar um programa que utiliza diretrizes de pr e-processamento. Como visto na se ca o 7.7, a primeira fase da compila ca o e denominada pr e-processador. Nela o compilador verica as instru co es de compila ca o passadas com o sinal #. No exemplo da listagem 8.3 inclu mos tr es diretrizes de pr e-processador: a primeira inclui o arquivo <iostream>, na linha #include <iostream>; a segunda diretriz de pr e-processador Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

206

AS ` ESTRUTURAS DE CONTROLE 8.9. INTRODUC AO

dene um bloco #ifdef..#endif, ou seja, se a vari avel DEBUG j a foi denida, o programa inclui a parte de c odigo que envia a mensagem "Vers~ ao com vari avel debug ativada" para a tela; do contr ario, a linha com a mensagem e desconsiderada (n ao e compilada). A terceira diretriz e o #endif que naliza o bloco. O exemplo da listagem 8.3 deve ser compilado usando g++ UsandoDiretrizesDePreProcessador-ifdef.cpp e, em seguida, testado ./a.out . Por m, compile usando g++ DDEBUG UsandoDiretrizesDePre-Processador-ifdef.cpp e teste novamente. Veja as diferen cas na sa da. Listing 8.3: Usando diretrizes de pr e-processador: #ifdef.
# include < iostream > int main () { # ifdef DEBUG std :: cout << " Vers~ a o com vari a vel debug ativada " << std :: endl ; # endif return 0; } [ b u e n o @ s u p o r t e 3 ] $ g ++ UsandoDire t r iz e sD e P re - Processador - ifdef . cpp [ b u e n o @ s u p o r t e 3 ] $ ./ a . out [ b u e n o @ s u p o r t e 3 ] $ g ++ - DDEBUG UsandoDire tr i z es D eP r e - Processador - ifdef . cpp [ b u e n o @ s u p o r t e 3 ] $ ./ a . out Vers~ a o com vari a vel debug ativada

Nota: veremos maiores detalhes sobre diretrizes de pr e-processador no Ap endice A Diretrizes de pr e-Processador.

8.9

Introdu c ao ` as estruturas de controle

Nesta se ca o veremos o uso das estruturas de controle for e while.

8.9.1

Usando for

O for e uma estrutura de controle de repeti ca o utilizado para a realiza ca o de la cos (loopings ). O prot otipo a seguir ilustra a forma de uso do for. O primeiro item e a inicializa ca o da vari avel de controle do la co; o segundo, e a condi ca o utilizada para continuar no la co se esta for falsa o la co e encerrado; o terceiro item, a c~ ao1, e utilizado, geralmente, para modicar a vari avel de controle. A a ca o2 e executada repetidas vezes, at e que a condi ca o seja falsa. Prot otipo: for(inicializa ca o; condi ca o; a ca o1) a ca o2; As listagens 8.4 e 8.5 mostram o uso de for. Na listagem 8.4 usamos um bloco for para enviar para tela o valor da vari avel i, criada dentro do for. Dentro do for a vari avel i e inicializada com o valor 1 (int i = 1;). Em seguida, cada la co do for envia para a tela o valor i (std::cout < < i < < " ";). Observe na sa da os valores de i: 1 2 3 4 5 6 7 8 9 10. Ap os cada la co, o valor de i e incrementado, i++, e comparado com o valor 10, i <= 10;. Quando i for igual a 11 a condi ca o se torna falsa, e o for e encerrado. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

AS ` ESTRUTURAS DE CONTROLE 8.9. INTRODUC AO Listing 8.4: Usando for.


# include < iostream > int main () { for ( int i = 1; i <= 10; i ++) std :: cout << i << " " ; std :: cout << std :: endl ; return 0; } 1 2 3 4 5 6 7 8 9 10

207

Na listagem 8.5, usamos um for encadeado, um for dentro de outro para enviar para tela y linhas e x vezes o caracter .. Listing 8.5: Usando for encadeado.
# include < iostream > int main () { int x , y ; std :: cout << " Entre com dois n u meros inteiros positivos ( x espa c o y enter ) : " ; std :: cin >> x >> y ; std :: cin . get () ; for ( int i = 1; i <= y ; i ++) { for ( int j = 1; j <= x ; j = j + 1) std :: cout << . ; std :: cout << std :: endl ; } return 0; } [ b u e n o @ l d s c 0 5 ] $ ./ a . out Entre com dois n u meros inteiros positivos ( x espa c o y enter ) : 4 2 .... .... [ b u e n o @ l d s c 0 5 ] $ ./ a . out Entre com dois n u meros inteiros positivos ( x espa c o y enter ) : 6 3 ...... ...... ......

8.9.2

Usando while e fun c oes da biblioteca de C/C++

O prot otipo a seguir mostra uma estrutura de controle do tipo while. O funcionamento de um bloco while e simples, enquanto a condi ca o for verdadeira a a ca o vai ser executada. Desta forma, em algum momento o bloco que cont em a a ca o a ser executada deve tornar a condi ca o falsa. Note que se a condi ca o nunca for falsa, o bloco com a a ca o nunca vai ser encerrado, ocorrendo um la co innito (sem sa da). Prot otipo: while (condi ca o) {a ca o;}; Veja agora o exemplo da listagem 8.6. Neste exemplo o objetivo e calcular o valor da pot encia dada por potencia = baseexpoente , o usu ario deve entrar com a base e o expoente. A seguir, dentro do bloco while, a pot encia e calculada. Observe que o valor de i inicia em 1 e e Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

208

AOS OPERADORES DE C++ 8.10. INTRODUC AO

incrementado dentro do while, quando i > y o la co e encerrado. O comando cin.get(); e utilizado para retirar do teclado o enter. Observe que o mesmo resultado pode ser obtido usando-se diretamente a fun ca o pow(x,y); da biblioteca padr ao de C. Para usar arquivos da biblioteca matem atica padr ao de C inclu mos o arquivo <cmath>. Listing 8.6: Usando while: Calculando a pot encia.
# include < iostream > // B i b l i o t e c a de e n t r a d a e sa da # include < cmath > // B i b l i o t e c a m a t e m a t i c a de C / C ++ int main () { int x , y ; std :: cout << " Entre com a base ( inteiro ) : " ; std :: cin >> x ; std :: cout << " Entre com o expoente ( inteiro ) : " ; std :: cin >> y ; std :: cin . get () ; int i = 1; double potencia = 1; while ( i <= y ) { potencia = potencia * x ; // O mesmo que p o t e n c i a *= x ; ++ i ; // O mesmo que i = i + 1; } std :: cout << " pot^ e ncia = " << potencia << std :: endl ; // C a l c u l a p o t ^ e n c i a usando fun c~ a o pow (x , y ) std :: cout << " pow (x , y ) = " << pow (x , y ) << std :: endl ; return 0; } [ a n d r e @ m e r c u r i o Cap2 - Sintaxe ] $ ./ a . out Entre com a base ( inteiro ) : 3 Entre com o expoente ( inteiro ) : 4 81

Voc e encontra uma descri ca o detalhada das diversas estruturas de controle de C++ no Ap endice D Estruturas de controle.

8.10

Introdu c ao aos operadores de C++

Veremos nesta se ca o uma breve introdu ca o aos operadores de C++ e um exemplo.

8.10.1

Usando operadores de C++

Neste ponto podemos apresentar um programa que utiliza operadores de C++. Se voc e ainda n ao conhece os operadores de C/C++, ap os a leitura desta se ca o, aconselha-se a leitura do Ap endice C Operadores. Veja a seguir o prot otipo de uso dos operadores relacionais (>, >=, <, <=, ==, !=), os quais s ao utilizados para comparar objetos. Prot otipo Operador Descri ca o Andr e Duarte Bueno

Programa ca o Orientada a Objeto com C++

AOS OPERADORES DE C++ 8.10. INTRODUC AO > >= < <= == != maior maior ou igual menor menor ou igual igual diferente

209

Um exemplo de uso dos operadores de compara ca o e apresentado na listagem C.1. A fun ca o main() cria dois inteiros, a e b. Em seguida, ela pede ao usu ario que entre com os valores de a e b. O programa chama ent ao a fun ca o void compara(int a, int b);, utilizada para comparar os valores a e b, e mostrar na tela o resultado da compara ca o. Veja na sa da que o usu ario entrou com os valores 3 e 4. A fun ca o Compara() n ao retorna nada (void), recebe como par ametros dois inteiros (int x, int y) e e usada para comparar os valores de a e b. Note que os objetos a e b, criados dentro de main(), s ao passados por c opia para a fun ca o Compara(). Veremos as diferentes formas de passagem de par ametros na se ca o 13.6. Listing 8.7: Usando os operadores de compara ca o, incremento, decremento, e os operadores compostos.
# include < iostream > // D e c l a r a fun c~ ao Compara void Compara ( int x , int y ) ; int main () { int a , b ; std :: cout << " Entre com dois numeros inteiros ( a espa c o b enter ) : " ; // O b s e r v e abaixo a l e i t u r a de duas v a r i a v e i s em uma u nica linha . // Isto pode ser feito , mas deve ser e v i t a d o. std :: cin >> a >> b ; std :: cin . get () ; // Pega o enter Compara (a , b ) ; // E x e c u t a fun c~ a o C o m p a r a () a += 5; // O p e r a d o r c o m p o s t o . Compara (a , b ) ; // E x e c u t a fun c~ a o C o m p a r a () b - -; // O p e r a d o r de d e c r e m e n t o . Compara (a , b ) ; // E x e c u t a fun c~ a o C o m p a r a () a *= ++ b ; // O p e r a d o r de i n c r e m e n t o . Compara (a , b ) ; // E x e c u t a fun c~ a o C o m p a r a () return 0; // E n c e r r a o p r o g r a m a } // Define a fun c~ a o C o m p a r a ( c o digo da fun c~ ao ) void Compara ( int x , int y ) { if ( x == y ) // O p e r a d o r e s de c o m p a r a c~ ao std :: cout << x << " == " << y << " \ t " ; if ( x != y ) std :: cout << x << " != " << y << " \ t " ; if ( x < y ) std :: cout << x << " < " << y << " \ t " ; if ( x > y ) std :: cout << x << " > " << y << " \ t " ; if ( x <= y ) std :: cout << x << " <= " << y << " \ t " ; if ( x >= y )

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

210
std :: cout << x << " >= " << y << " \ t " ; }

AS FUNC 8.11. INTRODUC AO OES

Entre com dois numeros inteiros ( a espa c o b enter ) : 3 4 3 != 4 3 < 4 3 <= 4 8 != 4 8 > 4 8 >= 4 8 != 3 8 > 3 8 >= 3 32 != 4 32 > 4 32 >= 4

Neste exemplo adicionamos, al em do uso de operadores, o uso de fun co es separadas de main(), o que e t pico em programas estruturados. Nota: como os conceitos de operadores (+, -, *, ...) e de estruturas de controle j a s ao bastante conhecidos, eles foram inclu dos no Ap endice C Operadores e no Ap endice D Estruturas de controle. Continue lendo o livro normalmente. Se tiver problemas para entender como funciona determinado operador ou estrutura de controle, consulte o item espec co no ap endice. Nota: veremos o uso de m etodos no Cap tulo 13 M etodos e no Cap tulo 14 Sobrecarga de m etodos.

8.11

Introdu c ao as fun c oes

Vimos os conceitos de fun co es e m etodos na se ca o 3.5. Lembre-se que fun co es no estilo de C, s ao normalmente fun co es globais, utilizadas em programa ca o estruturada. A id eia de usar fun co es e possibilitar que partes do c odigo que s ao constantemente repetidas sejam separadas do uxo principal. J a vimos na se ca o 8.6 a fun ca o main(). Veremos aqui o prot otipo e exemplos de declara ca o, deni ca o e uso de fun co es no estilo de C. Veja no prot otipo a seguir que uma fun ca o tem um retorno, um nome e uma lista de par ametros. Prot otipo: retorno NomeDaFun ca o(par ametros); Normalmente as fun co es s ao declaradas antes da fun ca o main(), e denidas depois de main(). Isto possibilita que as fun co es possam ser chamadas de dentro de main(). Veja a seguir algumas listagens com exemplos de fun co es. Veja na listagem 8.8 uma fun ca o simples, usada para calcular o cubo de um n umero. Observe que que a fun ca o cubo() e chamada diversas vezes dentro do for. Listing 8.8: Fun ca o cubo.
# include < iostream > int cubo ( int y ) ; int main () { // D e c l a r a c~ a o da fun c~ ao

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

AS FUNC 8.11. INTRODUC AO OES


int min , max ; std :: cout << " Entre com o intervalo ( valor m nimo e m a ximo ) ( ex : 3 e 10) : " ; std :: cin >> min >> max ; std :: cin . get () ; for ( int x = min ; x <= max ; x ++) std :: cout << " cubo de ( " << x << " ) = " << cubo ( x ) << std :: endl ; return 0; } // D e f i n i c~ a o da fun c~ ao : // r e t o r n o _ d a _ f u n c~ ao Nome_da_fun c~ ao ( par^ ametros) { corpo_da_fun c~ ao} int cubo ( int y ) { return y * y * y ; } Entre com o intervalo ( valor minimo e m a ximo ) ( ex : 3 e 10) :5 7 cubo de (5) =125 cubo de (6) =216 cubo de (7) =343

211

Veja na listagem 8.9 uma fun ca o simples, sem retorno e sem par ametros. Observe que usamos recurs ao para fun ca o main(). Uma recurs ao existe quando uma fun ca o chama a s mesma. Veremos o uso de recurs oes na se ca o E.3. Listing 8.9: Fun ca o com void.
# include < iostream > void f () ; void g ( void ) ; // C ++ // C p r e c i s a do s e g u n d o void

int main () { std :: cout << " \ a \ n " ; std :: cout << " Executar f () ou g () ? " ; char resp = f ; std :: cin >> resp ; std :: cin . get () ; // Pega o enter if ( resp == f || resp == F ) f () ; else if ( resp == g || resp == G ) g () ; else { std :: cout << " Sele ca ~ o errada , selecionou ( " << resp << " ) " << std :: endl ; main () ; // R e c u r s ~ ao } return 0; } void f () { std :: cout << " Fun ca ~ o void n~ a o retorna nada ( selecionou f ) " << std :: endl ; } void g ( void ) { std :: cout << " Fun ca ~ o void n~ a o retorna nada ( selecionou g ) " << std :: endl ; } Executar f () ou g () ? g Fun ca ~ o void n~ a o retorna nada ( selecionou g )

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

212

AS FUNC 8.11. INTRODUC AO OES

[ andre@mercurio Executar f () ou Sele ca ~ o errada , Executar f () ou Fun ca ~ o void n~ ao

Parte - VI ] $ ./ a . out g () ?6 seleciono u (6) g () ? f retorna nada ( selecionou f )

Apresenta-se na listagem 8.10 uma fun ca o em linha, utilizada para calcular o volume de uma esfera. Veremos em detalhes os conceitos de fun co es em linha na se ca o 13.10. Uma vari avel declarada com const e uma vari avel que n ao pode ser alterada. Veremos em detalhes o uso de const na se ca o 12.4. Listing 8.10: Fun ca o em linha: volume esfera.
# include < iostream > // V a r i a v e i s g l o b a i s devem ser d e c l a r a d a s com m a i usculas // const indica ser constante , n~ a o muda const double PI = 3.14159; /* Um p r o g r a m a d o r C usaria # define PI 3 . 1 4 1 5 9 */ // Fun c~ a o em linha inline double V o l u m e E s f e r a ( const double raio ) { return 4.0 / 3.0 * PI * raio * raio * raio ; } /* Um p r o g r a m a d o r C usaria uma macro , sem n e n h u m a v e r i f i c a c~ a o de tipo . # define V o l u m e E s f e r a ( raio ) ( 4 . 0 / 3 . 0 * PI * raio * raio * raio ) */ int main () { double raio ; std :: cout << " Entre com o raio : " ; std :: cin >> raio ; std :: cin . get () ; std :: cout << " Raio r = " << raio << " volume V = " << V o l u m e E s f e r a ( raio ) << std :: endl ; return 0; } Entre com o raio : 5 Raio r =5 volume V = 523.598

Veja na listagem 8.11 uma fun ca o utilizada para gerar n umeros rand omicos num determinado intervalo de valores. Listing 8.11: Exemplo de uso da biblioteca <cstdlib>.
# include < iostream > # include < iomanip > // A b i b l i o t e c a abaixo , no C chama stdlib .h , no C ++ chama c s t d l i b // a mesma f o r n e c e a fun c~ a o srand - s e m e n t e para g e r a d o r // e rand - gera n u mero r a n d o m i c o . # include < cstdlib > int main () {

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

8.12. DECLARAC OES E ESCOPO


int semente ; std :: cout << " Entre com uma semente : " ; std :: cin >> semente ; std :: cin . get () ; int min ; std :: cout << " Entre com o valor m nimo ( a ) : " ; std :: cin >> min ; std :: cin . get () ; int max ; std :: cout << " Entre com o valor m a ximo ( b ) : " ; std :: cin >> max ; std :: cin . get () ; // Passa a s e m e n t e para o g e r a d o r de n umeros aleat orios srand ( semente ) ; for ( int i = 1; i <= 50; i ++) // Chama 50 vezes a fun c~ a o rand { std :: cout << std :: setw (10) << ( min + ( rand () % ( max - min + 1) ) ) ; if ( i % 5 == 0) std :: cout << std :: endl ; } return 0; } Entre com uma semente : 4 Entre com o valor m nimo ( a ) : 1 Entre com o valor m a ximo ( b ) : 10 2 4 5 7 8 6 4 9 5 5 5 5 5 3 2 2 8 5 9 10 9 3 3 1 1 4 5 7 10 5 5 4 2 10 7 6 2 3 9 3

213

4 6 4 10 4 1 10 3 5 4

Nota: veremos o uso de elipse ... em fun co es na se ca o E.4.

8.12

Declara c oes e escopo

Um escopo e uma regi ao de c odigo que cont em declara co es. Cada declara ca o adiciona um nome ao escopo, e o uso desses nomes deve ser resolvido pelo compilador. Isto signica que n ao podemos ter dois nomes iguais no mesmo escopo pois o compilador caria confuso e acusaria uma ambig uidade. No exemplo a seguir int y; e declarado duas vezes, o que causa uma ambig uidade. Exemplo: int main() { int x; int y; int y; return 0; }

// // // //

In cio do escopo de main(), do bloco de main() Declara um inteiro x Declara um inteiro y Erro, mesmo nome no mesmo escopo (ambiguidade)

// Fim do escopo de main(), do bloco de main() Andr e Duarte Bueno

Programa ca o Orientada a Objeto com C++

214

8.13. SENTENCAS PARA CONCEITOS BASICOS DE C++

No exemplo a seguir criamos, dentro do bloco de main(), um bloco interno. Observe que temos duas vari aveis y: a primeira y = 3; e a segunda y = 4;. Note que, quando um bloco interno e fechado, os objetos criados dentro do bloco s ao destru dos automaticamente. Exemplo: int main() { // In cio do escopo de main() int x; int y = 3; std::cout < < "y = " < < y ; // Sa da: y = 3 { // Bloco interno, define novo escopo int y = 4; std::cout < < "y = " < < y ; // Sa da: y = 4 } // y = 4 sai de escopo e e destru do automaticamente std::cout < < "y = " < < y ; // Sa da: y = 3 return 0; } // Fim do escopo de main() Veremos mais detalhes sobre escopo ao longo deste livro e na se ca o B.4.

8.13

Senten cas para conceitos b asicos de C++

Sempre deixe uma linha em branco antes de uma declara ca o. Isto deixa o c odigo mais claro. Um objeto s o pode ser utilizado depois de ter sido declarado. Sempre que poss vel, inicie os objetos na sua declara ca o. Quando uma express ao for complexa, coloque par enteses extras para facilitar o entendimento do c odigo. Sempre use espa cos para maior claridade. Sempre use indenta ca o para deixar o c odigo organizado (voc e pode usar o programa indent. Veja se ca o ??). Use nomes curtos para objetos muito usados e nomes longos para objetos e m etodos pouco usados. Utilize um padr ao para o nome dos objetos (veja se ca o 8.3). No C temos de declarar todas as vari aveis no in cio do programa; no C++ podemos declarar os objetos em qualquer parte. O ideal e declarar os objetos perto de onde ser ao utilizados. Sempre declare um objeto por linha. Exemplo: // Cria int* a; e int b; int *a, b; // Declarar um objeto por linha deixa o programa mais claro int* a; int b; Objetos est aticos s ao inicializados com 0. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

8.14. RESUMO DO CAP ITULO

215

Objetos locais, criados dentro de um bloco (ou fun ca o), n ao s ao inicializados. Voc e precisa passar-lhes um valor. Nem todos os compiladores aceitam o uso de caracteres universais. A linguagem C/C++ reservou para uso futuro os seguintes prexos: is (exemplo: isblank()), mem (exemplo: memf()), str (exemplo: strtof()), to (exemplo: toascii()), wcs (exemplo: wcstof()). Utilize a palavra-chave export para informar que aquele objeto/classe/m etodo e acess vel externamente. Note que podemos montar a sa da que aparecer a na tela do computador usando o objeto std::cout e o operador de inser ca o < <. Podemos ir redirecionando caracteres e vari aveis do programa para tela do computador. Por exemplo, na linha std::cout < < "Mensagem1 " < < "Mensagem2 " < < "Mensagem3 "; enviamos para tela o texto "Mensagem1 Mensagem2 Mensagem3 ". 2 Objetos podem ser modicados com as palavras-chave const (constante, n ao muda), volatile (podem mudar de forma inesperada) e static (duram toda a execu ca o do programa). Veja se ca o B.3. 2 Voc e n ao deve confundir a classe de armazenamento com o escopo do objeto. A classe de armazenamento se refere ao tempo de vida do objeto (tempor ario ou permanente), j a o escopo do objeto dene onde ele pode ser utilizado (onde e vis vel). Veja uma descri ca o dos conceitos de classes de armazenamento na se ca o B.1, dos modicadores de acesso na se ca o B.3 e do escopo das vari aveis na se ca o B.4 do Ap endice B. 2 Segundo [Lischner, 2003], uma express ao integral constante deve ter seu valor denido na compila ca o. As situa co es em que isto e necess ario incluem: tamanho de um array, inicializa ca o dos valores de uma enumera ca o, r otulos de instru co es case:, inicializa ca o de membros est aticos e argumentos de templates.

8.14

Resumo do cap tulo

Neste cap tulo vimos alguns conceitos b asicos de C++, como os coment arios, s mbolos, especicador, lvalues. Aprendemos o que s ao os identicadores, os operadores e os literais. Vimos um grupo de palavras-chaves reservadas pelo C++, as palavras-chave de C++. Aprendemos que o nome dos objetos deve ser simples e claro. Aprendemos ainda a forma como declaramos e denimos os objetos, e as diferen cas da declara ca o (informa que o objeto existe) para deni ca o (reserva espa co na mem oria para o objeto). Vimos uma introdu ca o a diversos conceitos b asicos de C++, como fun ca o main(), uso de cin e cout, as diretrizes de pr e-processador (#ifdef..#endif), algumas estruturas de controle (for, while), fun co es da biblioteca-padr ao (pow(x,y)), alguns operadores, e uma introdu ca o ao conceito de fun co es. Finalmente, vimos a rela ca o entre declara co es e escopo. Nota: ao longo do livro veremos outros exemplos e listagens que esclarecem temas como escopo, cria ca o, destrui ca o e tempo de vida dos objetos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

216

8.15. EXERC ICIOS

8.15

Exerc cios

1. Qual a diferen ca b asica entre uma declara ca o e uma deni ca o? 2. Fa ca uma lista das palavras-chave que voc e j a memorizou. 3. Quais s ao os tipos padr oes de C++ que voc e j a conhece? 4. Modique a listagem 8.1 usando os caracteres apresentados na Tabela 22.3. 5. Modique a listagem 8.2 criando e usando novas vari aveis. Incluir outras opera co es como multiplica ca o e divis ao. 6. Modique a listagem 8.3, incluindo novas diretrizes de pr e-processador (veja Ap endice A Diretrizes de pr e-processador). 7. Modique as listagens 8.4, 8.5 e 8.6 fazendo com que elas fa cam algo mais u til. 8. Rode agora o programa da se ca o 7.8. Voc e j a conseguiria modic a-lo? Comece adicionando coisas novas dentro do m etodo Run(). 9. Um programa pode ser encerrado a qualquer momento chamando-se a fun ca o exit();, a qual encerra o programa destruindo os objetos criados, ou chamando abort();, que encerra o programa sem destruir os objetos criados. Monte um programa que use exit(); e outro que use abort();. Nota: se voc e n ao est a familiarizado com o uso de algoritmos, consulte as refer encias [Holloway, 2006] (algoritmos em C++) e [Cormen et al., 2002, Boente, 2006].

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 9

Tipos
Neste cap tulo veremos uma introdu ca o ao conceito de tipos: o que e um tipo (Se ca o 9.1) e quais os tipos predenidos de C++ (Se ca o 9.2). A deni ca o de tipos do usu ario (Se ca o 9.3), como vetores no estilo de C (Se ca o 9.3.1), como estruturas (Se ca o 9.3.2), uni oes (Se ca o 9.3.3), enumera co es (Se ca o 9.3.4), e classes (Se ca o 9.3.5). Os tipos denidos em bibliotecas externas (Se ca o 9.4), como a classe <string> (Se ca o 9.4.1) e a classe <vector> da STL (Se ca o 9.4.2). Como manipular os tipos de C++ (Se ca o 9.5), como criar apelidos com typedef (Se ca o 9.5.1), o uso de size_t() (Se ca o 9.5.2) e sizeof() para obter o tamanho dos objetos (Se ca o 9.5.3), e o uso de typeid() para vericar o tipo do objeto (Se ca o 9.5.4). Veremos tamb em a vantagem da tipica ca o forte do C++ (Se ca o 9.6). Nota: neste cap tulo apresentaremos v arios tipos de objetos que s ao utilizados em um programa um cap em C++. E tulo extenso, com muitas informa co es, n ao se preocupe se n ao entender tudo em uma primeira leitura. Ao longo dos pr oximos cap tulos estes conceitos ser ao reapresentados de forma mais detalhada.

9.1

Introdu c ao ao conceito de tipos

Um tipo e uma abstra ca o de algo (Se ca o 3.1). Para a linguagem C++ os tipos podem ser classicados em tr es grupos: Tipos predenidos da linguagem, como bool, char, int, double (Se ca o 9.2). Tipos denidos pelo programador (Se ca o 9.3). Tipos denidos em bibliotecas externas, como a STL (Se ca o 9.4).

9.2

Uso de tipos predenidos de C++

Os tipos num ericos predenidos da linguagem C++ s ao bool, char, int, float e double.

O tipo bool e utilizado para armazenar valores booleanos 0 (false/falso) ou 1 (true/verdadeiro), sendo utilizado como ag, por exemplo, em estruturas de controle. char e utilizado para armazenar caracteres ou n umeros inteiros pequenos. int e usado para armazenar n umeros inteiros, com ou sem sinal (unsigned). J a float e double s ao utilizados para armazenar n umeros utuantes (n umeros racionais). 217

218

9.2. USO DE TIPOS PREDEFINIDOS DE C++

No n umero 7.48e9, 7.48 e a mantissa, e 9 o expoente. O ponto e o separador da parte fracion aria (quando utiliza-se o locale C. Veja Se ca o 22.9.2. O caracter e ou E indica nota ca o exponencial. Se o resultado de uma determinada conta for innito (um n umero maior que a precis ao suportada), a sa da ser a Inf ou Innity. Se o resultado for um valor indeterminado (como em 0/0) a sa da ser a NaN ou Not a Number. CUIDADO: A divis ao de dois n umeros inteiros retorna um n umero inteiro, assim, 4 / 3 = 1. A divis ao de um n umero inteiro por um n umero utuante retorna um n umero utuante. Uma representa ca o do consumo de mem oria em bytes dos diferentes tipos e apresentada na Figura 9.1. Observe que um double consome o dobro de mem oria de um float. A escolha por float ou double depender a do uso: se voc e precisa de mais precis ao use double; se quer economizar mem oria use float. Os intervalos de valores suportados pelos tipos predenidos est ao listados na Tabela 9.1. Observe que char pode ser utilizado como uma letra ou como um n umero com intervalo entre -128 e +127. De fato, char e utilizado como n umero em alguns programas de processamento de imagens. Um n umero inteiro short int, vai de -32768 at e 32767. Isto signica que a conta realizada com um short int n ao poder a ultrapassar esses valores. Se precisar de n umeros inteiros grandes, use int, long int, ou long long.
1 1 1 1 1 1 2 3 4 5 2 6 3 7 4 8 5 2 2 6 3 3 7 2 4 4 8 bool, char, unsigned char short int, unsigned short int, unsigned int, long, unsigned long, int* float long long, double

9 10 11 12 long double

Figura 9.1: Tipos predenidos de C++ e suas dimens oes (32 bits). Vimos exemplos de como criar e utilizar um objeto com base em um tipo predenido de C++, nas listagens 8.2, 8.4, 8.5, 8.6 e C.1. Veremos na Se ca o 9.5.3 que o n umero de bytes consumido por um n umero inteiro varia de acordo com a plataforma. Veja na Listagem 9.1 um programa que utiliza os tipos predenidos de C++. Observe que este exemplo n ao tem nem entrada nem sa da de dados, n ao sendo necess aria a inclus ao de arquivos externos. Listing 9.1: Usando os tipos pr e-denidos de C++.
1 2 3 4 5 6 int main () { // Tipos pr e - d e f i n i d o s da l i n g u a g e m C ++ // Tipo booleano , i n t e r v a l o 0 ou 1 (1 byte ) bool flag = 0;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

9.2. USO DE TIPOS PREDEFINIDOS DE C++

219

Tabela 9.1: Tipos predenidos e intervalos.


Tipos b asicos bool char wchar_t unsigned char short unsigned short int unsigned int long unsigned long long long float double long double enum Caracter sticas booleano caracteres caracteres caracteres sem sinal inteiro inteiro pequeno, sem sinal inteiro inteiro sem sinal inteiro grande inteiro grande com sinal inteiro muito grande precis ao simples, 7 d gitos precis ao dupla, 15 d gitos precis ao dupla, 19 d gitos enumerados bytes 1 1 2 1 2 2 4 4 4 4 8 4 8 12 2 Valor m nimo 0 -128 0 0 -32768 0 -2.147.483.648 0 -2.147.483.648 0 -9.223.372.036 .854 .775.808 1.17e-38 1.7e-308 3.4e-4932 -2.147.483.648 Valor m aximo 1 127 65535 255 32767 65535 +2.147.483.647 +4.294.967.295 +2.147.483.647 +4.294.967.295 +9.223.372.036 .854.775.807 3.40e+38 1.7e+308 1.1e+4932 +2.147.483.648

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

// Tipo char , i n t e r v a l o -128 a +127 (1 byte ) char ch = b ; char nch = 14; // Tipo int , i n t e r v a l o int int_x = 777; -2147483648 a + 2 1 4 7 4 8 3 6 4 7 (4 bytes , 32 bits )

// Tipo float , i n t e r v a l o +/ - 3.4. e +/ -38 (7 d g i t o s de p r e c i s ~ a o ) (4 bytes ) float float_y = 3.212 f ; // Tipo double , i n t e r v a l o +/ - 1.7 e +/ -308 (15 d g i t o s de p r e c i s ~ a o ) (8 bytes ) double double_z = 7.48 e9 ; // Tipo long double , i n t e r v a l o +/ - 3.4 e +/ -4932 // (19 d g i t o s de p r e c i s ~ a o) (12 bytes ) long double l o n g _ d o u b l e _ r = 1.2 e -18; return 0; }

Observe no exemplo da Listagem 9.2 o uso e as diferen cas dos tipos int (inteiro) e unsigned int (inteiro sem sinal). Observe que quando usamos int a opera ca o x - y e v alida pois int aceita n umeros negativos. J a quando usamos unsigned int, z s o pode armazenar n umeros inteiros positivos, n ao podendo armazenar o resultado de x - y quando y > x. Observe na sa da gerada pelo compilador a mensagem de warning por estarmos armazenando um inteiro negativo em um inteiro sem sinal (unsigned int t = -1;). Observe na sa da que quando usamos int temos x = 300 e y = 500, e z = x - y apresenta o valor correto -200. Quando usamos unsigned int, aparece um valor absurdo, 4294967096, no lugar de -200. Como dito, isto ocorre porque z s o pode armazenar n umeros inteiros positivos. Vamos explicar este problema com um exemplo. Observe na Tabela 9.1 que um n umero unsigned int, vai de 0 at e +4.294.967.295, se criarmos um n umero t usando unsigned int t = 4.294.967.295; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

220 Quando fazemos t = t + 1;

9.2. USO DE TIPOS PREDEFINIDOS DE C++

o valor de t e incrementado do valor 1 e ultrapassa o limite denido. Como os n umeros s ao tratados de maneira c clica, o novo valor de t passa a ser 0 (zero). O mesmo problema ocorre quando ultrapassamos o limite inferior, isto e, se t = 0; o c odigo t = t -1; faz com que t assuma o valor +4.294.967.295. Listing 9.2: Diferen cas no uso de inteiro com sinal (signed) e sem sinal (unsigned).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 # include < iostream > int main () { { std :: cout << " - - - - - - - - - - > Testando a utiliza ca ~ o de int " << std :: endl ; int x , y , z ; std :: cout << " Entre com int x ( ex : 300) : " ; std :: cin >> x ; std :: cout << " Entre com int y ( ex : 500) : " ; std :: cin >> y ; std :: cin . get () ; z = x + y; std :: cout << " int z = x + y = " << z << std :: endl ; z = x - y; std :: cout << " int z = x - y = " << z << std :: endl ; } std :: cout << " - - - - - - - - - - > Testando a utiliza ca ~ o de unsigned int " << std :: endl ; unsigned int x , y , z ; std :: cout << " Entre com unsigned int x ( ex : 300) : " ; std :: cin >> x ; std :: cout << " Entre com unsigned int y ( ex : 500) : " ; std :: cin >> y ; std :: cin . get () ; z = x + y; std :: cout << " unsigned int z = x + y = " << z << std :: endl ; z = x - y; std :: cout << " unsigned int z = x - y = " << z << std :: endl ; // Se x if ( x > z = x else z = y > y r e t o r n a z = x - y , caso c o n t r a r i o ( else ) r e t o r n a z = y - x y) - y; - x;

// A r m a z e n a a i n f o r m a c~ a o do sinal , o b s e r v e que sinal e do tipo int . int sinal ; if ( x > y ) sinal = +1; else sinal = -1; // Cria objeto int para a r m a z e n a r o r e s u l t a d o int r e s u l t a d o _ c o r r e t o = sinal * z ; std :: cout << " z = | x - y | = " << z << std :: endl ; std :: cout << " sinal de x - y = " << sinal << std :: endl ; std :: cout << " int r e s u l t a d o _ c o r r e t o = sinal * z = " << r e s u l t a d o _ c o r r e t o << std :: endl ; unsigned int t = -1; std :: cout << " unsigned int t = -1 --> t = " << t << std :: endl ; return 0; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

9.2. USO DE TIPOS PREDEFINIDOS DE C++


Compila ca ~o : ========= == bash -3.00 $ g ++ signed - unsigned . cpp signed - unsigned . cpp : In function int main () : signed - unsigned . cpp :49: warning : converting negative value -0 x000000001 to unsigned int b [ a n d r e @ m e r c u r i o lyx ] $ ./ a . out - - - - - - - - - - > Testando uso de int Entre com int x ( ex : 300) :300 Entre com int y ( ex : 500) :500 int z = x + y =800 int z = x - y = -200 - - - - - - - - - - > Testando uso de unsigned int Entre com unsigned int x ( ex : 300) :300 Entre com unsigned int y ( ex : 500) :500 unsigned int z = x + y = 800 unsigned int z = x - y = 4294967096 z =| x - y |=200 sinal de x - y = -1 int r e s u l t a d o _ c o r r e t o = sinal * z = - 200 unsigned int t = -1 --> t = 4294967295

221

9.2.1

Uso de suxos para os tipos predenidos2

Quando digitamos um literal, Exemplo: int x = 7; // 7 e um literal

o mesmo representa que tipo de n umero inteiro? e um short? um int? um long int? ou um long long int? Por padr ao, 7 e um int. Podemos denir de forma exata o tipo do literal usando suxos. Veja lista de suxos e exemplo de uso a seguir: I,L u,U long unsigned

ul,uL,UL unsigned long uLL,Ull f unsigned long long float

Por exemplo: O n umero 7.45 e um double, 7.45f e um float, e 7.45L e long double. O n umero 7L e um long int, 7uL e um unsigned long int. O n umero 7LL e um long long int. O n umero que inicia com 0x e um n umero hexadecimal. O n umero que inicia com 0 (zero) e um n umero octal. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

222

9.2. USO DE TIPOS PREDEFINIDOS DE C++

9.2.2

Uso avan cado dos tipos predenidos2

Veja na Listagem 9.3 um programa que mostra informa co es sobre os tipos predenidos de C++. Como este exemplo utiliza conceitos avan cados de C++, como o uso de templates e bibliotecas padr oes de C++, n ao se preocupe se n ao entender seu funcionamento nesta primeira leitura. O arquivo de cabe calho <limits> inclui a classe template <numeric_limits>, a qual inclui atributos e m etodos que fornecem informa co es sobre os tipos predenidos. Por exemplo, a chamada a numeric_limits<Tipo>::is_integer() retorna verdadeiro se o Tipo for char, short, int, unsigned int. Neste exemplo, a fun ca o Info() recebe o tipo de objeto e uma string com seu nome. Em seguida, envia para a tela informa co es b asicas sobre o tipo como: e inteiro?; valores m aximos e m nimos suportados; expoentes m nimos e m aximos; valor innito e dados como radix, epsilon, round_error e round_style. Listing 9.3: Vericando os limites dos tipos pr e-denidos de C++.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 # include < iostream > # include < string > # include < limits > using namespace std ; // Fun c~ a o t e m p l a t e u t i l i z a d a para i n f o r m a r dados sobre o n u mero . // Recebe dois par^ a metros , p r i m e i r o o n u mero n , s e g u n d o o nome s template < typename Tipo > void Info ( Tipo n , string s ) { cout << " \n - - - > Informa co ~ e s sobre n u meros " << s << " <--- " ; s = " \ nnumeric_limit s < " + s + " >:: " ; cout << s << " is_integer = " << numeric_limits < Tipo >:: is_integer << s << " max () = " << numeric_limits < Tipo >:: max () << s << " min () = " << numeric_limits < Tipo >:: min () << s << " m i n _ e x p o n e n t = " << numeric_limits < Tipo >:: m i n _ e x p o n e n t << s << " m i n _ e x p o n e n t 1 0 = " << numeric_limits < Tipo >:: m i n _ e x p o n e n t 1 0 << s << " m a x _ e x p o n e n t = " << numeric_limits < Tipo >:: m a x _ e x p o n e n t << s << " m a x _ e x p o n e n t 1 0 = " << numeric_limits < Tipo >:: m a x _ e x p o n e n t 1 0 << s << " digits = " << numeric_limits < Tipo >:: digits << s << " digits10 = " << numeric_limits < Tipo >:: digits10 << s << " radix = " << numeric_limits < Tipo >:: radix << s << " infinity () = " << numeric_limits < Tipo >:: infinity () << s << " epsilon () = " << numeric_limits < Tipo >:: epsilon () << s << " round_err or () = " << numeric_limits < Tipo >:: round_err or () << s << " round_sty le = " << numeric_limits < Tipo >:: round_sty le << endl ; } int main () { char c ; int i ; long l ; long long ll ; float f ; double d ; long double ld ; Info (c , " char " ) ; Info (i , " int " ) ; Info (l , " long " ) ; Info ( ll , " long long " ) ; Info (f , " float " ) ; Info (d , " double " ) ; Info ( ld , " long double " ) ; return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ linux64 ./ a . out

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

9.2. USO DE TIPOS PREDEFINIDOS DE C++


---> Informa co ~ e s sobre n u meros char < - - numeric_limits < char >:: is_integer = 1 numeric_limits < char >:: digits = 7 ... ---> Informa co ~ e s sobre n u meros int < - - numeric_limits < int >:: is_integer = 1 numeric_limits < int >:: max () = 2147483647 numeric_limits < int >:: min () = -2147483648 numeric_limits < int >:: digits = 31 ... ---> Informa co ~ e s sobre n u meros long < - - numeric_limits < long >:: is_integer = 1 numeric_limits < long >:: max () = 9 2 2 3 3 7 2 0 3 6 8 5 4 7 7 5 8 0 7 numeric_limits < long >:: min () = -922337203 6 85 4 77 5 80 8 numeric_limits < long >:: digits = 63 ... ---> Informa co ~ e s sobre n u meros long long < - - numeric_limits < long long >:: is_integer = 1 numeric_limits < long long >:: max () = 9 2 2 3 3 7 2 0 3 6 8 5 4 7 7 5 8 0 7 numeric_limits < long long >:: min () = -9223372036 8 54 7 7 58 0 8 numeric_limits < long long >:: digits = 63 ... ---> Informa co ~ e s sobre n u meros float < - - numeric_limits < float >:: is_integer = 0 numeric_limits < float >:: max () = 3.40282 e +38 numeric_limits < float >:: min () = 1.17549 e -38 numeric_limits < float >:: m i n _ e x p o n e n t = -125 numeric_limits < float >:: m i n _ e x p o n e n t 1 0 = -37 numeric_limits < float >:: m a x _ e x p o n e n t = 128 numeric_limits < float >:: m a x _ e x p o n e n t 1 0 = 38 numeric_limits < float >:: digits = 24 numeric_limits < float >:: infinity () = inf ... ---> Informa co ~ e s sobre n u meros double < - - numeric_limits < double >:: is_integer = 0 numeric_limits < double >:: max () = 1.79769 e +308 numeric_limits < double >:: min () = 2.22507 e -308 numeric_limits < double >:: m i n _ e x p o n e n t = -1021 numeric_limits < double >:: m i n _ e x p o n e n t 1 0 = -307 numeric_limits < double >:: m a x _ e x p o n e n t = 1024 numeric_limits < double >:: m a x _ e x p o n e n t 1 0 = 308 numeric_limits < double >:: digits = 53 numeric_limits < double >:: digits10 = 15 numeric_limits < double >:: infinity () = inf ... ---> Informa co ~ e s sobre n u meros long double < - - numeric_limits < long double >:: is_integer = 0 numeric_limits < long double >:: max () = 1.18973 e +4932 numeric_limits < long double >:: min () = 3.3621 e -4932 numeric_limits < long double >:: m i n _ e x p o n e n t = -16381 numeric_limits < long double >:: m i n _ e x p o n e n t 1 0 = -4931 numeric_limits < long double >:: m a x _ e x p o n e n t = 16384 numeric_limits < long double >:: m a x _ e x p o n e n t 1 0 = 4932 numeric_limits < long double >:: digits = 64 numeric_limits < long double >:: digits10 = 18 numeric_limits < long double >:: infinity () = inf ...

223

Nota: veja no manual do seu ambiente de desenvolvimento onde est ao armazenados os arquivos da biblioteca de C++. No GNU/Linux est ao em /usr/include/c++/vers aoDoCompilador. D e uma olhada no arquivo de biblioteca <limits> (exemplo: /usr/include/c++/4.1.1/limits). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

224

9.2. USO DE TIPOS PREDEFINIDOS DE C++ Esse arquivo cont em vari aveis que denem os limites para os tipos predenidos da linguagem.

9.2.3

Senten cas para uso de tipos predenidos

Os tipos inteiros (char, short, int, long) e os tipos utuantes (float, double, long double) tamb em s ao conhecidos como tipos aritm eticos. Um tipo aritm etico pode ser automaticamente convertido para outro. Por default, um tipo menor e convertido em um tipo maior (exemplo: int e convertido para float). A id eia e que os valores sejam preservados. Cuidado especial deve ser tomado quando convertemos um tipo com sinal negativo para um tipo sem sinal (veja Listagem 9.2). Um tipo utuante, quando convertido para int, e truncado (exemplo: int y = 4.33; // y = 4). Utilize unsigned char quando precisar trabalhar com n umeros entre 0 e 255. Utilize signed char quando precisar trabalhar com n umeros entre -128 e 127. A palavra-chave const e usada para indicar que o conte udo do objeto n ao muda. No exemplo a seguir o valor de y ser a sempre 5. Exemplo: const int y = 5; // Cria objeto constante do tipo inteiro Por default, o n umero 5.3 e um double; j a 5.3f e um n umero float. Podemos atribuir a um bool um valor diferente de 0 e 1. Neste caso, todo valor diferente de zero assume o valor 1 (true/verdadeiro). Um caracter e representado dentro de aspas simples, como na sequ encia: a, \b, \u03co. O caracter a e uma letra simples. O caracter \b e um caracter de escape (veja Tabela 22.3). J a \u03co e um caracter universal. Uma string de C (cstring) e representada dentro de aspas duplas, como em: "oi tudo bem!" observe que podemos quebrar a string utilizando uma barra invertida, "oi tudo \ bem" concatenar strings, "oi" " tudo" " bem" ou incluir caracteres de escape "oi\t tudo\t bem\a". Um espa co , uma tabula ca o horizontal \t, uma tabula ca o vertical \v, um avan co de formul ario \fe um caracter de nova linha \n s ao conhecidos e tratados como whitespace caracters. 2 Uma wide string tamb em e representada dentro de aspas duplas, mas a string e antecedida da letra L como em: L"oi tudo bem!". Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

9.3. USO DE TIPOS DO USUARIO

225

9.3

Uso de tipos do usu ario

Veja nesta se ca o exemplos preliminares de deni ca o e uso de tipos do usu ario. Veremos como criar tipos do usu ario utilizando vetores (Se ca o 9.3.1), estruturas (Se ca o 9.3.2), uni oes (Se ca o 9.3.3), enumera co es (Se ca o 9.3.4) e classes (Se ca o 9.3.5).

9.3.1

Introdu c ao aos vetores no estilo de C

Em C/C++, podemos criar um vetor usando o tipo do objeto a ser armazenado no vetor, o nome do vetor e o n umero de elementos do vetor que e colocado dentro de []. Veja a seguir o prot otipo para criar e usar um vetor no estilo de C. Prot otipo: // Para criar um vetor em C Tipo NomeVetor [dimens ao]; Tipo NomeVetor []= {lista de elementos}; // Para acessar um elemento do vetor NomeVetor[posi ca o]; O exemplo a seguir ilustra a cria ca o e o uso de um vetor de n umeros inteiros. Observe que denimos explicitamente o tamanho de v1, com a dimens ao 5. O tamanho de v2 e calculado pelo compilador, em tempo de compila ca o. Usamos um for para calcular a soma dos elementos de v1 e v2 e armazenar em v3. Exemplo: int v1[5]; for( int i = 0; v[i] = i; int v2[] = { 3, int v3[5]; for( int i = 0; v3[i] = v1[i]

// Cria vetor v1 i < 5 ; ++i ) // Inicializa valores de v1 4, 7, 9, 1 }; // Cria vetor v2 e j a inicializa // Cria vetor v3 i < 5 ; ++i ) + v2[i];

Dica: em C e C++ os vetores iniciam com o ndice 0 e n ao com 1. Assim, num vetor de tamanho n, o primeiro elemento e o elemento v[0], e o u ltimo elemento o v[n-1]. Nota: o Ap endice H, Vetores e matrizes arrays, mostra em detalhes o uso de vetores e arrays importante no estilo de C. Veremos na Se ca o 15.3 o uso de aloca ca o din amica e vetores. E destacar que o uso de vetores no estilo de C e obsoleto; eles t em sido substitu dos por <vector> de C++. Veremos uma introdu ca o aos vetores no estilo de C++ na Se ca o 9.4.2. Veremos o uso avan cado de vetores e arrays no Cap tulo ?? Biblioteca Blitz++.

9.3.2

Introdu c ao ` as estruturas

A linguagem C utiliza a palavra-chave struct para criar estruturas de dados que s ao utilizadas para armazenar vari aveis, dentro de uma entidade u nica (sem fun co es). O prot otipo para deni ca o de uma estrutura inicia-se com a palavra-chave struct e, em seguida, o nome da estrutura e o bloco com a deni ca o das vari aveis que fazem parte da estrutura. N ao se esque ca do ponto e v rgula ap os o nal do bloco. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

226 Prot otipo: // Declara estrutura SNomeEstrutura struct SNomeEstrutura; // Dene estrutura SNomeEstrutura struct SNomeEstrutura { Tipo1 vari avel1; Tipo2 vari avel2; };

9.3. USO DE TIPOS DO USUARIO

Depois de denida uma estrutura, o seu nome passa a ser um tipo do usu ario, podendo ser utilizada de forma semelhante a de qualquer outro tipo de C++. Para criar um objeto do tipo SNomeEstrutura fa ca: SNomeEstrutura nomeObjeto; Podemos utilizar as vari aveis da estrutura usando nomeObjeto.variavel1 = valor; O exemplo da Listagem 9.4 ilustra a declara ca o e utiliza ca o de estruturas simples. Dentro da struct SPessoa criamos dois vetores de caracteres no estilo de C, nome e matr cula. A fun ca o main() utiliza a estrutura SPessoa para criar um professor. Em seguida, solicita os dados do professor. Na linha SPessoa aluno[numeroAlunos]; criamos um vetor aluno para armazenar informa co es sobre os alunos. Observe que cada casa do vetor armazena uma estrutura do tipo SPessoa. Um la co for e utilizado para entrada dos dados dos alunos, e, ent ao, uma rela ca o com os dados do professor e dos alunos e enviada para a tela. Neste exemplo denimos um tipo novo, o tipo SPessoa, criamos objetos a partir deste tipo, o professor e o vetor aluno, e utilizamos os objetos criados. Listing 9.4: Usando struct.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # include < iostream > // Define uma nova e s t r u t u r a struct SPessoa { char nome [50]; // Vetor nome com 50 c a r a c t e r e s ( uma c s t r i n g ) char matricula [20]; // Vetor m a t r i c u l a com 20 c a r a c t e r e s }; int main () { std :: cout << " Entre com o n u mero de alunos da disciplina ( ex =3) : " ; int n u m e r o A l u n o s ; std :: cin >> n u m e r o A l u n o s ; std :: cin . get () ; SPessoa professor ; std :: cout << " Entre com o nome do professor ( sem espa co ): ";

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

9.3. USO DE TIPOS DO USUARIO


19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 std :: cin >> professor . nome ; std :: cout << " Entre com a matr cula do professor : " ; std :: cin >> professor . matricula ; SPessoa aluno [ n u m e r o A l u n o s ]; for ( int contador = 0; contador < n u m e r o A l u n o s ; contador ++) { std :: cout << " Aluno " << contador ; std :: cout << " \ nEntre com o nome do aluno ( sem espa co ): "; std :: cin >> aluno [ contador ]. nome ; std :: cout << " Entre com a matr cula do aluno : " ; std :: cin >> aluno [ contador ]. matricula ; } std :: cout << " \n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << " \ nRELA C~ A O DE PROFESSOR E S E ALUNOS : " << " \n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << " \ nNome do professor : " << professor . nome << " \ nMatr cul a : " << professor . matricula ; for ( int contador = 0; contador < n u m e r o A l u n o s ; contador ++) { std :: cout << " \n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " << " \ nAluno " << contador << " \ nNome do aluno : " << aluno [ contador ]. nome << " \ nMatr cul a : " << aluno [ contador ]. matricula ; } return 0; } [ b u e n o @ l d s c 0 5 Cap -09] $ ./ a . out Entre com o n u mero de alunos da disciplina ( ex =3) :3 Entre com o nome do professor ( sem espa c o ) : P . C . Philippi Entre com a matr cula do professor : 3251 Aluno 0 Entre com o nome do aluno ( sem espa co ): Liang_Zhirong Entre com a matr cula do aluno : 6154 Aluno 1 Entre com o nome do aluno ( sem espa co ): Fabio_Magnani Entre com a matr cula do aluno : 9465 Aluno 2 Entre com o nome do aluno ( sem espa co ): Luis_Orlando_Emeri ch Entre com a matr cula do aluno : 3164 ------------------------------------------------------RELA C~ A O DE PROFESSORE S E ALUNOS : ------------------------------------------------------Nome do professor : P . C . Philippi Matr cula : 3251 ------------------------------------------------------Aluno 0 Nome do aluno : L i a n g _ Z h i r o n g Matr cula : 6154 ------------------------------------------------------Aluno 1 Nome do aluno : F a b i o _ M a g n a n i Matr cula : 9465 ------------------------------------------------------Aluno 2 Nome do aluno : L u i s _ O r l a n d o _ E m e r i c h

227

Nota: veremos o uso de estruturas em detalhes no Ap endice G Estruturas, uni oes, enumePrograma ca o Orientada a Objeto com C++ Andr e Duarte Bueno

228 ra co es.

9.3. USO DE TIPOS DO USUARIO

9.3.3

Introdu c ao ` as uni oes

Tamb em podemos criar novos tipos, ou tipos do usu ario utilizando uni oes. Uma union (uni ao) permite a um conjunto de objetos ocupar o mesmo local na mem oria. Veja o prot otipo a seguir. Observe que, como os objetos ocupam o mesmo local na mem oria, somente um objeto pode ser utilizado por vez e que o tamanho da union ser a dado pelo tamanho do maior objeto. Note ainda que podemos colocar dois objetos denidos pelo usu ario dentro de uma union, mas s o podemos utilizar um de cada vez. Isto e, quando um e usado, o outro e perdido. Prot otipo: // Declara uni ao UNomeUniao union UNomeUniao; // Dene uni ao UNomeUniao union UNomeUniao { Tipo1 v1; Tipo2 v2; } A Listagem 9.5 inicia denindo a uni ao UPropriedade, com dois atributos um double e um int. Em seguida, cria objeto a partir da uni ao denida, UPropriedade obj;. O acesso aos atributos da uni ao e simples, nomeObjetoUni ao.nomeAtributo (exemplo: obj.raioHidraulico;). Observe que o sizeof() da uni ao tem a mesma dimens ao do sizeof() de um double. Veremos o uso de sizeof() na Se ca o 9.5.3. Listing 9.5: Usando union.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # include < iostream > int main () { union U P r o p r i e d a d e { int r a i o H i d r a u l i c o ; double condutanc i a ; };

// Define a uni~ ao // A t r i b u t o s da uni~ ao

U P r o p r i e d a d e obj ; // Cria objeto do tipo UPropriedade , com nome obj obj . r a i o H i d r a u l i c o = 3; std :: cout << " r a i o H i d r a u l i c o = " << obj . r a i o H i d r a u l i c o << \ t ; obj . condutanci a = 5.0; std :: cout << " condut^ a nci a = "

<< obj . condutanc i a << \ n ;

std :: cout << " sizeof ( double ) = " << sizeof ( double ) << \ t ; std :: cout << " sizeof ( U P r o p r i e d a d e ) = " << sizeof ( U P r o p r i e d a d e ) return 0; } raioHidraulico = 3 sizeof ( double ) = 8 condut^ a nc i a = 5 sizeof ( U P r o p r i e d a d e ) = 8

<< std :: endl ;

Nota: veremos o uso de uni oes em detalhes no Ap endice G Estruturas, uni oes, enumera co es. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

9.3. USO DE TIPOS DO USUARIO

229

9.3.4

Introdu c ao ` as enumera c oes

Uma enumera ca o e uma seq u encia de valores que tem como objetivo enumerar algum processo. Uma enumera ca o e um tipo denido pelo usu ario. No prot otipo a seguir, v1 , v2 , v3 ,..., vn s ao os valores, e ENome e o nome da enumera ca o. Prot otipo: enum ENome { v1, v2, v3,...,vn }; Veja no exemplo a seguir como declarar e usar uma enumera ca o. EDia e o nome da enumera ca o e dom = 1, seg = 2, ter = 3, qua = 4, qui = 5, sex = 6, sab = 7, os valores da enumera ca o. Observe que os valores de cada elemento da enumera ca o s ao incrementados de 1. Note que criamos um objeto do tipo da enumera ca o na linha EDia dia; e o utilizamos da forma como usamos os tipos predenidos de C++. Exemplo: enum EDia { dom, seg, ter, qua, qui, sex, sab }; EDia dia; dia = seg; cout < < "hoje e " < < dia; Nota: veremos o uso de enumera co es em detalhes no Ap endice G Estruturas, uni oes, enumera co es.

9.3.5

Introdu c ao ` as classes

A forma mais comum de criar tipos do usu ario e utilizar o conceito de classe. C++ permite a constru ca o do conceito de classe, com atributos e m etodos, exatamente da forma discutida na Parte I Filosoa e modelagem orientada a objeto. N ao se preocupe se n ao entender exatamente o que est a sendo feito, pois, no Cap tulo 11 Classes, descreveremos em detalhes como criar e utilizar as classes de C++. Implementaremos nossa primeira classe na Listagem 9.6. Nosso objetivo e mostrar a forma como C++ dene uma classe e mostrar que uma classe denida pelo usu ario se comporta da mesma forma que os tipos predenidos da linguagem. Observe que a declara ca o de um objeto do tipo CComplexo (exemplo: CComplexo a, b;) usa o mesmo formato que a declara ca o de um tipo predenido de C++ (exemplo: int x;). A forma de uso tamb em e igual (exemplo: c = a + b). Nota: neste exemplo utilizamos o conceito de sobrecarga de operador na linha c = a + b;. Veja o conceito de operadores no Ap endice C Operadores, e de sobrecarga de operadores no Cap tulo 21 Sobrecarga de operador. O conceito de friend ser a apresentado no Cap tulo 20 Friend. Listing 9.6: Exemplo preliminar de deni ca o de classe do usu ario.
1 2 3 4 5 6 7 8 # include < iostream > // / E x e m p l o p r e l i m i n a r de d e f i n i c~ a o de um tipo de usu a rio , // / por meio de uma classe // / D e f i n i c~ a o do tipo do u s u a r i o CComplexo , r e p r e s e n t a um n u mero c o m p l e x o class CComplexo { public :

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

230
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

9.4. USANDO TIPOS DEFINIDOS EM BIBLIOTECAS STL

// / A t r i b u t o s real e img double real , img ; // / M e todo usado para d e f i n i c~ a o dos v a l o r e s de real e img void Set ( double _real , double _img ) { real = _real ; img = _img ; } // / S o b r e c a r g a do o p e r a d o r + friend CComplexo operator +( CComplexo & c1 , CComplexo & c2 ) ; }; // / E x e m p l o da d e f i n i c~ a o da s o b r e c a r g a de um o p e r a d o r + // / O o p e r a t o r+ cria um novo n u mero c o m p l e x o com nome c3 onde a r m a z e n a a soma // / dos v a l o r e s reais e i m a g i n a r i o s de c1 e c2 . CComplexo operator +( CComplexo & c1 , CComplexo & c2 ) { CComplexo c3 ; c3 . real = c1 . real + c2 . real ; c3 . img = c1 . img + c2 . img ; return c3 ; } int main () { CComplexo a , b ; // / Fun c~ ao principal

// / Cria os o b j e t o s a e b do tipo C C o m p l e x o // / Chama m e todo Set dos o b j e t o s a e b a . Set (5 , 4) ; // / a . real = 5; a . img = 4 b . Set (2 , 6) ; // / b . real = 2; b . img = 6 CComplexo c ; // / Cria um novo objeto do tipo c o m p l e x o com nome c c = a + b; // / Soma os c o m p l e x o s a e b e a r m a z e n a em c // / Mostra o r e s u l t a d o na tela std :: cout << " c ( " << c . real << " ," << c . img << " ) = " << " a ( " << a . real << " ," << a . img << " ) + " << " b ( " << b . real << " ," << b . img << " ) " << std :: endl ; return 0; // / E n c e r r a o p r o g r a m a

} [ a n d r e @ m e r c u r i o Parte - II ] $ ./ a . out c (7 ,7) = a (5 ,4) + b (2 ,3)

Agora que voc e j a sabe usar os tipos predenidos de C++ (char, int, float, etc.), j a tem id eia de como se declara e se dene um tipo do usu ario (a estrutura SPessoa, a uni ao UPropriedade, a enumera ca o EDia e a classe CComplexo), podemos ver um exemplo que utiliza uma biblioteca externa (a biblioteca-padr ao de C++, a STL). Nota: os tipos num ericos predenidos da linguagem C++, bool, char, int, float e double, podem ser vistos como classes denidas pelo criador do C++ e que est ao escondidas de voc e. Assim, pode-se imaginar que existem as classes: class bool{};, class char{};, class int{};, class float{};, class double{};.

9.4

Usando tipos denidos em bibliotecas STL

Uma biblioteca e um conjunto de arquivos objetos reunidos em um u nico arquivo. Voc e pode criar e utilizar suas pr oprias bibliotecas ou utilizar bibliotecas desenvolvidas por terceiros. Veremos como criar nossas pr oprias bibliotecas no Cap tulo ?? Bibliotecas, e na Se ca o ?? Crit erios para sele ca o de bibliotecas externas. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

9.4. USANDO TIPOS DEFINIDOS EM BIBLIOTECAS STL

231

Nesta se ca o vamos apresentar uma introdu ca o a duas classes da biblioteca-padr ao de C++: as classes <string> e <vector>.

9.4.1

Introdu c ao ` a classe <string>

Basicamente uma string e uma seq u encia de caracteres. Para utilizar a classe string de C++, inclua o arquivo de cabe calho <string>, crie objetos do tipo string e, em seguida, acesse seus m etodos. Veja no exemplo a seguir diferentes formas para criar strings: Exemplo: #include <string> int main() { // Cria string vazia com nome s1 std::string s1; // Cria string com nome s2 e conte udo "a classe string" std::string s2 ("a classe string"); // Cria string com nome s3 e inicializa com " e legal" std::string s3 = " e legal"; // Cria string com nome s4, uma c opia de s3 std::string s4 (s3); // Cria string s5, com espa co para 10 caracteres, preenche com b std::string s5 (10, b); // Cria string com nome s6 e redimensiona para 100 caracteres std::string s6 ("eu terei espa co para 100 caracteres"); s6.resize(100); return 0; } Veja a seguir o prot otipo de alguns m etodos da classe string. Note que size_type, normalmente, e um int informando a dimens ao da string. A palavra-chave const em um par ametro indica que o mesmo n ao vai ser alterado ( e constante). A palavra-chave const no nal da declara ca o de um m etodo indica que este m etodo n ao modica o objeto ( e somente leitura). size type size() const; Retorna o n umero de elementos utilizados pelo container (veja Figura 32.1). Para mudar o size() de um container use resize(novaDimens~ ao). void reserve (size type n = 0); Reserva espa co de mem oria para n elementos (n caracteres). void clear (); Zera a string. A string ca vazia. bool empty () const; Retorna true se a string estiver vazia. void erase(iterator p); Remove o elemento da posi ca o p, isto e, o elemento acessado usando o iterador p. string substr (size type pos = 0, size type n = npos) const; Cria uma substring a partir da posi ca o pos, considerando n caracteres. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

232

9.4. USANDO TIPOS DEFINIDOS EM BIBLIOTECAS STL

size type nd (const char * s, size type pos, size type n) const; Procura a primeira ocorr encia da string s, de modo que a pesquisa inicia em pos e considera at e n caracteres. size type nd (const string & str, size type pos = 0) const; Procura a primeira ocorr encia da cstring str, a pesquisa inicia em pos. const char* c str(); Retorna uma string constante no estilo de C (uma cstring). A palavra-chave const no in cio da declara ca o de um m etodo indica que este m etodo retorna um objeto constante (const char*). Na Listagem 9.7, alguns m etodos da classe string s ao testados. Uma descri ca o detalhada da classe string e apresentada no Cap tulo 24 A classe <string>. Listing 9.7: Exemplo preliminar de uso da classe <string> de C++.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 # include < iostream > # include < string > int main () { // Cria string com nome s1 std :: string s1 ; s1 = " Oi , tudo bem " ; // Cria string com nome s2 e a r m a z e n a " C ++ e legal " std :: string s2 ( " C ++ e legal " ) ; // Cria string com nome s3 e i n i c i a l i z a com " demais " std :: string s3 = " demais " ; // Tamanho , c a p a c i d a d e e d i m e n s ~ ao std :: cout << " \ ns1 . size () = " << " \ ns1 . capacity () = " << " \ ns1 . max_size () = " m a xima da string s1 << s1 . size () << s1 . capacity () << s1 . max_size () << std :: endl ;

// R e t o r n a true se s1 e s t i v e r vazia if ( s1 . empty () ) std :: cout << " A std :: string s1 esta vazia " << std :: endl ; // C o n c a t e n a c~ ao s1 += s2 + s3 ; std :: cout << " Ap o s s1 += s2 + s3 ; \ ns1 = " << s1 << " \ ns2 = " << s2 << " \ ns3 = " << s3 << std :: endl ; return 0; }

s1 . size () = 12 s1 . capacity () = 12 s1 . max_size () = 4 6 1 1 6 8 6 0 1 8 4 2 7 3 8 7 8 9 7 Ap o s s1 += s2 + s3 ; s1 = Oi , tudo bem C ++ e legal demais s2 = C ++ e legal s3 = demais

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

9.4. USANDO TIPOS DEFINIDOS EM BIBLIOTECAS STL

233

9.4.2

Introdu c ao ` a STL e ` a classe <vector>

A STL, ou Standard Template Library, e uma biblioteca de objetos avan cada que foi desenvolvida utilizando os mais modernos conceitos da programa ca o orientada a objeto em C++. Todo desenvolvimento da STL foi acompanhado e aprovado pelo comit e de padroniza ca o do C++, o ANSI C++ (veja Se ca o 7.3), sendo parte integrante das distribui co es-padr ao de C++. Entre as caracter sticas da STL destacam-se: N ao utiliza polimorsmo em fun ca o do desempenho. Utiliza extensivamente os templates (veremos os templates no Cap tulo 27 Templates). A STL e constru da com base em tr es conceitos (Se ca o 31.1.2): Containers objeto utilizado para armazenar grupos de objetos (como <vector>). Iteradores objetos utilizados para percorrer o container (s ao ponteiros inteligentes). Programa c ao gen erica conjunto de fun co es gen ericas que manipulam os containers utilizando os iteradores. A STL e apresentada em detalhes na Parte III deste livro. No exemplo da Listagem 9.8 voc e ver a a utiliza ca o da classe <vector>, uma classe extremamente u til disponibilizada pela STL. Mas antes de discutirmos o exemplo, vamos apresentar alguns conceitos b asicos de <vector>. Um <vector> e um tipo de container em que os dados est ao armazenados de forma seq u encial; funciona como um vetor no estilo de C (Se ca o 9.3.1), permitindo acesso aleat orio (veja agora as Figuras 32.1 e 31.2). O container <vector> tem r apida inser ca o de objetos no nal do vetor e lenta no meio. Como em vetores comuns de C, <vector> n ao verica os ndices. Isto signica que se o vetor tem dez casas, podemos acessar de v[0] at e v[9]. N ao podemos acessar v[10]. O Acesso a v[10] provoca um acesso de mem oria ilegal, e o programa pode travar/terminar (veremos exemplos de bugs na Listagem ??). Veja no exemplo a seguir como criar e usar um <vector>. Para usar um container do tipo <vector>, inclua o arquivo de cabe calho <vector>. Observe que, como criei objetos do tipo <vector>, posso acessar os m etodos da classe, no caso, o m etodo v.size() retorna o n umero de elementos do container. Exemplo: #include <vector> int main() { // Cria um vetor para armazenar n umeros inteiros // v1 tem tamanho zero. std::vector<int> v1(); // Cria um vetor de inteiros, com 15 elementos, e nome v2 std::vector<int> v2(15); // Cria um vetor de floats com 16 elementos todos iguais a 3.55 std::vector<float> v3(16,3.55); std::cout < < "\nn umero de elementos do container =" < < v3.size() < < "\ncapacidade do container =" < < v3.capacity() < < "\no vetor esta vazio? " < < v3.empty() < < std::endl; return 0; } Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

234

9.4. USANDO TIPOS DEFINIDOS EM BIBLIOTECAS STL

Os m etodos size(), reserve(), clear(), empty() e erase(), brevemente descritos na Se ca o 9.4.1, s ao v alidos para <vector>. Veja a seguir outros m etodos u teis de <vector>. void push back(const T& x); Insere uma c opia do objeto x no nal do vetor (no m do container). void pop back(); Remove o u ltimo elemento do vetor (sem retorno). No exemplo da Listagem 9.8 e criado um vetor e solicitada ao usu ario a entrada de dados. Cada novo valor que o usu ario introduz e armazenado no vetor. Para encerrar a entrada de dados, o usu ario digita Ctrl + d no GNU/Linux e Mac OS X, e ctrl + z no Windows. Em seguida, o programa mostra os valores do vetor. Este exemplo inclui o uso do objeto container <vector> e os m etodos push_back(), size(), empty(), clear(), front() e back(). Note ainda que como a classe <vector> e uma classe gen erica (template), posso criar um vetor de inteiros, de n umeros utuantes ou de outro tipo qualquer. Observe que para criar um <vector> usamos std::vector<Tipo> nomeVetor;, ou seja, e necess ario passar dentro de <> o tipo de objeto que o vetor vai armazenar. No exemplo estamos criando um vetor de inteiros, logo, usamos std::vector <int> v;. O programa utiliza streams, como std::cout e std::cin, para sa da e entrada de dados. O m etodo good() pode ser acessado pela istream std::cin para vericar se a u ltima entrada foi correta. Neste exemplo usamos if(std::cin.good()) para vericar se a entrada foi correta. Caso armativo, o objeto data e acrescentado no m do vetor v com push_back(data);. O programa utiliza ainda estruturas de controle, como, do...while() (veja Se ca o D.3.3), e for (veja Se ca o 8.9.1, D.3.1). Listing 9.8: Exemplo preliminar de uso da classe <vector> da biblioteca STL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # include < iostream > // Entrada e sa da # include < vector > // Classe de vetores , do container vector int main () // Defini ca ~ o da fun ca ~ o main () . { // Cria um vector , do tipo int , com nome v ( um vetor de inteiros ) // Como um vector pode armazenar objetos de diferente s tipos // ( char , int , float , CComplexo ) preciso informar dentro de <> // o tipo a ser manipulad o pelo vetor . std :: vector < int > v ; int data ; std :: cout << << << <<

" No DOS um Ctrl + z encerra a entrada de dados ." " No Mac um Ctrl + d encerra a entrada de dados ." " No GNU / Linux um Ctrl + d encerra a entrada de dados ." std :: endl ;

// Inicia la c o do .. while , vai ser repetido enquanto a entrada for correta // note que do .. while e executado pelo menos uma vez . do { std :: cout << "\ nEntre com o dado (" << v . size () << ") : "; std :: cin >> data ; std :: cin . get () ; if ( std :: cin . good () ) v . push_back ( data ) ; } while ( std :: cin . good () ) ; // Se a entrada for v a lida // Adiciona data ao final do vetor v // Enquanto n~ a o digitar ctrl +d , ou ctrl + z

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

9.5. MANIPULANDO TIPOS


30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 // Acessa partes do vetor usando m e todos front () e back () std :: cout << "\ nPrimeiro elemento do vetor = " << v . front () << "\ n U ltimo elemento do vetor = " << v . back () << std :: endl ; // Usa um la c o for para percorrer o vetor e mostrar os elementos na tela for ( int i = 0; i < v . size () ; i ++) std :: cout << " v [" << i << "]=" << v [ i ] << ; std :: cout << std :: endl ; if ( v . empty () ) // Verifica se o container esta vazio std :: cout << " O vetor est a vazio " << std :: endl ; else std :: cout << " O vetor n~ a o est a vazio " << std :: endl ; // Chama m e todo clear () , que apaga todos os objetos armazenad o s no vetor . v . clear () ; if ( v . empty () ) // Verifica se o container esta vazio std :: cout << " O vetor est a vazio " << std :: endl ; else std :: cout << " O vetor n~ a o est a vazio " << std :: endl ; std :: cin . get () ; return 0; } [ a n d r e @ m e r c u r i o Parte - II ] $ ./ a . out No DOS um ctrl + z encerra a entrada de dados . No Mac um ctrl + d encerra a entrada de dados . No Linux um ctrl + d encerra a entrada de dados . Entre Entre Entre Entre com com com com o o o o dado dado dado dado (0) :1 (1) :2 (2) :3 (3) :

235

Primeiro elemento do vetor = 1 U ltimo elemento do vetor = 3 v [0]=1 v [1]=2 v [2]=3 O vetor n~ a o esta vazio O vetor esta vazio

Bem, vimos exemplos de como declarar, denir e utilizar os tipos predenidos de C++, tipos do usu ario e tipos denidos em bibliotecas externas (como a STL). Revise os exemplos e veja que a forma como se declara, dene-se e se usa os tr es tipos de objetos e a mesma.

9.5

Manipulando tipos

Veremos a seguir um conjunto de conceitos de C++ utilizados para manipular os diferentes tipos de objeto de C++.

9.5.1

Criando apelidos typedef

Um typedef nada mais e do que um apelido para uma declara ca o de um objeto. Veja a seguir o prot otipo para denir e usar um typedef. Prot otipo: typedef TipoConhecido Apelido; Apelido nomeObjeto; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

236

9.5. MANIPULANDO TIPOS

No exemplo a seguir vamos criar um apelido para o tipo const float, com nome cfloat. Um objeto const e float poder a ser criado usando-se cfloat. Exemplo: typedef const float cfloat; cfloat objeto_float_constante; No pr oximo exemplo criaremos outros apelidos, como uint, uchar, ptrInt e schar. Exemplo: typedef unsigned int uint; typedef unsigned char uchar; typedef int* ptrInt; typedef signed char schar; A vantagem do uso de typedefs e que o programador precisa digitar um n umero menor de caracteres. A desvantagem e que em alguns editores perde-se o recurso de identica ca o da sintaxe utilizada, conhecido como sintax highlighty e dispon vel na maioria dos editores de programas (como o emacs, gedit, kate).

9.5.2

Obtendo o tipo de tamanho size_t()

O tipo size_t e um conceito gen erico que representa a dimens ao de um objeto (seu tama um tipo integral, sem sinal. O tipo efetivo de size_t depende da plataforma, sendo nho). E usualmente implementado como um int. Veja a seguir o prot otipo para uso de size_t(). Prot otipo: size t(objeto); Nota: de um modo geral size_t e formatado como unsigned int.

9.5.3

Obtendo o tamanho dos objetos sizeof()

O operador sizeof() e utilizado para retornar o tamanho de um objeto em bytes. Quando aplicado a um vetor, retorna o n umero total de bytes do vetor. Pode ser aplicado ao ponteiro de uma fun ca o, mas n ao se aplica a uma fun ca o. Veja a seguir o prot otipo de sizeof(): Prot otipo: sizeof(Tipo); Retorna o tamanho do Tipo. sizeof(obj); Retorna o tamanho do objeto. sizeof(Tipo*); Retorna o tamanho da classe do ponteiro. Na Listagem 9.9 mostramos na pr atica o uso de sizeof(). No in cio da listagem, colocamos em coment ario as instru co es para compilar o programa para plataforma de 32 e 64 bits. At e aqui, todo programa que compilamos tinha o nome a.out . Podemos informar o nome do execut avel com a op ca o -o. Por exemplo, a linha g++ -m64 sizeof.cpp -o sizeof-64 Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

9.5. MANIPULANDO TIPOS

237

e usada para compilar o arquivo sizeof.cpp para plataforma de 64 bits (op ca o -m64), e solicita que o nome do execut avel seja sizeof-64 (op ca o -o sizeof-64). Observe que tamb em geramos uma vers ao de 32 bits do programa. Note as diferen cas no tamanho em bytes dos tipos predenidos de C++: 64 bits: sizeof(long int) = 8 sizeof(long double) = 16 sizeof(&nome) = 8 32 bits: sizeof(long int) = 4 sizeof(long double) = 12 sizeof(&nome) = 4 Note que a sa da das listagens 9.3, 9.9 e as informa co es da Tabela 9.1 s ao dependentes da plataforma (16, 32, 64 ou 128 bits). Isto signica que antes de usar os tipos predenidos voc e deve vericar quais os valores assumidos pelos tipos predenidos na sua plataforma. Listing 9.9: Usando sizeof().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // Vers~ a o 32 bits : g ++ - m32 sizeof . cpp -o sizeof -32 // Vers~ a o 64 bits : g ++ - m64 sizeof . cpp -o sizeof -64 # include < iostream > int main () { char nome [] = " Uma string de C ou cstring " ; std :: cout << " \ n sizeof ( bool ) = " << " \ n sizeof ( char ) = " << " \ n sizeof ( unsigned char ) = " << << << << "\n "\n "\n "\n sizeof ( int ) = " sizeof ( unsigned int ) = " sizeof ( long int ) = " sizeof ( long long int ) = "

<< sizeof ( bool ) << sizeof ( char ) << sizeof ( unsigned char ) << << << << sizeof sizeof sizeof sizeof ( int ) ( unsigned int ) ( long int ) ( long long int )

<< " \ n sizeof ( float ) = " << " \ n sizeof ( double ) = " << " \ n sizeof ( long double ) = "

<< sizeof ( float ) << sizeof ( double ) << sizeof ( long double )

<< " \ n sizeof (& nome ) = " << " \ n sizeof ( nome ) = " return 0; }

<< sizeof (& nome ) << sizeof ( nome ) << std :: endl ;

[ b u e n o @ l d s c 0 5 Cap -09] $ g ++ - m64 sizeof . cpp -o sizeof -64 [ b u e n o @ l d s c 0 5 Cap -09] $ ./ sizeof -64 sizeof ( bool ) =1 sizeof ( char ) =1 sizeof ( unsigned char ) =1 sizeof ( int ) =4 sizeof ( unsigned int ) =4 sizeof ( long int ) =8 <--

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

238
sizeof ( long long int ) =8 sizeof ( float ) =4 sizeof ( double ) =8 sizeof ( long double ) =16 sizeof (& nome ) = 8 sizeof ( nome ) = 27

9.5. MANIPULANDO TIPOS

<-<--

[ b u e n o @ l d s c 0 5 Cap -09] $ g ++ - m32 sizeof . cpp - o sizeof -32 [ b u e n o @ l d s c 0 5 Cap -09] $ ./ sizeof -32 sizeof ( bool ) =1 sizeof ( char ) =1 sizeof ( unsigned char ) =1 sizeof ( int ) =4 sizeof ( unsigned int ) =4 sizeof ( long int ) =4 <-sizeof ( long long int ) =8 sizeof ( float ) =4 sizeof ( double ) =8 sizeof ( long double ) =12 <-sizeof (& nome ) = 4 <-sizeof ( nome ) = 27

Veja outro exemplo de uso de sizeof() na Listagem C.1. Nota: veremos como gerar programas multiplataforma no Cap tulo ?? Como montar um programa multiplataforma com as ferramentas da GNU. O compilador g++ e descrito em detalhes no Cap tulo ?? Compilando com gcc e g++.

9.5.4

Identicando o tipo do objeto typeid()2

Para facilitar a verica ca o do tipo de determinado objeto, foi desenvolvida a biblioteca <typeinfo>. Essa biblioteca sobrecarrega os operadores == e != para comparar tipos do usu ario. O operador typeid(), quando aplicado a um objeto, retorna o tipo do objeto. Veja a seguir o prot otipo para uso de typeid(). Prot otipo: typeid(objeto); typeid(objeto).name(); Para uso do typeid() e preciso estar ativada a op ca o -RTTI Run Time Type Identication do compilador. No compilador da GNU, o g++, esta op ca o j a e ativada por padr ao. Leia no manual de seu compilador como ativar esta op ca o. Se voc e passar para a fun ca o typeid() um ponteiro (ou refer encia) com o valor 0, a fun ca o typeid() lan ca uma exce ca o do tipo bad_typeid. Veja no exemplo da Listagem 9.10 como vericar se dois objetos a e b s ao do mesmo tipo. Observe que o m etodo typeid() retorna um objeto com informa co es sobre o tipo, assim, voc e pode chamar o m etodo name() para obter o nome da classe do objeto. Listing 9.10: Usando typeid().
1 2 3 4 5 6 # include < iostream > # include < string > # include < typeinfo > // Uso de typeid () using namespace std ; class A { public : int a ; };

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

FORTE DO C++ 9.6. VANTAGEM DA TIPIFICAC AO


7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

239

class B : public A { class K { int { A B K main () a; b; k; public :

public : int k ; };

int b ; };

// Cria objeto do tipo A com nome a // Cria objeto do tipo B com nome b // Cria objeto do tipo K com nome k " \ ntypeid ( a ) " \ ntypeid ( a ) " \ ntypeid ( a ) " \ ntypeid ( b ) == == == == typeid ( a ) -> " typeid ( b ) -> " typeid ( k ) -> " typeid ( k ) -> " << << << << ( typeid ( typeid ( typeid ( typeid (a) (a) (a) (b) == == == == typeid typeid typeid typeid (a)) (b)) (k)) (k))

cout << << << <<

<< " \ ntypeid ( a ) . name () ->" << ( typeid ( a ) . name () ) << " \ ntypeid ( b ) . name () ->" << ( typeid ( b ) . name () ) << " \ ntypeid ( k ) . name () ->" << ( typeid ( k ) . name () ) << endl ; int o b j e t o I n t e i r o = 3; string n o m e O b j e t o I n t e i r o = typeid ( o b j e t o I n t e i r o ) . name () ; cout << " nomeObjetoI nt e ir o - > " << n o m e O b j e t o I n t e i r o << endl ; double o b j e t o D o u b l e = 3; string n o m e O b j e t o D o u b l e = typeid ( o b j e t o D o u b l e ) . name () ; cout << " nomeObjetoDo ub le - > " << n o m e O b j e t o D o u b l e << endl ; return 0; } typeid ( a ) == typeid ( a ) - >1 typeid ( a ) == typeid ( b ) - >0 typeid ( a ) == typeid ( k ) - >0 typeid ( b ) == typeid ( k ) - >0 typeid ( a ) . name () - >1 A typeid ( b ) . name () - >1 B typeid ( k ) . name () - >1 K nomeObjetoIn te i ro - > i nomeObjetoDou bl e - > d

9.6

Vantagem da tipica c ao forte do C++

A tipica ca o forte obriga o programador a tomar mais cuidado na declara ca o, deni ca o e utiliza ca o dos objetos, atributos e m etodos. Em troca, tem uma garantia maior de que o c odigo n ao apresenta problemas, pois, com a tipica ca o forte, o compilador pode encontrar mais facilmente os erros do programa.

9.7

Senten cas para tipos

Um tipo do usu ario, ou um tipo de uma biblioteca externa, estar a bem denido se puder ser utilizado da mesma forma que um tipo predenido de C++. Em uma plataforma de 32 bits, o tipo float tem 32 bits, double tem 64 bits e long double tem 96 bits. Note que o tipo long double possui 12 bytes de comprimento e e exatamente assim que o processador 80 x 87 trabalha com n umeros em pontos utuantes. Dessa forma, pode-se passar um objeto do tipo long double diretamente para programas em assembler. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

240

9.8. RESUMO DO CAP ITULO

O compilador g++ (descrito no Cap tulo ?? Compilando com gcc e g++) suporta o tipo long long, que representa um inteiro de 64 bits. A convers ao de tipos e discutida no Cap tulo 25 Convers oes.

9.8

Resumo do cap tulo

Neste cap tulo aprendemos que a linguagem C++ e altamente prototipada. Aprendemos a criar e usar objetos predenidos de C++ (como int e float). Vimos que os tipos predenidos podem ser do tipo inteiro (char, short int, int, long int) ou utuantes (float, double, long double). Os mesmos podem ser explicitamente indicados no c odigo com uso de suxos, como em 7.45f (float) ou 89LL (long long int). Aprendemos a usar o arquivo de cabe calho <limits> e o template numeric_limits<Tipo> para obter informa co es num ericas sobre os tipos predenidos. Vimos exemplos preliminares que mostram como proceder para criar tipos do usu ario e a utiliz a-los da mesma forma que os tipos predenidos de C++. Vimos os vetores no estilo de C, uma introdu ca o ` as estruturas, ` as uni oes, ` as enumera co es e ` as classes, aprendendo a criar tipos do usu ario (tipos do programador). Criamos uma estrutura SPessoa, uma uni ao UPropriedade, uma enumera ca o EDia e uma classe CComplexo. Aprendemos os conceitos b asicos da classe <string> e seu uso para manipular objetos strings em C++. Tamb em aprendemos a utilizar um objeto <vector> da STL. O m etodo push_back(); e usado para adicionar elementos no nal do vetor. O m etodo size(); retorna o tamanho do vetor. O m etodo empty(); retorna true se o vetor estiver vazio e false se estiver com algum elemento. O m etodo clear(); e utilizado para zerar o vetor (apagar todos os elementos). Vimos ainda conceitos como typedef para criar apelidos, typeid() para vericar o tipo do objeto, e sizeof() para obter o tamanho dos objetos. Nos pr oximos cap tulos descreveremos, passo a passo, como criar nossas pr oprias classes (tipos do usu ario) e como utilizar em detalhes os containers da STL.

9.9

Exerc cios

1. Quais s ao os tipos predenidos de C++ e seus respectivos valores m nimos, m aximos? 2. Se vou trabalhar com uma matriz em que os valores variam de -100 a +100, qual tipo devo utilizar? 3. Por que devo tomar cuidado com unsigned? 4. Modique a Listagem 9.1 acrescentando sa da para tela. 5. Modique a Listagem 9.2, troque int por char e veja os resultados. 6. Compile e rode a Listagem 9.3 em computadores de 32 e 64 bits. Verique as diferen cas nas sa das. 7. Modique a Listagem 9.4, acrescentando novas vari aveis na estrutura criada. 8. Documentar a Listagem 9.4, descrevendo o que ocorre a cada linha. 9. Modique a Listagem 9.5, criando uma uni ao de tipos diferentes. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

9.9. EXERC ICIOS 10. Implementeexemplo que utilize enumera co es (Se ca o 9.3.4).

241

11. Modique a Listagem 9.7, acrescentando o uso de find(), reserve(), substr(), clear() e replace(). 12. Modique a Listagem 9.8, acrescentando o uso de erase(), pop_back() e clear(). 13. A Listagem 9.8 apresenta um trecho de c odigo repetido. Monte uma fun ca o externa para tratar esse trecho de c odigo. 14. Compare os m etodos disponibilizados para <vector> e para <string>. 15. Compile e rode a Listagem 9.9, em um computador 32 bits, e anoteos resultados. Repita o procedimento para um computador de 64 bits. 16. Tente modicar a Listagem 9.6. Tente acrescentar um operador de subtra ca o -. 17. Na Listagem 9.2 explique porque foi poss vel criar os n umeros x, y, z duas vezes dentro de main()? 18. Se voc e tiver curiosidade, pode ler antecipadamente a Se ca o 32.1, que descreve o container <vector>.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

242

9.9. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 10

Namespace
Vimos na se ca o 6.2.2 os conceitos de assuntos e pacotes. Veremos, ent ao, que os mesmos podem ser implementados em C++ utilizando-se o conceito de namespace. Para isso, estudaremos o que e um namespace (Se ca o 10.1) e como usar o espa co de nomes da biblioteca-padr ao de C++ (Se ca o 10.2). Em seguida, mostraremos como usar a palavra-chave using para liberar o acesso a determinado objeto (Se ca o 10.3), como denir e utilizar um espa co de nomes para criar pacotes (Se ca o 10.4) e como usar um namespace an onimo (Se ca o 10.5). Veremos ainda o uso avan cado dos namespaces (Se ca o 10.6), como compor namespaces (Se ca o 10.6.1), como criar namespaces aninhados (Se ca o 10.6.2) e como usar vari aveis est aticas em um namespace (Se ca o 10.6.3).

10.1

O que e um namespace?

Vimos na Se ca o 6.2.2 que um pacote e um conjunto de classes mais fortemente relacionadas entre si, e que essas classes costumam fazer parte do mesmo assunto. Usualmente C++ usa o conceito de namespace para empacotar grupos de classes. Como o pr oprio nome diz, namespace signica espa co para nomes. Um namespace e um espa co utilizado para declarar vari aveis, fun co es, classes, uni oes, estruturas, enumera co es etc. Um namespace dene um escopo. Quando voc e monta seu programa utilizando bibliotecas externas, podem ocorrer duplica co es de nomes, isto e, um objeto denido em uma das bibliotecas externas pode ter o mesmo nome de um objeto denido por voc e. Por exemplo: voc e criou as fun co es min() e max(), as quais retornam o menor e o maior valor de um vetor, mas a STL j a possui essas fun co es. Desta forma, ao chamar a fun ca o min(), o compilador n ao sabe qual fun ca o min() voc e quer chamar a que voc e deniu ou a da STL? Solucionar o problema da duplica ca o de nomes pode ser complexo, pois, se esses nomes pertencerem a bibliotecas externas, voc e precisar a contactar os desenvolvedores dessas bibliotecas para resolver os conitos, ou renomear seus objetos e fun co es. Veremos a seguir como usar o namespace padr ao de C++ e, na Se ca o 10.4, como denir um namespace. 243

244

STD:: 10.2. UTILIZANDO O ESPACO DE NOMES DA BIBLIOTECA-PADRAO

10.2

Utilizando o espa co de nomes da biblioteca-padr ao std::

Para utilizar os objetos da biblioteca-padr ao de C++ e preciso incluir a palavra-chave std e, em seguida, o operador de resolu ca o de escopo ::. Veja o prot otipo. Prot otipo: // Para usar uma fun ca o da std std::nomeFuncao(); // Para usar um objeto da std std::nomeObjeto; // Para chamar uma fun ca o da std com par ametros da std std::nomeFuncao(std::nomePar ametro); Nas listagens de c odigo j a apresentadas, j a utilizamos std::cout, std::cin.get() e std::endl.

10.3

Mudando escopo com using

A palavra-chave using e utilizada para mudar o escopo de uma vari avel, um atributo, um objeto, uma fun ca o ou um m etodo. De um modo geral, using pode ser utilizado para: Liberar o uso de um objeto de um namespace para uso no escopo local. No exemplo a seguir liberamos apenas o uso de cout. Exemplo: using std::cout; cout < < "oi tudo bem" < < std::endl; Liberar o acesso de fun co es de escopo diferente no escopo local. No exemplo a seguir liberamos o uso da fun ca o abort(), da biblioteca-padr ao de C. Veja exemplo da Listagem 10.2. Exemplo: #include <cstdlib> using std::abort; // Torna a fun c~ ao abort() acess vel Liberar o uso de todas as classes, objetos e fun co es declaradas dentro de um namespace para uso no escopo local. No exemplo a seguir liberamos todos os objetos, fun co es e classes da std:: para uso local. Exemplo: using namespace std; int x = 3; cout < < " Entre com x : "; cin > > x; cin.get(); cout < < " x = " < < x < < endl; Compor namespaces. Veremos exemplo na Se ca o 10.6.1. 2 Mudar a visibilidade (p ublica, protegida ou privada) dos membros de uma classe em heran cas (Se ca o 17.5). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

10.4. PROTOTIPO PARA DECLARAR E DEFINIR UM NAMESPACE

245

10.4

Prot otipo para declarar e denir um namespace

Nesta se ca o veremos como criar um pacote utilizando o conceito de namespace. Veja o prot otipo. Observe que colocamos a palavra-chave namespace seguido do nome do namespace. Tudo que estiver dentro do bloco far a parte do namespace, do escopo do namespace. Por conven ca o o nome de um namespace/pacote inicia com letra min uscula. Prot otipo: // Declara ca o/deni ca o do namespace namespace nomeNamespace { // Declara ca o de vari avel/objeto Tipo nome; // Declara ca o de fun ca o retorno NomeFun ca o (par ametros); // Declara ca o de classe class CNomeClasse { // Declara ca o de atributo da classe Tipo nomeAtributo; // Declara ca o de m etodo da classe retorno NomeM etodo(par ametros); }; // Fim da classe } // Fim do namespace // Denindo fun co es de um namespace fora do namespace retorno nomeNamespace::NomeFun ca o(par ametros){...}; // Denindo m etodos de um namespace fora do namespace retorno nomeNamespace::CNomeClasse::NomeM etodo(par ametros){...}; Veja na Listagem 10.1 um exemplo de deni ca o e uso de um namespace. Observe que criamos tr es n umeros x: um global, x = 3, um dentro de main(), x = 2, e um dentro do namespace n1, x = 7. Tamb em criamos dentro do namespace n1 o namespace n2. Dentro da fun ca o main() mostramos como acessar o x global e do namespace, e como chamar a fun ca o Saida(). Observe que dentro de main(), x se refere ao x de main() e, dentro da fun ca o Saida(), x se refere ao x do namespace. Ou seja, cada fun ca o acessa o objeto que est a no seu escopo. Listing 10.1: Denindo e usando um namespace.
# include < iostream > int x = 3; namespace n1 { const int x = 7; void Saida () ; namespace n2 { int y = 4; } } // // // // // // // // // // Objeto x no escopo global Cria um bloco n a m e s p a c e com o nome n1 Inicio do bloco do n a m e s p a c e n1 Objeto x do n a m e s p a c e n1 Fun c~ a o Saida () do n a m e s p a c e n1 Cria n a m e s p a c e n2 a n i n h a d o dentro de n1 Inicio do bloco do n a m e s p a c e n2 Objeto y do n a m e s p a c e n1 :: n2 Fim do bloco do n a m e s p a c e n2 Fim do bloco do n a m e s p a c e n1

int main () {

// Fun c~ a o main ()

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

246

10.4. PROTOTIPO PARA DECLARAR E DEFINIR UM NAMESPACE

std :: cout << " \ nFun ca ~ o main () : " << std :: endl ; int x = 2; // Cria x no escopo de main () // U t i l i z a x = 2 std :: cout << " x = " << x << std :: endl ; // U t i l i z a x = 3 global std :: cout << " :: x = " << :: x << std :: endl ; // U t i l i z a x do n a m e s p a c e n1 , x = 7 std :: cout << " n1 :: x = " << n1 :: x << std :: endl ; // U t i l i z a y do n a m e s p a c e n1 :: n2 std :: cout << " n1 :: n2 :: y = " << n1 :: n2 :: y << std :: endl ; n1 :: Saida () ; // Chama fun c~ a o Saida () do n a m e s p a c e n1 return 0; } // D e f i n i c~ a o da fun c~ a o Saida () do n a m e s p a c e n1 void n1 :: Saida () { std :: cout << " \ nFun ca ~ o Saida () do namespace n1 " << " \ nx = " << x // x do n a m e s p a c e << " \ n :: x = " << :: x // x global << " \ nn2 :: y = " << n2 :: y << std :: endl ; } Fun ca ~ o main () : x = 2 :: x = 3 n1 :: x = 7 n1 :: n2 :: y = 4 Fun ca ~ o Sa da () do namespace n1 x = 7 :: x = 3 n2 :: y = 4

O exemplo da Listagem 10.2 mostra o uso de using para colocar duas fun co es de diferentes escopos no escopo de main(). Quando chamamos F(2.33); (linha 25), e executada a fun ca o global (que recebe um int) e n ao a do namespace. Isto ocorre poque a fun ca o F(double) do namespace n ao est a no escopo da fun ca o global. Para colocar as duas fun co es no mesmo escopo usamos using. Quando compilamos um programa o compilador pode emitir mensagens de warning ou cuidado, indicando que estamos utilizando algum recurso da linguagem de forma incorreta. Ao compilar a Listagem 10.2, aparece a mensagem de warning ao converter um float para int na linha 25. Listing 10.2: Usando using para colocar fun co es no mesmo escopo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # include < iostream > void F ( int i ) // Fun c~ a o global { std :: cout << " Global : void F ( int i ) " << std :: endl ; } namespace M e u N a m e s p a c e // Cria um n a m e s p a c e M e u N a m e s p a c e { // Fun c~ a o F ( double ) do n a m e s p a c e M e u N a m e s p a c e . void F ( double d ) { std :: cout << " namespace M e u N a m e s p a c e : void F ( double d ) " << std :: endl ;} // Fun c~ a o G () do n a m e s p a c e M e u N a m e s p a c e . void G () { std :: cout << " namespace M e u N a m e s p a c e : void G () " << std :: endl ; F (3) ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

10.5. NAMESPACES ANONIMOS


16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 } } // Cria um apelido , um s i n ^ o n i m o para M e u N a m e s p a c e com nome nm namespace mn = M e u N a m e s p a c e ; int main () { F (1) ; F (2.33) ; mn :: F (1) ; mn :: F (2.33) ; mn :: G () ;

247

// // // // // // // // // //

Chama Chama Chama Chama Chama

fun c~ ao fun c~ ao fun c~ ao fun c~ ao fun c~ ao

F ( int ) global F ( int ) global F ( double ) do n a m e s p a c e F ( double ) do n a m e s p a c e G , que chama fun c~ a o F do n a m e s p a c e

using mn :: F ; using :: F ; F (1) ; F (2.33) ; return 0; }

Posso c o l o c a r as f u n c~ o e s no escopo de main () Coloca mn :: F ( double ) no escopo de main () Coloca F ( int ) no escopo de main () Chama fun c~ a o F ( int ) global Chama fun c~ a o F ( double ) do n a m e s p a c e

[ b u e n o @ l d s c 0 5 ] $ g ++ namespace . cpp namespace . cpp : In function int main () : namespace . cpp :25: warning : passing double for argument 1 to void F ( int ) [ b u e n o @ l d s c 0 5 ] $ ./ a . out Global : void F ( int i ) Global : void F ( int i ) namespace N : void F ( double namespace N : void F ( double namespace N : void G () namespace N : void F ( double Global : void F ( int i ) namespace N : void F ( double

d) d) d) d)

10.5

Namespaces an onimos

Um namespace pode ser an onimo, isto e, sem nome. Neste caso, vari aveis, fun co es, objetos e classes denidas dentro do namespace est ao no escopo em que o namespace e denido. No exemplo a seguir criamos um namespace an onimo. Observe que a vari avel x pode ser acessada diretamente. Exemplo: namespace // Cria namespace an^ onimo { int x = 0; // Se comporta como uma vari avel global void f(); } int main() { cout < < x < < endl; // Acessa x do namespace an^ onimo diretamente } As vari aveis criadas dentro de um namespace an onimo s o podem ser utilizadas no arquivo em que o namespace foi denido. Funciona da mesma maneira que vari aveis est aticas globais (veja Se ca o B.4). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

248

2 10.6. NAMESPACES USO AVANCADO

Programadores de C costumam usar static para indicar que determinada vari avel tem escopo de arquivo. O mesmo pode ser feito com C++, mas e melhor usar um namespace an onimo, porque este pode conter classes, enumera co es e templates, enquanto static suporta apenas fun co es e objetos [Lischner, 2003].

10.6

Namespaces uso avan cado2

Veremos nesta se ca o o uso avan cado dos namespaces: Como compor (Se ca o 10.6.1), como criar namespaces aninhados (Se ca o 10.6.2) e como usar vari aveis est aticas em um namespace (Se ca o 10.6.3).

10.6.1

Compondo namespace com using2

Voc e pode compor dois ou mais namespaces. No exemplo a seguir o namespace minhalib inclui os namespace lib1 e lib2. As linhas using namespace lib1; e using namespace lib2; fazem com que lib1 e lib2 quem no mesmo escopo da minhalib. Exemplo: // Compondo namespaces namespace lib1{...}; namespace lib2{...}; namespace minhalib { using namespace lib1; using namespace lib2; ... }

10.6.2

Namespace aninhado2

Namespaces podem ser aninhados (como classes aninhadas, veja Se ca o 11.5.4). Veja na Listagem 10.1 um exemplo.

10.6.3

Usando vari aveis est aticas em um namespace2


Listing 10.3: Usando vari aveis est aticas em um namespace.

Vari aveis est aticas denidas em um namespace precisam ser denidas. Veja Listagem 10.3.
// Uso de v a r i avel est a t i c a em um n a m e s p a c e # include < iostream > namespace m { struct S { static int i ; }; } // Define o a t r i b u t o e s t a t i c o i , da e s t r u t u r a S , do n a m e s p a c e m int m :: S :: i = 1; int main () { // usa a t r i b u t o e s t a t i c o do n a m e s p a c e m , da e s t r u t u r a S std :: cout << m :: S :: i << std :: endl ; return 0; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

10.7. SENTENCAS PARA NAMESPACE


bash -3.1 $ g ++ namespace - e - static . cpp bash -3.1 $ ./ a . out 1

249

10.7

Senten cas para namespace

Por conven ca o o nome de um pacote/namespace inicia com letra min uscula. Se uma vari avel ou fun ca o e declarada com o mesmo nome de um namespace, ent ao, a vari avel declarada oculta o namespace. O acesso ao namespace deve ser feito usando o operador de resolu ca o de escopo. Fun co es denidas dentro do namespace s ao vis veis entre si (veja no exemplo da Listagem 10.2 as fun co es F() e G()). Em arquivos de cabe calho (*.h) nunca utilize using namespace std;. Por exemplo: para acessar cout nos arquivos de cabe calho use std::cout. Isto se justica, pois, se colocarmos using namespace std; no in cio do arquivo que declara a classe, a inclus ao de um objeto global com o mesmo nome de um objeto do namespace cria uma ambig uidade. Pode-se criar um sin onimo para um namespace. No exemplo a seguir, ml e um apelido para Minha_lib_versao_x_y_z (veja Listagem 10.2): Exemplo: namespace ml = Minha_lib_versao_x_y_z; Utilize um nome de namespace grande e depois crie um sin onimo para ele. Use namespace para grupos de classes que formam um assunto, classes que representam um conceito em comum. A declara ca o using e transitiva, isto e, se o namespace A usa o namespace B, e o namespace B usa o namespace C, um nome acess vel em A tamb em e acess vel em C, [Lischner, 2003]. Um namespace pode ser denido dentro de outro namespace, mas n ao pode ser denido dentro de um bloco (reveja Se ca o 10.6.2 e Listagem 10.1). Um namespace pode ser criado sem um nome namespace an onimo (veja Se ca o 10.5). Exemplo: namespace {...} Segundo [Lischner, 2003], namespaces de C++ s ao semelhantes a namespaces de Java. A diferen ca e que em Java, duas classes do mesmo pacote (namespace) t em privil egios de acesso, o que n ao ocorre em C++. Quando declaramos uma classe dentro de um namespace, todos os atributos, m etodos e operadores devem ser declarados dentro do mesmo namespace. Um namespace n ao tem custo computacional. 2 A senten ca using namespace std; e v alida no escopo em que foi denida, e s o deve ser utilizada em programas pequenos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

250

10.8. RESUMO DO CAP ITULO

10.8

Resumo do cap tulo

Neste cap tulo aprendemos que o conceito de namespace existe para resolver o problema da duplica ca o de nomes por meio da cria ca o de escopos adicionais. Vimos que podemos usar os objetos da biblioteca-padr ao diretamente, basta incluir a declara ca o using namespace std; no in cio do programa. Aprendemos a criar nossos pr oprios namespaces, de forma que podemos usar namespaces para criar o conceito de assunto/pacotes em C++. Aprendemos que um namespace e um escopo, e as fun co es, vari aveis e classes denidas dentro do namespace est ao no escopo do namespace. A deni ca o do escopo e da visibilidade dos objetos em C++ ser a vista na Se ca o 11.2 e no Ap endice B.4. Vimos ainda que a palavra-chave using pode ser utilizada para colocar objetos e fun co es de diferentes escopos em um mesmo escopo. Aprendemos que podemos criar um namespace an onimo, podemos compor namespaces e criar namespaces aninhados. No pr oximo cap tulo, Cap tulo 11 Classe, veremos como implementar o conceito de classes em C++.

10.9

Exerc cios

1. Diga com suas palavras o que e um namespace e quais suas vantagens. 2. Monte os diagramas UML para a Listagem 10.1, acrescentando os pacotes necess arios. 3. Modique a Listagem 10.1, acrescentando um nome longo para n1 e n2, e, em seguida, denindo n1 e n2 como sin onimos. 4. Acrescente o conceito de namespace nas listagens 9.1, 9.2 e 9.6. 5. Modique a Listagem 10.2, acrescentando um namespace n3. 6. Adicione uma vari avel static float j na Listagem 10.3.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 11

Classes
Vimos, no Cap tulo 3 Conceitos b asicos de orienta ca o a objeto, que a classe e a unidade de dentro da classe que declaramos os atributos, encapsulamento dos atributos e dos m etodos. E os m etodos e seus controles de acesso. Neste cap tulo veremos o prot otipo para declarar e denir uma classe em C++ (Se ca o 11.1). Veremos como utilizar as palavras-chave public, protected e private para denir a visibilidade (acesso) dos atributos e m etodos da classe (Se ca o 11.2), bem como a rela ca o entre classes e escopo (Se ca o 11.3) e o uso de diretrizes de pr e-processador com classes (Se ca o 11.4). Veremos ainda o uso avan cado de classes (Se ca o 11.5), as classes abstratas (Se ca o 11.5.1), as classes de interface (Se ca o 11.5.2), o encapsulamento e a robustez de c odigo (Se ca o 11.5.3), as classes aninhadas (Se ca o 11.5.4), as classes do tipo POD (Se ca o 11.5.5) e as classes do tipo trivial (Se ca o 11.5.6).

11.1

Prot otipo para declarar e denir classes

Uma classe e um conjunto de atributos (vari aveis ou objetos) reunidos com um conjunto de m etodos (fun co es). Os atributos e m etodos inclu dos na classe s ao aqueles que fazem sentido ` a classe; s ao chamados ainda de elementos da classe. Quando voc e cria uma classe, est a denindo um novo tipo trata-se de um tipo do usu ario. Voc e deve incluir na documenta ca o do programa o conceito e a forma de uso do novo tipo. Um mesmo nome n ao pode ser dado a um m etodo e a um atributo. Para identicar as classes e seus relacionamentos, fa ca associa co es diretas com conceitos do mundo real. Veja exemplo a seguir: Exemplo: Uma classe edif cio, janela, porta etc. Ao criar suas classes, d e a elas um formato simples. Isto pode ser feito dividindo uma classe grande e complexa em classes menores. Crie classes pequenas para realizar tarefas pequenas. Note que o uso de classes extensas torna sua manuten ca o mais complexa. A classe n ao e um objeto, e uma descri ca o do objeto (deni ca o da forma e do conte udo do objeto). 251

252 11.2. ENCAPSULAMENTO EM C++ UTILIZANDO O ESPECIFICADOR DE ACESSO A declara ca o de uma classe dene um escopo, todos os membros da classe est ao no escopo da classe. Adicionalmente, todos os membros de uma classe t em de ser declarados em seu interior. Veja a seguir o prot otipo para declara ca o e deni ca o de uma classe em C++. Verique que existem diferentes tipos de atributos e de m etodos. Ao lado do prot otipo, h a um coment ario informando a se ca o em que o mesmo ser a apresentado. Prot otipo: // Declara ca o, diz que existe a classe class CNomeClasse; // Deni ca o, inclui o corpo da classe class CNomeClasse { // Especicadores de acesso public: // Acesso p ublico, veja se ca o 11.2 protected: // Acesso protegido, veja se ca o 11.2 private: // Acesso privado, veja se ca o 11.2 // Atributos Tipo nome; // Atributos de objeto, veja se ca o 12.2 static Tipo nome; // Atributos de classe, est aticos - static , veja se ca o 12.3, const Tipo nome; // Atributos constantes - const , veja se ca o 12.4 mutable Tipo nome; // Atributos mutantes - mutable , veja se ca o 12.5.1 volatile Tipo nome; // Atributos vol ateis - volatile , veja se ca o 12.5.2 // M etodos Tipo M etodo(par ametros); // M etodos normais, veja se ca o 13.7 Tipo M etodo(par ametros) const ; // M etodos constantes - const , veja se ca o 13.8 static Tipo M etodo(par ametros); // M etodos est aticos - static , veja se ca o 13.9 inline Tipo M etodo(par ametros); // M etodos em linha - inline , veja se ca o 13.10 virtual Tipo M etodo(par ametros); // M etodos virtuais - virtual , veja se ca o 19.2 virtual Tipo M etodo(par ametros)=0; // M etodos virtuais puros, veja se ca o 19.4 }; // Encerra a deni ca o da classe importante observar a presen E ca de (;) no nal do bloco que declara a classe.

11.2

Encapsulamento em C++ utilizando o especicador de acesso

Para a an alise orientada a objeto, encapsulamento e o ato de esconder do usu ario informa co es que n ao s ao de seu interesse. Assim, o encapsulamento envolve a separa ca o dos elementos vis veis de um objeto dos invis veis. Reveja as se co es 3.1, 3.2 e a Figura 3.2. Lembre-se que a vantagem do uso do encapsulamento surge quando h a a necessidade de se modicar um programa ou biblioteca existente. Para implementar o conceito de encapsulamento (ou ocultamento de informa ca o), C++ oferece as palavras-chave public, protected e private. public Signica que o atributo ou m etodo faz parte da interface do objeto, podendo ser acessado de qualquer local. Veremos exemplos nas listagens 13.1, 13.2, 13.3. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

11.3. CLASSES E ESCOPO

253

protected Signica que o atributo ou m etodo est a protegido de acesso externo. S o pode ser acessado pelos m etodos da classe, pelos m etodos das classes-derivadas (classes herdeiras) e por fun co es amigas friend. Veremos exemplos na Listagem 13.5. private Signica que o atributo ou m etodo s o pode ser acessado pelos m etodos da classe (m etodos internos da classe) e por fun co es amigas friend. Veremos exemplos nas listagens 13.2, 13.3. Para aumentar o encapsulamento da classe, declare tudo como privado. S o deixe como p ublico o que for essencial e zer parte da interface da classe. Evite atributos protegidos, uma vez que eles podem ser utilizados em diversas classes derivadas, sendo dif cil identicar o impacto de mudan cas nestes atributos. A utiliza ca o de public, protected e private ser a esclarecida por meio dos exemplos e listagens apresentados ao longo do livro.

11.3

Classes e escopo

Vimos que um escopo e uma regi ao de c odigo que cont em declara co es, que cada declara ca o adiciona um nome ao escopo, e que o uso desses nomes deve ser resolvido pelo compilador. Conclui-se, ent ao, que n ao podemos ter dois nomes iguais no mesmo escopo, pois isso causa uma ambig uidade. Uma classe dene um escopo. Todo membro (atributo/m etodo) declarado dentro da classe est a no escopo da classe. Para acessar os atributos declarados em uma classe precisamos ter um objeto. Vimos na Se ca o 11.2 que s o podemos acessar externamente os membros p ublicos da classe, ou seja, o membro deve ser vis vel. 2 Atributos de classe, isto e, atributos declarados com static pertencem ` a classe e n ao ao objeto, podendo ser acessados sem um objeto se forem p ublicos. 2 Uma fun ca o friend n ao pertence ao escopo da classe. A palavra-chave friend apenas indica que a fun ca o e amiga. Veremos fun co es e m etodos amigos no Cap tulo 20 Friend.

11.4

Classes e diretrizes de pr e-processador

Em nossos programas costumamos incluir algumas bibliotecas, como a <iostream>. Se tivermos um programa com muitos arquivos, a biblioteca <iostream> pode ser inclu da mais de uma vez. Para evitar que a <iostream> seja inclu da mais de uma vez na mesma unidade de tradu ca o, no in cio do arquivo <iostream> est ao presentes as seguintes diretrizes de pr eprocessador. Exemplo: #ifndef __IOSTREAM // In cio do bloco #ifndef #define __IOSTREAM // Seq u^ encia da biblioteca.... Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

254 #include <ostream> #include <istream> ... #endif

2 11.5. CLASSES USO AVANCADO

// Fim do bloco

As instru co es apresentadas realizam os seguintes passos: primeiro vericam se a vari avel __IOSTREAM j a foi denida; se ainda n ao foi, ela e denida e, em seguida, as instru co es compilam a seq u encia da biblioteca. Se a vari avel __IOSTREAM j a foi denida, todo o restante do bloco e pulado. Observe que com essas instru co es a Seq u encia da biblioteca.... s o e pr e-processada uma u nica vez. Da mesma forma, nossas pr oprias classes tamb em devem utilizar as diretrizes de pr eprocesssador para evitar que a classe seja redenida. Veja a seguir como implementar a classe CEndereco ilustrada na Figura 12.1. Observe que basta iniciar o arquivo com as linhas #ifndef CEndereco e #dene CEndereco, e terminar o arquivo com a linha #endif. Exemplo: #ifndef __CEndereco #define __CEndereco #include <string> class CEndereco { protected: int numero; string rua; public: int Numero(); string Rua(); }; #endif // // // // // // // In cio do bloco __CEndereco Define vari avel __CEndereco Classe string da biblioteca padr~ ao Cria classe CEndereco Controle de acesso Acesso protegido Atributos

// Acesso p ublico // M etodos

// Fim do bloco __CEndereco

11.5

Classes Uso avan cado2

Veremos nesta se ca o o uso avan cado de classes em C++. Os conceitos aqui apresentados t em uma rela ca o direta com o conceito de m etodos virtuais, que ser a apresentado na Se ca o 19.2 e com o conceito de polimorsmo, que ser a apresentado na Se ca o 19.3.

11.5.1

Classes abstratas2

M etodos virtuais s ao m etodos que t em seu endere co denido dinamicamente, ou seja, durante a execu ca o do programa. M etodos virtuais puros s ao m etodos que s ao declarados como virtuais na classe-base e que n ao s ao implementados (n ao s ao denidos). Eles ser ao descritos na Se ca o 19.4. Uma classe que cont em m etodos virtuais n ao implementados e uma classe abstrata, n ao podendo ser utilizada para criar objetos. Exemplo: class CNomeClasse { // M etodo virtual puro virtual void NomeM etodo(parametro) = 0; }; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

2 11.5. CLASSES USO AVANCADO

255

Se n ao podemos criar um objeto, ent ao para que serve uma classe abstrata? Embora n ao possamos criar objetos, podemos criar ponteiros para classes abstratas. Normalmente usamos um ponteiro para classe-base da hierarquia para acessar os diferentes objetos criados. Veremos exemplos na Se ca o 19.3.

11.5.2

Classes de interface2

Segundo [Parga, 2006], Um dos desaos de se trabalhar com POO e criar uma rela ca o um-para-um entre os elementos do problema do mundo real e os elementos da solu ca o onde est a sendo modelado o problema, ou seja, o desao e identicar com clareza os objetos reais, dando-lhes limites claros, al em de denir de forma simples sua interface de acesso. O mesmo autor arma ainda que a interface s o estabelece que pedidos possam ser feitos a um objeto. A codica ca o necess aria para satisfazer cada pedido deve estar denida na classe que implementa essa interface. Esta segunda frase destaca que podemos ter duas classes: a primeira descreve a interface de acesso ( e uma classe abstrata); a segunda implementa de fato as funcionalidades da classe. Em C++ voc e pode criar uma classe de interface, basta que ela s o tenha m etodos p ublicos vazios. Observe que a classe n ao tem atributos, apenas m etodos que informam a forma de acesso ` a classe. Veja a seguir um exemplo de classe de interface. Coloquei a inicial I para indicar que a classe e uma classe de interface. Lembre-se que usamos a inicial C para indicar que se trata de uma classe do usu ario. Observe que usamos o conceito de m etodos virtuais puros, veja Se ca o 19.2. class ICPessoa { public: // Acesso p ublico ICPessoa(){}; virtual ~ICPessoa(){}; virtual std::string Nome() virtual int Idade() virtual std::string Sexo() virtual CEndereco Endereco() };

const const const const

= = = =

0; 0; 0; 0;

Note a diferen ca entre classe abstrata e classe de interface. A classe abstrata pode ter atributos e m etodos normais; j a a classe de interface s o deve ter m etodos p ublicos.

11.5.3

Classes encapsulamento e robustes de c odigo2

O conceito de encapsulamento e essencial ao desenvolvimento de softwares robustos e seguros e envolve aspectos como: ocultar os membros internos; garantir que altera co es nos membros internos n ao afetem a interface do objeto; proteger os membros internos de acessos n ao-autorizados. Outro mecanismo u til para garantir maior robustez e denir a interface da classe apenas com m etodos normais, n ao virtuais. Esta t ecnica e conhecida como NVI NonVirtual Interface , [Sutter, 2006]. Os mesmos chamariam m etodos virtuais, veja o exemplo: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

256

2 11.5. CLASSES USO AVANCADO

Exemplo: class CNome{ public: // M etodos p ublicos n~ ao virtuais void M1() { return M1_v(); }; void M2() { return M2_v(); }; private: virtual void M1_v(); // M etodos privados virtuais virtual void M2_v(); }; Isto garante maior robustez, pois a interface permanece xa, enquanto podemos redeclarar e redenir os m etodos virtuais mais a ` vontade. Por exemplo, poder amos reescrever a classe da seguinte forma: Exemplo: class CNome{ public: void M1() { M1_v_preProcessamento(); M1_v(); M1_v_posProcessamento(); }; void M2() { M2_v(); }; private: virtual void M1_v_preProcessamento(); virtual void M1_v(); virtual void M1_v_posProcessamento(); virtual void M2_v(); }; Note que a interface de M1() n ao foi mudada, mas sua implementa ca o sim. Inclu mos os m etodos virtuais virtual void M1_v_preProcessamento(); e virtual void M1_v_posProcessamento();.

11.5.4

Classes aninhadas3

Podemos declarar classes aninhadas (classes dentro de classes). Veja no exemplo a seguir que a classe CNomeClasse tem uma classe aninhada CNomeClasseAninhada. Veja exemplo na Listagem G.1. Exemplo: class CNomeClasse { public: int x; // Classe aninhada class CNomeClasseAninhada { int y; }; }; Nota: o comportamento de classes aninhadas em C++ e diferente do encontrado em Java. Uma classe aninhada em C++ e como um membro static em Java. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

2 11.5. CLASSES USO AVANCADO

257

11.5.5

Classes do tipo POD3

Um POD Plain Old Data e um tipo especial de classe. Veja a seguir suas caracter sticas: Uma classe POD e compat vel com estruturas de C. Todos os seus membros de dados s ao armazenados de forma cont gua. Uma classe POD pode ser copiada usando-se fun co es da biblioteca-padr ao de C, como memcpy(). A vantagem de uma classe POD e que a mesma pode ser manipulada como uma estrutura. Por exemplo, o uso de memcpy() garante melhor desempenho na c opia de uma estrutura. Segundo [Lischner, 2003] uma classe do tipo POD n ao pode ter: construtores e destrutores; operador de c opia; m etodos virtuais; classes-base; membros privados ou protegidos n ao est aticos; membros de dados n ao est aticos que s ao refer encias.

11.5.6

Classes do tipo trivial3

Uma classe trivial e um tipo especial de classe. Segundo [Lischner, 2003] uma classe trivial n ao pode ter: construtores e destrutores; operador de c opia; m etodos virtuais; classes-base. Veja a seguir outras caracter sticas de uma classe trivial: Todas as classes-base de uma classe trivial devem ser triviais. Todos os membros n ao est aticos devem ser triviais. As classes triviais s ao importantes porque uni oes s o podem ter membros triviais. Veremos uni oes na Se ca o G.2. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

258

11.6. SENTENCAS PARA CLASSES

11.6

Senten cas para classes

Os atributos que comp oem a classe podem ser de diferentes tipos. No exemplo, da classe CEndereco, utilizam-se uma string e um int. Costumo adotar o seguinte padr ao para classes: primeiro coloco os atributos e m etodos p ublicos, depois os protegidos e, por m, os privados. Linguagens como Java e C# t em o conceito de classe de interface. 2 Uma classe-base imediata e chamada de clase-base direta. Uma classe-base n ao imediata e chamada ainda de classe ancestral. 2 Note que fun co es friend n ao est ao no escopo da classe. 2 Uma classe com pelo menos um m etodo virtual e uma classe polim orca. 2 Uma classe A qualquer n ao pode conter um objeto do tipo A, mas somente um ponteiro para A. Antes do nal da deni ca o de uma classe, seu nome s o pode ser utilizado se o tamanho da classe n ao for necess ario. 2 Lembre-se: uma classe do usu ario e um tipo novo e deve ter todos os elementos esperados, isto e, construtor/destrutor, construtor de c opia, operadores, m etodos de convers ao, atributos e m etodos. 2 Uma classe com atributos const ou refer encias t em de ter obrigatoriamente um construtor para inicializar esses atributos. Veja Se ca o 16.1. 2 Se um m etodo tem inicializadores, isto e, atributos com valores predenidos, estes devem car vis veis na classe (arquivo *.h), pois quem utiliza a classe olha o arquivo de cabe calho (*.h) e nem sempre tem acesso ao arquivo de implementa ca o (*.cpp). Veja Se ca o 13.6.4. 2 Note que uma classe de interface tamb em pode ser implementada utilizando heran cam ultipla. 3 Como um membro privado participa da pesquisa de resolu ca o do m etodo a ser executado, e vis vel nos arquivos em que foi inclu do, mas n ao pode ser chamado porque e privado, de modo que algumas chamadas podem se tornar inv alidas ou amb guas, mesmo que o m etodo nunca possa ser executado [Sutter, 2006]. Veja Se ca o 14.3.1. 3 Podemos ter classes locais, isto e, classes declaradas dentro de blocos, mas elas t em as seguintes restri co es [Lischner, 2003]: N ao podem ter membros est aticos. Todos os m etodos internos devem ser inline. Uma classe local n ao pode ser utilizada como argumento de um template. 3 O polimorrmo em tempo de compila ca o utilizando templates possibilita a quebra do conceito de encapsulamento e, portanto, deve ser evitado. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

11.7. RESUMO DO CAP ITULO

259

11.7

Resumo do cap tulo

Vimos e revimos alguns conceitos b asicos sobre classes e o prot otipo para declarar e denir uma classe em C++. Aprendemos a denir a visibilidade (encapsulamento) com o uso das palavras-chave public, protected e private. Vimos que C++ usa m etodos p ublicos e abstratos para criar classes de interface. Lembre-se: os m etodos abstratos s ao declarados mas n ao denidos. Aprendemos que os membros da classe est ao no escopo da classe. Aprendemos a evitar que um mesmo bloco com deni ca o de um namespace ou classe seja compilado duas vezes usando as diretrizes de pr e-processador #ifndef, #define e #endif. Aprendemos a diferenciar classes abstratas de classes de interface. Aprendemos que a deni ca o da interface de uma classe e extremamente importante, e um dos momentos cruciais no design de um sistema. Isto signica que deve-se dispender um bom tempo de an alise com a correta deni ca o da interface. Isto se justica, pois a redeni ca o da interface tem um custo elevado. Aprendemos a aumentar o encapsulamento das classes usando a t ecnica NVI (Se ca o 11.5.3). Finalmente, vimos como criar classes aninhadas, classes do tipo POD e classes triviais.

11.8

Exerc cios

1. Abra um editor UML (como umbrello ou vp), monte um diagrama de classes e, em seguida, gere o c odigo. Abra os arquivos gerados em um editor de texto e verique se os mesmos seguem o prot otipo denido neste cap tulo (Se ca o 11.1). 2. Baixe alguns programas em C++ na internet e veja se os mesmos seguem o prot otipo denido neste cap tulo (Se ca o 11.1). Observe que cada autor costuma ter um estilo um pouco diferente, mas a estrutura geral e a mesma. 3. D e uma olhada no estilo dos arquivos da biblioteca-padr ao (no GNU/Linux est ao em /usr/include/c++/vers ao, no Windows est ao instalados no diret orio do pacote de desenvolvimento). 4. D e exemplos de objetos com atributos e m etodos que devem ser p ublicos. Em seguida, indique atributos protegidos e privados. 5. Exponha com suas palavras o que e uma classe de interface. 6. Para que servem as classes triviais? 7. Neste momento voc e pode reler a Se ca o 6.11.3, senten cas para conseguir o reuso de classes. 8. Explique com suas palavras como funciona o escopo em uma classe. 9. Para que servem as classes abstratas? E as classes de interface? 10. O que s ao classes aninhadas? 11. O que signica POD? E NVI?

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

260

11.8. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 12

Atributos
Neste momento voc e pode reler a Se ca o 3.4, a qual apresenta o conceito de atributo. Veremos neste cap tulo o prot otipo para declarar e denir atributos em C++ (Se ca o 12.1), o que s ao atributos de objeto (Se ca o 12.2), atributos de classe static (Se ca o 12.3) e os atributos constantes const (Se ca o 12.4). Veremos ainda o uso avan cado dos atributos (Se ca o 12.5), os atributos mutantes mutable (Se ca o 12.5.1) e os atributos vol ateis volatile (Se ca o 12.5.2). Nota: exemplos completos de classes com atributos e m etodos ser ao apresentados no Cap tulo 13 M etodos.

12.1

Prot otipo para declarar e denir atributos

Em C++ um atributo pode ser um tipo predenido da linguagem, um tipo denido pelo programador ou um tipo denido em uma biblioteca externa, como a STL (veja Cap tulo 9 Tipos). Veja a seguir o prot otipo para declara ca o de um atributo normal, de um atributo de classe (ou est atico) e de atributos const, mutable e volatile. Ao lado do prot otipo est a o n umero da se ca o em que o mesmo ser a apresentado. Prot otipo: // Arquivo CNomeClasse.h class CNomeClasse { // Atributos Tipo nome; // Atributos de objeto, veja se ca o 12.2 static Tipo nome; // Atributos de classe, est aticos - static , veja se ca o 12.3, const Tipo nome; // Atributos constantes - const , veja se ca o 12.4 mutable Tipo nome; // Atributos mutantes - mutable , veja se ca o 12.5.1 volatile Tipo nome; // Atributos vol ateis - volatile , veja se ca o 12.5.2 }; // Arquivo CNomeClasse.cpp Tipo CNomeClasse::nomeA; // Deni ca o de atributo est atico 261

262

12.2. ATRIBUTOS DE OBJETO

12.2

Atributos de objeto

Um atributo de objeto e declarado dentro da classe sem a utiliza ca o do modicador de tipo static. Para criar um atributo de objeto, coloca-se o tipo seguido do nome do atributo. Exemplo: class CNomeClasse { public: int x; }; O exemplo da Listagem 12.1 ilustra a declara ca o, dentro da classe, de alguns atributos. O diagrama UML da classe CEndereco e da classe CTeste e ilustrado na Figura 12.1. No in cio do arquivo inclu mos as classes- padr ao de C++ que ser ao utilizadas e denimos o uso dos objetos no escopo da std. Criamos as classes CEndereco e CTeste. A classe CEndereco tem dois atributos: o primeiro e um n umero inteiro utilizado para armazenar o n umero da casa; o segundo e a string rua, utilizada para armazenar o nome da rua. Os m etodos Numero() e Rua() retornam, respectivamente, o n umero e nome da rua. Os m etodos ser ao apresentados no Cap tulo 13 M etodos. A segunda classe, CTeste, tem cinco atributos. Dois deles s ao tipos predenidos (int e float), o terceiro atributo, CEndereco, e um objeto da classe que denimos anteriormente. Temos ainda um atributo <string> e um atributo <vector>. Ou seja, a classe CTeste tem atributos de diversos tipos. Observe que dentro da classe CTeste, declaramos um objeto do tipo CEndereco. Os tipos ou classes denidas por n os passam a funcionar da mesma forma que os tipos predenidos da linguagem. Note que a classe <vector> e uma classe template, e que precisamos passar dentro de <> o tipo de objeto que ser a armazenado no vetor vd. No caso, vd armazenar a n umeros do tipo double. Dentro da fun ca o main(), criamos um objeto do tipo CTeste com nome obj. Em seguida, utilizamos os atributos denidos em CTeste, como x, nome e vd. Note que para acessar os atributos do objeto usa-se nomeObjeto.nomeAtributo (exemplo: obj.x = 3.1;). A linha obj.vd.push_back(34.5); e usada para adicionar no vetor vd o n umero 34.5. Veja na Figura 12.1 como ca um objeto do tipo CEndereco e CTeste na mem oria. Os m etodos ser ao descritos em detalhes no Cap tulo 13 M etodos. Listing 12.1: Usando atributos de objeto em uma classe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include < iostream > # include < string > # include < vector > using namespace std ; // // // // E n t r a d a e sa da de dados Classe string de C ++ C o n t a i n e r < vector > da stl E s t a m o s usando o n a m e s p a c e std

class CEndereco // Cria classe C E n d e r e c o { public : int numero ; // A t r i b u t o s string rua ; public : // M etodos int Numero () { return numero ; } string Rua () { return rua ; } }; class CTeste // Cria classe CTeste

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

12.3. ATRIBUTOS DE CLASSE STATIC


17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 { public : int contador ; float x ; CEndereco endereco ; string nome ; vector < double > vd ; };

263

// // // // //

int e um tipo pr e - d e f i n i d o de C ++ float e um tipo pr e - d e f i n i d o de C ++ C E n d e r e c o foi d e f i n i d o acima O tipo string e um tipo da biblioteca - padr~ ao O tipo vector e um tipo da biblioteca - padr~ ao

// Dentro da fun c~ a o main () cria e usa um objeto do tipo CTeste int main () { CTeste obj ; // Cria objeto do tipo CTeste com nome obj obj . x = 3.1; // A r m a z e n a o valor 3.1 em obj . x obj . endereco . rua = " Avenida Atlantida " ; obj . endereco . numero = 360; obj . nome = " Joao da Silva " ; // A r m a z e n a " jo~ a o " em obj . nome obj . vd . push_back (34.5) ; cout << " \ nobj . x = " << obj . x << " \ nobj . nome = " << obj . nome << " \ nendereco . rua = " << obj . endereco . rua << " \ nendereco . numero = " << obj . endereco . numero << " \ nobj . vd [0] = " << obj . vd [0] << endl ; return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ a . out obj . x = 3.1 obj . nome = Joao da Silva endereco . rua = Avenida Atlantida endereco . numero = 360 obj . vd [0] = 34.5

Figura 12.1: Como cam os objetos do tipo CTeste e CEndereco na mem oria.
UML Objeto do tipo CTeste na memria Objeto do tipo CEndereco na memria

CEndereco
+numero: int +rua: string +Numero(): int +Rua(): string

CTeste
+contador: int +x: float +endereco: CEndereco +nome: string +vd: vector<double> Inclui todo o vetor vd

Contador x endereco nome vd

numero rua

Atributo agregado O objeto CTeste "tem um" endereo

12.3

Atributos de classe static

Existem dois tipos de atributos dentro de uma classe: os atributos de objeto (individuais, s ao armazenados no objeto) e os atributos de classe (coletivos, s ao armazenados na classe). O objetivo dos atributos de classe e possibilitar o seu compartilhamento por todos os objetos criados. Outro objetivo dos membros est aticos em classes e eliminar o uso de vari aveis globais. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

264

12.3. ATRIBUTOS DE CLASSE STATIC

Para criar um atributo de classe, coloca-se a palavra-chave static seguida do tipo e do nome do atributo.

Exemplo: static int contador;

O exemplo a seguir ilustra a declara ca o e a deni ca o de atributos de classe (est aticos). O atributo mec e um atributo est atico.

Exemplo: #include "CEndereco.h" class CUniversidade { public: // Atributo de objeto, do tipo int, com nome numeroAlunos int numeroAlunos; // Atributo de objeto, do tipo CEndereco, com nome endereco CEndereco endereco; // Atributo de classe (static), do tipo string, com nome mec static string mec; }; string CUniversidade::mec = "Minist erio Educa c~ ao e Cultura"; int main() { // Cria dois objetos do tipo CUniversidade CUniversidade ufsc,unicamp; return 0; }

Observe que atributos est aticos precisam ser denidos fora da classe. Observe a forma da deni ca o.

// Tipo NomeClasse::nomeAtributo = valor; string CUniversidade::mec = "Minist erio Educa c~ ao e Cultura";

Veja na Figura 12.2 o diagrama UML da classe CUniversidade e como ca a mem oria para os objetos ufsc e unicamp. Observe que tanto o objeto ufsc quanto o objeto unicamp t em os atributos numeroAlunos e endereco, mas o atributo mec e armazenado na classe e compartilhado pelos dois objetos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

12.4. ATRIBUTOS CONSTANTES CONST

265

Figura 12.2: Como cam os objetos na mem oria quando a classe tem atributos est aticos.
Diagrama UML Objetos ufsc e unicamp na memria Memria do programa

CUniversidade
+mec: string +numeroAlunos: int +endereco: TEndereco Atributo esttico aparece sublinhado Atributo esttico armazenado na classe e compartilhado pelos objetos ufsc e unicamp. Objeto ufsc numeroAlunos endereco Objeto unicamp numeroAlunos endereco classe CUniversidade mec

Note que a altera ca o de um atributo est atico se reete em todas as inst ancias da classe. Se o atributo for est atico e p ublico, poder a ser acessado externamente sem um objeto. Basta passar o nome da classe, o operador de resolu ca o de escopo (::) e o nome do atributo. Exemplo: string orgao_regulador = CUniversidade::mec; Nota: atributos inteiros constantes e est aticos e enumera co es podem ser denidos dentro da classe. Exemplo: class CNomeClasse { static const int valor = 5; };

12.4

Atributos constantes const

O objetivo de um atributo const e fornecer ao objeto um atributo que ele poder a acessar, mas n ao poder a alterar, ou seja, e utilizado para cria ca o de atributos constantes (somente leitura). Um atributo const deve ser inicializado nos m etodos construtores da classe, n ao podendo mais ser alterado. Os m etodos construtores ser ao descritos na Se ca o 16.1, e o uso de atributos const na Se ca o 16.4. No exemplo a seguir, o atributo static const float pi; pertence ` a classe e n ao pode ser modicado. O atributo max pertence ao objeto, e inicializado no construtor da classe e n ao pode ser alterado ( e constante). Exemplo: class CMath { // Atributo est atico e constante, do tipo float, // com nome pi pertence a classe static const float pi; // Atributo normal e constante, do tipo int, // com nome max, pertence ao objeto Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

266

2 12.5. ATRIBUTOS USO AVANCADO

const int max; // Inicializa atributo max no m etodo construtor (detalhes na sec~ ao 16.4) CMath(int _max) : max(_max){}; }; // Inicializa atributo est atico const float CMath::pi = 3.141516; Veja outro exemplo na Listagem 13.3.

12.5

Atributos uso avan cado2

Veremos nesta se ca o o uso avan cado de atributos em C++. O que s ao os atributos mutantes mutable (Se ca o 12.5.1) e os atributos vol ateis volatile (Se ca o 12.5.2).

12.5.1

Atributos mutantes mutable2

Se uma classe tem um m etodo membro const, TipoDeRetorno NomeM etodo(par^ ametros) const; este n ao pode alterar os atributos da classe. Uma forma de contornar isto e denir o atributo como mutable. A palavra-chave mutable signica que o atributo pode mudar, mesmo que ele seja declarado como const. Membros mutable s ao usados em atributos que s ao logicamente const, mas que por motivos operacionais podem ser alterados [Lischner, 2003]. A utilidade real de mutable ocorre quando um m etodo utiliza diversos atributos do objeto, mas voc e quer ter certeza de que estes n ao ser ao alterados e por isso declara o m etodo como const. No entanto, por algum motivo, um determinado atributo precisa ser alterado, bastando para tal deni-lo com o qualicador mutable. Exemplo: class CTeste { public: mutable int x; void Altera_x() const; } A seguir, embora o m etodo Altera_x() seja const, x e alterado pois foi declarado como mutable. void CTeste::Altera_x()const { x++; }; A palavra-chave mutable pode ser utilizada em classes como uma alternativa ao const_cast<> (Se ca o 25.8). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

12.6. SENTENCAS PARA ATRIBUTOS

267

12.5.2

Atributos vol ateis volatile3

A palavra-chave volatile e utilizada para dar a um atributo o status de volatile. Este tipo de atributo pode mudar de forma inesperada. volatile e utilizado na programa ca o paralela com threads. Veja exemplos de uso de volatile no Cap tulo ?? Introdu ca o ao processamento paralelo com m ultiplas threads. Veremos exemplo na Listagem ??.

12.6

Senten cas para atributos

Observe que voc e pode combinar alguns qualicadores e um especicador. Veja no exemplo a seguir a utiliza ca o dos qualicadores const e volatile e do especicador int. Exemplo: int x; const int y; const volatile int x; Lembre-se: os atributos devem ser, na medida do poss vel, sempre privados e devem ser acessados usando m etodos p ublicos. Desta forma o acesso pelos clientes e uniforme. Uma das vantagens desta t ecnica e poder substituir os m etodos void NomeAtributo() por vers oes que, al em de retornar/setar o atributo, realizam alguma opera ca o adicional. No exemplo a seguir, quando mudamos o n umero de intervalos, nx, devemos recalcular dx, considerando os intervalos de integra ca o xmax e xmin. Exemplo: // Cria atributo nx int nx; // Seta novo valor para nx, e j a atualiza dx void Nx(int _nx) { nx = _nx; dx = (xmax - xmin) / nx; }; // Obt em valor de nx int Nx() { return nx; }; O uso de m etodos para acessar os atributos da classe garante a invari ancia da classe. Membros est aticos podem ser utilizados para compartilhar atributos entre objetos da mesma classe. Se o atributo for o mesmo para todas as classes da hierarquia, use static. Em alguns casos, mas n ao sempre, o uso de const faz com que o programa que mais r apido. Como o uso de const aumenta a seguran ca do programa, use e abuse de const. Para maiores detalhes veja [Sutter, 2006]. 2 Se o atributo for const, este n ao muda. Como ele n ao muda seu valor, deve ser denido no construtor. 2 Lembre-se que a declara ca o const n ao garante totalmente que o atributo seja const, pois podemos usar const_cast<>, mutable ou volatile para mudar um atributo const. 2 Um objeto est atico denido em um m etodo e criado na primeira execu ca o do m etodo e destru do no nal da execu ca o do programa. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

268 Exemplo int M etodo() { static int x = 0; ... return x; } 3 Uma classe local n ao pode conter membros est aticos.

12.7. RESUMO DO CAP ITULO

12.7

Resumo do cap tulo

Vimos o conceito de atributos na Se ca o 3.4, e, neste cap tulo, aprendemos a implementar diferentes tipos de atributos com C++. Aprendemos a declarar e denir atributos na Se ca o 12.1. Vimos que na maioria dos casos trabalharemos com atributos de objeto, mas, quando necess ario, podemos usar os atributos de classe (declarados com static). Aprendemos que podemos declarar dentro da classe atributos const, mutable e volatile, sendo que const e mais utilizado. Lembre-se que um const e um atributo que vai ser inicializado na constru ca o do objeto e que vai se manter constante. No pr oximo cap tulo, Cap tulo 13 M etodos, veremos na pr atica v arios exemplos de classes. Veremos como inicializar os atributos no construtor na Se ca o 16.4 e a ordem de constru ca o dos atributos de um objeto na Se ca o 16.6.1.

12.8

Exerc cios

1. Na Listagem 12.1 use o operador sizeof() para obter o tamanho dos objetos CEndereco e CTeste. 2. Monte um exemplo que inclua atributos normais, est aticos e const. 3. Construa uma classe com atributos const (Se ca o 12.4).

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 13

M etodos
Vimos na Se ca o 3.5 o conceito de m etodos. Neste cap tulo mostraremos como implementar o conceito de m etodos em C++. Veremos uma introdu ca o aos m etodos de C++ (Se ca o 13.1), o prot otipo para declarar, denir e utilizar m etodos em uma classe (Se ca o 13.2), os detalhes da declara ca o (Se ca o 13.3), deni ca o (Se ca o 13.4) e retorno dos m etodos (Se ca o 13.5). Al em disso, veremos como funciona a passagem de par ametros (Se ca o 13.6), por c opia (Se c ao 13.6.1), por refer encia (Se ca o 13.6.2), por ponteiro (Se ca o 13.6.2) e o uso de par ametros predenidos (Se ca o 13.6.4). Veremos tamb em o que s ao os m etodos normais (Se ca o 13.7), os m etodos constantes const (Se ca o 13.8) e os m etodos est aticos static (Se ca o 13.9), al em de aprendermos como otimizar o programa utilizando os m etodos em linha inline (Se ca o 13.10). Por m, veremos links para se co es em que trataremos do uso avan cado de m etodos e algumas senten cas u teis. Nota: neste momento voc e pode reler a Se ca o 6.11.4, senten cas para conseguir o reuso de m etodos e para construir m etodos robustos.

13.1

Introdu c ao aos m etodos de C++

O leitor mais atento deve ter percebido que o que estamos fazendo e denir um conjunto de ferramentas relacionadas ao uso dos objetos. Imagine o objeto como sendo uma caixa, onde atributos/propriedades podem ser armazenados. Os m etodos s ao funcionalidades que podemos realizar com nossa caixa. Imagine que temos uma caixa com bolinhas de gude, de todos os tipos e cores. As bolinhas de gude s ao atributos do tipo todo parte do objeto caixa. Ou seja, voc e sabe que uma bolinha de gude n ao e uma caixa, mas que uma caixa pode ter bolinhas de gude. A pergunta e: voc e deixaria qualquer um mexer em suas bolinhas de gude? Provavelmente muito prov n ao. E avel que voc e queira dividir sua caixa em tr es partes. Na primeira divis ao, p ublica, voc e coloca as bolinhas de gude que qualquer um poder a acessar. Na segunda divis ao, protegida, voc e coloca bolinhas especiais, que somente voc e e seus lhos poder ao mexer. Finalmente, em uma terceira divis ao, voc e vai colocar aquelas bolinhas especiais, que somente voc e ter a acesso. Esta divis ao e bastante pr oxima de nossa realidade, de nosso dia-a-dia. A mesma e implementada em C++ com os especicadores de controle de acesso public, protected e private. Vamos a um outro exemplo, uma pessoa. Uma pessoa tem atributos normais, que mudam com o tempo. Como exemplo a idade, o peso. Tamb em temos atributos que s ao constantes, n ao mudam. Como exemplo, o sexo e a data de nascimento, os quais s ao denidos quando 269

270

13.2. PROTOTIPO PARA DECLARAR E DEFINIR METODOS

o objeto tem origem e n ao muda nunca mais. Finalmente, um grupo de irm aos tem algumas caracter sticas em comum, compartilhadas. Como exemplo, o sobrenome e o nome do planeta em que vivemos (nosso programa s o atende aos terr aqueos). Veremos em nossos exemplos que esses conceitos da vida real s ao implementados em C++ com os atributos normais (peso), const (data de nascimento, nome dos pais) e static (sobrenome, planeta em que vivem). Enm, os conceitos j a existem. Precisamos usar os mecanismos da linguagem C++ para informar o compilador que o objeto tem um determinado comportamento. Isto e feito com o uso das palavras-chave public, protected, private, const, static etc.

13.2

Prot otipo para declarar e denir m etodos

Vimos anteriormente os conceitos de declara ca o (Se ca o 8.4) e deni ca o (Se ca o 8.5). Para m etodos a declara ca o informa que o m etodo existe (sua assinatura); j a sua deni ca o reserva espa co de mem oria para o c odigo do m etodo. A rela ca o entre a declara ca o e a deni ca o e dada pela assinatura do m etodo. Veja a seguir o prot otipo para declara ca o de um m etodo. Os itens dentro de [] s ao opcionais. Cada um desses itens ser a explicado neste ou nos pr oximos cap tulos. Prot otipo: [Pr e-qualicador] TipoRetorno NomeM etodo([Tipo Par ametro,...]) [P os-qualicador] Pr e-qualicador inline , static , extern , explicit , virtual , friend TipoRetorno void, bool , char , short , int , long , float , double , tipos do usu ario, tipos de bibliotecas externas,... NomeM etodo Nome do m etodo denido pelo programador (Tipo Par ametro,...) Tipo e nome de cada par ametro [na declara ca o o nome e opcional, na deni ca o e obrigat orio], o tipo pode incluir: void, bool , char , short , int , long , float , double , tipos do usu ario, tipos de bibliotecas externas,... P os-qualicador const , volatile , [lista de exce co es que podem ser lan cadas] Veja a seguir o prot otipo para declarar e denir os m etodos de uma classe. Observe que os m etodos s ao declarados dentro da classe (no arquivo CNomeClasse.h) e denidos fora da classe (no arquivo CNomeClasse.cpp), com exce ca o dos m etodos inline, os quais podem ser declarados e denidos dentro da classe. Veja ainda que a declara ca o dos m etodos normais, est aticos, em linha e virtuais e diferente, mas a deni ca o e igual. A deni ca o do m etodo const inclui a palavra-chave const. Ao lado do prot otipo do m etodo colocamos o n umero da se ca o em que o mesmo ser a apresentado. Prot otipo: // Arquivo CNomeClasse.h class CNomeClasse { Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

DE UM METODO 13.3. DECLARAC AO // Declara ca o de M etodos Tipo M etodo(par ametros); Tipo M etodo(par ametros) const ; static Tipo M etodo(par ametros); inline Tipo M etodo(par ametros); virtual Tipo M etodo(par ametros); virtual Tipo M etodo(par ametros)=0;

271

// M etodos normais, veja se ca o 13.7 // M etodos constantes - const , veja se ca o 13.8 // M etodos est aticos - static , veja se ca o 13.9 // M etodos em linha - inline , veja se ca o 13.10 // M etodos virtuais - virtual , veja se ca o 19.2 // M etodos virtuais puros, veja se ca o 19.4

// M etodo inline impl cito, veja se ca o 13.10 Tipo M etodo(par ametros) { ... Implementa ca o do m etodo ... return(Tipo); } }; // Fim da declara ca o da classe Prot otipo: // Arquivo CNomeClasse.cpp #include CNomeClasse.h // Deni ca o de um m etodo da classe Tipo CNomeClasse::M etodo(par ametros) { ... Implementa ca o do m etodo ... return(Tipo); } // Deni ca o de um m etodo const da classe Tipo CNomeClasse::M etodo(par ametros) const { ... Implementa ca o do m etodo ... return(Tipo); } Nota: o acesso aos m etodos da classe pode ser modicado com as palavras-chave public, protect e private (veja Se ca o 11.2). Veja na Se ca o 10.4 o prot otipo para declarar e denir um m etodo em uma classe denida dentro de um namespace. Veremos a seguir cada uma das tarefas realizadas por um m etodo. Al em disso, veremos como declarar e denir um m etodo, seu retorno e seus par ametros.

13.3

Declara c ao de um m etodo

Um m etodo recebe como par ametros de entrada um conjunto de objetos, realiza determinada seq u encia de opera co es e, em seguida, retorna um objeto. As tarefas realizadas por um m etodo em C++ s ao: Receber uma lista de objetos (par ametros). Executar um conjunto de tarefas. Retornar apenas um objeto. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

272

DE UM METODO 13.4. DEFINIC AO

A declara ca o de um m etodo e a descri ca o de seu retorno, seu nome e seus par ametros, antes de sua deni ca o. A vantagem das declara co es e que elas facilitam o trabalho do compilador, ou seja, auxiliam na identica ca o da chamada de m etodos com par ametros errados. No exemplo a seguir o retorno e do tipo int, o nome do m etodo e SomaInt(), e os par ametros s ao dois objetos do tipo int. Note que na declara ca o de um m etodo, o nome dos par ametros e opcional. A declara ca o do m etodo SomaFloat() inclui como retorno um float, e como par ametro, dois objetos do tipo float, com nomes a, b. Exemplo: // Arquivo CSoma.h class CSoma { public: // Declara c~ ao do m etodo SomaInt(), par^ ametro sem nome int SomaInt( int , int ); // Declara c~ ao do m etodo SomaFloat(), par^ ametro com nome float SomaFloat( float a, float b ); };

13.4

Deni c ao de um m etodo

A deni ca o de um m etodo e a implementa ca o de seu c odigo, do conjunto de instru co es que ser ao executadas pelo m etodo. Veja a seguir a implementa ca o do m etodo SomaInt() e seu uso dentro da fun ca o main(). Observe que colocamos o retorno, int, o nome da classe, CSoma, o operador de resolu ca o de escopo (::), o nome do m etodo, SomaInt(), e seus par ametros ( int a, int b ). O nome da classe seguido de :: e necess ario pois informa ao compilador que o m etodo SomaInt() pertence a classe CSoma. Se n ` ao colocarmos CSoma::, deixando apenas int SomaInt( int a, int b );, teremos uma fun ca o global e n ao um m etodo da classe (um erro comum). Exemplo: // Arquivo CSoma.cpp // Inclui o arquivo "CSoma.h" com a defini c~ ao da classe CSoma #include "CSoma.h" // Defini c~ ao do m etodo SomaInt() da classe CSoma int CSoma::SomaInt ( int a, int b ) { return a + b; } // Arquivo programa.cpp // Uso do m etodo SomaInt() da classe CSoma #include "CSoma.h" #include <iostream> int main() { // Cria objetos do tipo int com nomes x e y int x = 3; int y = 4; // Cria objeto do tipo CSoma com nome obj CSoma obj; // Uso do m etodo SomaInt() de obj Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

13.5. RETORNO DE UM METODO int z = obj.SomaInt(x,y); std::cout < < "\nSoma = " < < z < < std::endl; return 0; }

273

Observe que para criar um objeto do tipo int, fazemos int nomeObjeto;. Para criar um objeto do tipo do usu ario, o procedimento e o mesmo, CSoma obj;. Tendo um objeto da classe CSoma, podemos acessar seus atributos e m etodos p ublicos diretamente, como em obj.SomaInt(x,y);.

13.5

Retorno de um m etodo

Todo m etodo deve ter um tipo de retorno. O retorno e os par ametros de um m etodo podem ser de qualquer tipo, isto e, um tipo predenido de C++, um tipo do usu ario ou um tipo denido em uma biblioteca externa. C++ tem alguns padr oes de retorno denidos no arquivo de cabe calho <cstdlib>, como EXIT_SUCESS e EXIT_FAILURE. #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 Quando voc e n ao quiser nenhum retorno, dever a especicar o tipo void. O uso de void como retorno signica que o m etodo n ao tem retorno. No exemplo a seguir o M etodo() n ao tem nenhum retorno, o que e informado com a palavra-chave void. Exemplo: class CMath { int abs(int x); double sqrt(double x); void M etodo(); };

// M etodo com retorno do tipo int // M etodo com retorno do tipo double // M etodo sem retorno e sem par^ ametro

O retorno de um m etodo pode ser uma chamada a outro m etodo ou a um objeto. 2 O retorno de um m etodo n ao pode ser um array nem uma fun ca o, mas pode ser um ponteiro ou refer encia a um array ou fun ca o. Veja Ap endice H Vetores e matrizes arrays.

13.6

Par ametros dos m etodos

Quando declaramos um m etodo devemos incluir a lista de par ametros. Isto e, a lista de objetos que o m etodo receber a. Veremos nesta se ca o que os par ametros podem ser passados por c opia (Se ca o 13.6.1), refer encia (Se ca o 13.6.2), ou ponteiro (Se ca o 13.6.3). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

274

13.6. PARAMETROS DOS METODOS

13.6.1

Passagem dos par ametros por c opia

Neste caso o m etodo recebe como par ametro uma c opia do objeto. Note que como e criada mais lento porque precisa criar uma c opia, o objeto original n ao sofre nenhuma altera ca o. E uma c opia de cada objeto passado como par ametro. No exemplo a seguir, dentro de main(), o objeto int a n ao vai sofrer nenhuma altera ca o, pois o m etodo M() vai receber uma c opia de a, com nome x. Exemplo: class CNomeClasse { public: int M(int x); }; int CNomeClasse::M(int x) { return x = 5; } int main() { CNomeClasse obj; int a = 1; int b = obj.M(a); return 0; }

// Declara c~ ao do m etodo M() // Defini c~ ao do m etodo M()

// Chamada do m etodo M()(uso) // aqui a = 1, b = 5

13.6.2

Passagem dos par ametros por refer encia

Uma refer encia e um apelido para um objeto. Veja no exemplo a seguir como criar uma refer encia. Exemplo: int x; // Cria objeto do tipo inteiro com nome x int& ref_x; // Cria uma refer^ encia para x ref_x = 5; // Usa a refer^ encia para armazenar o valor 5 em x Veremos descri ca o detalhada do uso de refer encias no Cap tulo 15 Ponteiros, refer encias e gerenciamento de mem oria. Como uma refer encia e um apelido para um objeto, quando o m etodo recebe como par ametro a refer encia, ele recebe o pr oprio objeto e n ao uma c opia. Note que a passagem de par ametro por refer encia e mais r apida, pois o m etodo tem acesso direto aos objetos (sem criar uma c opia destes). Observe ainda que o objeto passado pode sofrer altera co es dentro do m etodo. No exemplo a seguir, dentro de main(), o objeto a vai sofrer altera ca o, pois o m etodo M() vai receber o pr oprio a. Note que dentro de main() o nome do objeto e a, e dentro do m etodo M() o apelido de a e x. Exemplo: class CNomeClasse { public: int M(int& x); };

// Declara c~ ao do m etodo M()

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

13.6. PARAMETROS DOS METODOS int CNomeClasse::M(int &x) { return x = 5; } int main() { CNomeClasse obj; int a = 1; int b = obj.M(a); return 0; } // Defini c~ ao do m etodo M()

275

// Chamada de M()(uso) // aqui a = 5, b = 5

13.6.3

Passagem dos par ametros por ponteiro

Neste caso o m etodo recebe como par ametro um ponteiro para o objeto. Um ponteiro e um objeto que aponta para outro objeto, podendo ser usado para alterar os valores armazenados no objeto apontado. Veja no exemplo a seguir que dado um objeto x do tipo inteiro, podemos criar um ponteiro para x usando int* ptr_x = &x;. Observe que usamos o caracter * para indicar que estamos criando um ponteiro para um inteiro. O caracter & (e comercial) e usado para pegar o endere co de x e armazenar em ptr_x. Exemplo: int x; // Cria objeto do tipo inteiro com nome x int* ptr_x; // Cria ponteiro para inteiro ptr_x = &x; // Pega o endere co do objeto x e armazena em ptr Veremos descri ca o dos ponteiros no Cap tulo 15 Ponteiros, refer encias e gerenciamento de mem oria. No exemplo a seguir declaramos como par ametro um ponteiro com nome pb, que e utilizado dentro do m etodo M() para acessar o objeto. O objeto acessado pelo ponteiro pode sofrer altera co es. Exemplo: class CNomeClasse { public: int M(int *pb); // Declara c~ ao do m etodo M() }; int CNomeClasse::M(int* pb)// Defini c~ ao do m etodo M() { return *pb = 5; } int main() { CNomeClasse obj; int a = 1; int b = obj.M( &a ); // Chamada do m etodo M()(uso) return 0; // aqui a = 5, b = 5 } Note que a passagem por ponteiro e semelhante ` apassagem por refer encia no que tange ` a modica ca o do par ametro. Isto e, ambos modicam o objeto passado como par ametro. Veja na Listagem 13.1 exemplo ilustrando a passagem de par ametros. N ao se preocupe se n ao entender a parte que usa ponteiros; depois de ler o cap tulo de ponteiros, releia esse Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

276

13.6. PARAMETROS DOS METODOS

exemplo. O programa inicia com a inclus ao da biblioteca <iostream>. Em seguida, cria a classe CTeste com quatro m etodos p ublicos, Soma_Valor(), Soma_Referencia(), Soma_Ponteiro() e Soma_ReferenciaPonteiro(). Na fun ca o main() criam-se duas vari aveis a e b, do tipo int. Os valores de a e b s ao mostrados na tela. Depois disso, cria-se um objeto do tipo CTeste, e os m etodos de CTeste s ao executados. No in cio da execu ca o de Soma_Valor(), criam-se as vari aveis x e y c opias de a e b. Assim, a modi ca o de x e y dentro de Soma_Valor() n ao altera os valores dos par ametros passados, no caso a e b denidos dentro de main(). Por m, as vari aveis a e b s ao passadas como par ametros dos outros tr es m etodos. Nestes tr es casos, os valores de a e b denidos dentro de main() s ao modicados. Listing 13.1: Passando par ametros por valor, refer encia e ponteiro.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 # include < iostream > using std :: cout ; using std :: endl ; class CTeste { public : int Soma_Valor ( int , int ) ; int S o m a _ R e f e r e n c i a ( int & , int &) ; int S o m a _ P o n t e i r o ( int * , int *) ; int S o m a _ R e f e r e n c i a P o n t e i r o ( int *& , int *&) ; }; // D e f i n i c~ a o de um m e todo que recebe p a r ^ a m e t r o s por valor ( int ) int CTeste :: Soma_Valo r ( int x , int y ) { int soma = x + y ; x = 5; // In u til , usado apenas para m o s t r a r que a , b y = 7; // d e f i n i d o s dentro de main () n~ a o s~ ao alterados return soma ; } // D e f i n i c~ a o de um m e todo que recebe p a r ^ a m e t r o s por r e f e r ^ e n c i a ( int &) int CTeste :: S o m a _ R e f e r e n c i a ( int & x , int & y ) { int soma = x + y ; x = 55; y = 77; return soma ; } // D e f i n i c~ a o de um m e todo que recebe p a r ^ a m e t r o s por p o n t e i r o ( int *) int CTeste :: S o m a _ P o n t e i r o ( int *x , int * y ) { int soma = * x + * y ; * x = 555; * y = 777; return soma ; } // D e f i n i c~ a o de um m e todo que recebe p a r ^ a m e t r o s como // r e f e r ^ e n c i a para um p o n t e i r o ( int *&) int CTeste :: S o m a _ R e f e r e n c i a P o n t e i r o ( int *& x , int *& y ) { int soma = * x + * y ; * x = 5555; * y = 7777; return soma ; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

13.6. PARAMETROS DOS METODOS


50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

277

int main () { // Cria o b j e t o s a e b do tipo int int a = 1; int b = 2; cout << " a = " << a << " , b = " << b << endl ; // Cria objeto obj do tipo CTeste CTeste obj ; // Chama m e t o d o s do objeto obj cout << " Ap o s chamar Soma_Valor (a , b ) ; " << " soma = " << obj . Soma_Valor (a , b ) << " , a = " << a << " , b = " << b << endl ; cout << " Ap o s chamar S o m a _ R e f e r e n c i a (a , b ) ; " << " soma = " << obj . S o m a _ R e f e r e n c i a (a , b ) << " , a = " << a << " , b = " << b << endl ; cout << " Ap o s chamar S o m a _ P o n t e i r o (& a ,& b ) ; " << " soma = " << obj . S o m a _ P o n t e i r o (& a , & b ) << " , a = " << a << " , b = " << b << endl ;

// Cria int * pa int * pb cout << << <<

p o n t e i r o s para a e b = &a; = &b; " Ap o s chamar S o m a _ R e f e r e n c i a P o n t e i r o ( pa , pb ) ; " " soma = " << obj . S o m a _ R e f e r e n c i a P o n t e i r o ( pa , pb ) " , a = " << a << " , b = " << b << endl ;

return 0; } a = 1 , b = Ap o s chamar Ap o s chamar Ap o s chamar Ap o s chamar 2 Soma_Valor (a , b ) ; soma = 3 , a = 1 , b = 2 S o m a _ R e f e r e n c i a (a , b ) ; soma = 3 , a = 1 , b = 2 S o m a _ P o n t e i r o (& a ,& b ) ; soma = 132 , a = 55 , b = 77 S o m a _ R e f e r e n c i a P o n t e i r o ( pa , pb ) ; soma = 1332 , a = 555 , b = 777

13.6.4

Par ametros predenidos inicializadores

A utiliza ca o de par ametros predenidos consiste em atribuir valores iniciais aos par ametros de um m etodo. Assim, quando o m etodo e chamado sem par ametros, ser ao utilizados os par ametros predenidos. Veja o prot otipo. Note que se o par ametro pn n ao for passado, o m etodo vai assumir que pn tem o valor vn. Prot otipo: TipoRetorno NomeM etodo(Tipo p1 = v1, Tipo p2 = v2, ... ,Tipo pn = vn); No exemplo a seguir, o m etodo M() tem os par ametros a, b e c previamente inicializados com os valores 4, 7 e 9.3, respectivamente. Observe que o m etodo M() pode ser chamado de diferentes formas e que os par ametros que deixam de ser fornecidos s ao aqueles que est ao mais ` a direita. Exemplo: int CNomeClasse::M(int a = 4, int b = 7, float c = 9.3) { Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

278 return a + b + c; } int main() { // O m etodo M() pode CNomeClasse obj; obj.M(77, 5, 66.6); obj.M(33, 75); obj.M(67); obj.M(); return 0; }

13.7. METODOS NORMAIS

ser chamado das seguintes formas: // // // // a a a a = = = = 77, 33, 67, 4, b b b b = = = = 5, 75, 7, 7, c c c c = = = = 66.6 9.3 9.3 9.3

Um par ametro predenido pode ser a chamada a um m etodo, veja o exemplo: Exemplo: int CNome::M1() { return 2; } int CNome::M2(int x, int y = CNome::M1(), int z = 3) { return x + y + z; } Par ametros predenidos podem ser acumulados em mais de uma declara ca o. No exemplo a seguir, o m etodo M2() foi declarado diversas vezes. Lembre-se que declara co es podem ser repetidas. Observe que a chamada a M2() sem par ametros funciona, pois considera as declara co es (2) e (3). Embora v alido, este procedimento deve ser evitado, porque as declara co es podem estar em arquivos diferentes. Exemplo: int M2(int x, int y, int z); // Declara c~ ao (1) int M2(int x, int y, int z = 3); // Declara c~ ao (2) int M2(int x = 1, int y = 2, int z); // Declara c~ ao (3) void Teste() { CNomeClasse obj; obj.M2(); // Equivale a obj.M2(1, 2, 3) } Note que se os tipos dos par ametros forem diferentes teremos sobrecarga de m etodos, a qual ser a discutida no Cap tulo 14 Sobrecarga de m etodos. Veremos a seguir os diferentes tipos de m etodos de uma classe.

13.7

M etodos normais

Os m etodos normais s ao declarados dentro da classe sem nenhum qualicador adicional, isto e, sem uso dos qualicadores inline, static, virtual ou const. Veja o prot otipo: Prot otipo: class CNome { // Declara ca o TipoRetorno NomeM etodo(par ametros); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

13.7. METODOS NORMAIS }; // Deni ca o TipoRetorno CNomeClasse::NomeM etodo(par ametros) {.. c odigo..} // Uso objeto.NomeM etodo(par ametros);

279

Veremos o uso dos m etodos normais mediante a implementa c ao da classe CPessoa. Veja na Figura 13.1 o diagrama UML da classe CPessoa e na Listagem 13.2 sua implementa ca o. Neste exemplo, usamos os tipos predenidos de C++, os tipos do usu ario e os tipos da biblioteca-padr ao de C++ (<string> e <vector>).
CPessoa
+nome: string +matricula: string +Entrada(): void +Saida(): void

Figura 13.1: A classe CPessoa. O programa inicia pela inclus ao das bibliotecas que ser ao utilizadas e pela libera ca o do uso do namespace std. Em seguida, dene a classe CPessoa, com atributos nome, matricula e dois m etodos, um para Entrada() e outro para Saida() de dados. O m etodo Entrada() pede para o usu ario a entrada dos atributos do objeto, o nome da pessoa e seu n umero de matricula. O m etodo Saida() envia para a tela o nome e matricula do objeto. Na fun ca o main(), criamos um objeto do tipo CPessoa, com nome professor e solicitamos seus dados. Em seguida, criamos um <vector> da STL (Se ca o 9.4.2) para armazenar dois objetos do tipo CPessoa. Dentro do primeiro for(), para cada aluno i, executamos o m etodo Entrada(), ou seja, lemos os dados do aluno[i]. No segundo for(), cada aluno[i] envia para a tela seus atributos, chamando o m etodo Saida(). Note no exemplo da Listagem 13.2 que os dados do professor s ao lidos diretamente usando getline (cin, professor.nome);, isto s o e poss vel porque os atributos nome e matricula s ao p ublicos. Listing 13.2: Classe com atributo e m etodo normal.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include < iostream > # include < string > # include < vector > using namespace std ; /* * A classe C P e s s o a r e p r e s e n t a uma pessoa ( um aluno ou um p r o f e s s o r ) de uma u n i v e r s i d a d e . Tem um nome , uma matr cula , e m etodos b a s i c o s para e n t r a d a e sa da de dados . */ class CPessoa { public : std :: string nome ; // A t r i b u t o s n o r m a i s std :: string matricula ; void Entrada () ; // M e todo normal void Saida () const ; // M e todo const };

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

280
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

13.7. METODOS NORMAIS

// S o l i c i t a a t r i b u t o s do objeto void CPessoa :: Entrada () { cout << " Entre com o nome do aluno : " ; getline ( cin , nome ) ; cout << " Entre com a matr cula do aluno : " ; getline ( cin , matricula ) ; } // Mostra void { cout << << } a t r i b u t o s do objeto CPessoa :: Saida () const " Nome do aluno : " << nome " \ nMatr cul a : " << matricula << endl ;

int main () { string linha = " \n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " ; const int n u m e r o A l u n o s = 2; // Cria CPessoa cout << getline cout << getline um objeto do tipo C P e s s o a com nome p r o f e s s o r professor ; " Entre com o nome do professor : " ; ( cin , professor . nome ) ; " Entre com a matr cula do professor : " ; ( cin , professor . matricula ) ;

// Cria um vetor de o b j e t o s do tipo C P e s s o a com nome aluno vector < CPessoa > aluno ( n u m e r o A l u n o s ) ; for ( int contador = 0; contador < n u m e r o A l u n o s ; contador ++) { cout << " \ nAluno " << contador << endl ; aluno [ contador ]. Entrada () ; } cout << linha << " \ nRELA C~ A O DE PROFESSOR E S E ALUNOS : " << linha << " \ nNome do professor : " << professor . nome << " \ nMatr cul a : " << professor . matricula << endl ; for ( int contador = 0; contador < n u m e r o A l u n o s ; contador ++) { cout << linha << " \ nAluno " << contador << endl ; aluno [ contador ]. Saida () ; } cout << linha ; return 0; } Entre com o nome do professor : Andre Duarte Bueno Entre com a matr cula do professor : 123 Aluno 0 Entre com o nome do aluno : Giovanni Colonese Entre com a matr cula do aluno : 324 Aluno 1 Entre com o nome do aluno : Alan Galante Entre com a matr cula do aluno : 984 ------------------------------------------------------RELA C~ A O DE PROFESSOR E S E ALUNOS : -------------------------------------------------------

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

13.8. METODOS CONSTANTES CONST


Nome do professor : Andre Duarte Bueno Matr cula : 123 ------------------------------------------------------Aluno 0 Nome do aluno : Giovanni Colonese Matr cula : 324 ------------------------------------------------------Aluno 1 Nome do aluno : Alan Galante Matr cula : 984

281

Este e um de seus primeiros programas orientados a objeto. Simples, n ao e? Voc e declarou uma classe: class CPessoa... Deniu os m etodos da classe: void CPessoa::Entrada(){...} Criou objetos da sua classe: CPessoa professor; Usou o objeto: cout < < "Nome do professor: " < < professor.nome < < "\n";

13.8

M etodos constantes const

Se um m etodo da classe n ao altera o estado e os atributos do objeto, ele deve ser declarado como const. Observe no prot otipo a seguir que a palavra-chave const e colocada no nal da declara ca o: Prot otipo: class CNome { // Declara ca o TipoRetorno NomeM etodo(par ametros) const; }; // Deni ca o TipoRetorno NomeClasse::NomeM etodo(par ametros) const {.. c odigo..} // Uso objeto.NomeM etodo(par ametros); A declara ca o const instrui o compilador de que o m etodo n ao pode alterar o estado do objeto. Observe no pr oximo exemplo que a palavra-chave const e colocada antes do (;) ponto-e-v rgula que naliza a declara ca o. Exemplo: class CNomeClasse { int valor; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

282 int Valor() const; int MudaValor(); }; int CNomeClasse::Valor() const { return valor; } void CNomeClasse::Valor(int v) { return valor = v; }

13.8. METODOS CONSTANTES CONST // Declara c~ ao de m etodo const // Declara c~ ao de m etodo normal // Defini c~ ao de m etodo const // Defini c~ ao de m etodo normal // muda atributo valor

Se dentro de um m etodo const algum atributo for modicado, ou um m etodo n ao const for chamado, o compilador acusar a o erro. Exemplo: int CNomeClasse::Valor() const // Outra defini c~ ao para Valor { ++valor; // Erro, n~ ao pode mudar atributo Valor(5); // Erro, n~ ao pode chamar m etodo normal return valor; } Se um m etodo qualquer receber como par ametro um objeto const, esse m etodo s o poder a acessar os m etodos const desse objeto, ou seja, n ao poder a acessar os m etodos que modicam o estado do objeto. Exemplo: void f(const CNomeClasse& obj) { cout < < obj.Valor(); // ok, o m etodo Valor() e const obj.MudaValor(); // Erro, n~ ao pode chamar m etodo normal } Releia a Listagem 13.2, observe que o m etodo Saida() e const. Veja na Listagem 13.3 um exemplo de uso de par ametros e m etodos const. Neste exemplo criamos uma classe CNumeroRandomico, a qual e usada para fornecer n umeros rand omicos. O atributo random armazena o n umero rand omico. O m etodo Random() retorna o n umero rand omico. O m etodo Update() gera um novo n umero rand omico. Como Update() altera o estado do objeto, isto e, altera o valor de random, ele n ao pode ser declarado como const. A fun ca o main() solicita a entrada de uma semente e cria um objeto CNumeroRandomico, em seguida chama Inicializa() passando a semente. Dentro do for, chama o m etodo Update(), que gera um novo n umero rand omico e ent ao chama Random(). Esse exemplo mostra o uso de duas fun co es da biblioteca-padr ao de C, a srand(), para informar o valor da semente e a rand(), para gerar um novo n umero rand omico. Nota: veremos, no Ap endice K Arquivos de cabe calho, os arquivos de cabe calho padr ao de C/C++ e uma breve descri ca o das fun co es mais utilizadas. Listing 13.3: Classe com m etodo const.
1 2 3 4 5 # include < iostream > # include < iomanip > # include < cstdlib > using namespace std ; // F u n c~ o e s srand () e rand ()

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

13.8. METODOS CONSTANTES CONST


6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 class C N u m e r o R a n d o m i c o { private : double random ; int semente ; public :

283

// A t r i b u t o s n o r m a i s // n u mero r a n d o m i c o // s e m e n t e g e r a d o r a i n i c i a l // M etodos // M e todo de i n i c i a l i z a c~ ao void Inicializa ( const int _semente = 1) ; // M e t o d o s const double Random () const ; // R e t o r n a n u mero r a n d o m i c o int Semente () const ; // R e t o r n a a s e m e n t e void Update () ; // M e todo normal

}; // M e todo de i n i c i a l i z a c~ ao void C N u m e r o R a n d o m i c o :: Inicializa ( const int _semente ) { semente = _semente ; random = 0; srand ( semente ) ; } double C N u m e r o R a n d o m i c o :: Random () { return random ; } int C N u m e r o R a n d o m i c o :: Semente () { return semente ; } const

const

// Update gera um novo n u mero r a n d ^ o m i c o e a r m a z e n a em random void C N u m e r o R a n d o m i c o :: Update () { random = rand () ; } int main () { cout << " \ nEntre com uma semente : " ; int semente ; cin >> semente ; cin . get () ; C N u m e r o R a n d o m i c o gerador ; gerador . Inicializa ( semente ) ; cout << " Valor da semente : " << gerador . Semente () << " Valor inicial : " << gerador . Random () << endl ; for ( int i = 0; i < 5; i ++) { gerador . Update () ; cout << " gerador . Random ( " << setw (3) << i << " ) = " << setw (15) << gerador . Random () << endl ; } return 0; } bash -3.00 $ ./ a . out Entre com uma semente : 4 Valor da semente : 4 Valor inicial : 0 gerador . Random ( 0) = 1.96808 e +09 gerador . Random ( 1) = 2.87724 e +08 gerador . Random ( 2) = 4.10622 e +08 gerador . Random ( 3) = 5.58519 e +08

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

284
gerador . Random ( 4) = 4.60165 e +08

13.9. METODOS ESTATICOS STATIC

Dica: a biblioteca Matpack, descrita no Cap tulo ?? Biblioteca Matpack, inclui diversas classes utilit arias para gera ca o de n umeros rand omicos.

13.9

M etodos est aticos static

Vimos que existem dois tipos de atributos: os atributos de objeto (Se ca o 12.2) e de classe (Se ca o 12.3). Se voc e montar um m etodo que s o opera sobre os atributos est aticos da classe, pode declar a-lo como sendo um m etodo est atico. Adicionalmente, um m etodo est atico e p ublico pode ser acessado sem um objeto da classe, basta colocar o nome da classe, o operador de resolu ca o de escopo (::) e o nome do m etodo. Veja a seguir o prot otipo: Prot otipo: class CNome { // Declara ca o static TipoRetorno NomeM etodo(par ametros); }; // Deni ca o TipoRetorno NomeClasse::NomeM etodo(par ametros) {.. c odigo..} // Uso NomeClasse::NomeM etodoEst atico(); Veja na Listagem 13.4 um exemplo de classe com atributo e m etodo est atico. Este exemplo e um aperfei coamento da Listagem 13.2. Como inova ca o temos o atributo iaa, e o n umero de alunos e solicitado ao usu ario. Tamb em temos um atributo est atico, numeroAlunos, utilizado para armazenar o total de alunos (e professores) que foram criados. O m etodo est atico NumeroAlunos() retorna o n umero de alunos e pode ser acessado sem um objeto. Listing 13.4: Classe com atributo e m etodo est atico.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # include < iostream > # include < string > # include < vector > using namespace std ; /* A classe C P e s s o a r e p r e s e n t a uma pessoa ( um aluno ou um p r o f e s s o r ) de uma u n i v e r s i d a d e . Tem um nome , uma matricula , um iaa , e m etodos b a s i c o s para e n t r a d a e sa da de dados . */ class CPessoa { public : std :: string nome ; std :: string matricula ; float iaa ; private : static int n u m e r o A l u n o s ; public : void Entrada () ; void Saida () const ; // Um m e todo e s t a t i c o s o pode a c e s s a r e a l t e r a r a t r i b u t o s e s t aticos static int N u m e r o A l u n o s () ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

13.9. METODOS ESTATICOS STATIC


23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 }; // A t r i b u t o e s t atico e aquele que p e r t e n c e a classe e n~ a o ao objeto // e p r e c i s a ser d e f i n i d o depois da classe int CPessoa :: n u m e r o A l u n o s = 0; // M e todo est a tico , r e t o r n a o n u mero de alunos int CPessoa :: N u m e r o A l u n o s () { return n u m e r o A l u n o s ; } void CPessoa :: Entrada () { n u m e r o A l u n o s ++; cout << " Entre com o nome : " ; getline ( cin , nome ) ; cout << " Entre com a matr cula : " ; getline ( cin , matricula ) ; cout << " Entre com o IAA : " ; cin >> iaa ; cin . get () ; } void { cout << << << } CPessoa :: Saida () const " Nome : " << nome " \ tMatr cula : " << matricula " \ tIAA : " << iaa << endl ;

285

int main () { string linha = " \n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - " ; cout << " \ nEntre com o n u mero de alunos da disciplin a ( ex : 3) : " ; int n u m e r o A l u n o s ; cin >> n u m e r o A l u n o s ; cin . get () ; CPessoa professor ; cout << " Entre com o nome do professor : " ; getline ( cin , professor . nome ) ; cout << " Entre com a matr cula do professor : " ; getline ( cin , professor . matricula ) ; vector < CPessoa > aluno ( n u m e r o A l u n o s ) ; for ( int contador = 0; contador < aluno . size () ; contador ++) { cout << linha << " \ nAluno " << contador << endl ; aluno [ contador ]. Entrada () ; } cout << linha << " \ nRELA C~ A O DE PROFESSORE S E ALUNOS : " << linha << " \ nNome do professor : " << professor . nome << " \ nMatr cula : " << professor . matricula << " \ n " ; for ( int contador = 0; contador < aluno . size () ; contador ++) { cout << linha << " \ nAluno " << contador << endl ; aluno [ contador ]. Saida () ; } // Usa m e todo e s t a t i c o sem ter um objeto cout << " \ nN u mero alunos = " << CPessoa :: N u m e r o A l u n o s () << endl ; return 0;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

286
85 }

13.10. METODOS EM LINHA INLINE

Entre com o n u mero de alunos da disciplina ( ex : 3) : 3 Entre com o nome do professor : Andr e Duarte Bueno Entre com a matr cula do professor : 654 ---------------------------------------------------------Aluno 0 Entre com o nome : Tiago Schaewer Entre com a matr cula : 548 Entre com o IAA : 9.8 ---------------------------------------------------------Aluno 1 Entre com o nome : Alan Galante Entre com a matr cula : 987 Entre com o IAA : 9 ---------------------------------------------------------Aluno 2 Entre com o nome : Giovanni Colonese Entre com a matr cula : 475 Entre com o IAA : 9.3 ---------------------------------------------------------RELA C~ A O DE PROFESSOR E S E ALUNOS : ---------------------------------------------------------Nome do professor : Andr e Duarte Bueno Matr cula : 654 ---------------------------------------------------------Aluno 0 Nome : Tiago Schaewer Matr cula : 548 IAA : 9.8 ---------------------------------------------------------Aluno 1 Nome : Alan Galante Matr cula : 987 IAA : 9 ---------------------------------------------------------Aluno 2 Nome : Giovanni Colonese Matr cula : 475 IAA : 9.3 N u mero alunos =3

Dica: substitua o uso de atributos est aticos por fun co es est aticas que retornam uma refer encia para objetos est aticos. Veja o exemplo: Exemplo: const double& Pi() { static const double pi = 3.141516; return pi; }

13.10

M etodos em linha inline

Quando voc e dene um m etodo, o compilador reserva um espa co de mem oria que e ocupado pelo c odigo do m etodo. Quando voc e chama um m etodo com par ametros, o compilador passa os par ametros para o m etodo a ser executado, mudando a linha de execu ca o do programa (P1). Depois de executado o m etodo, o programa retorna para o local onde estava (P2) e executa a instru ca o seguinte ` a chamada do m etodo. Observe que existem dois passos intermedi arios, ir at e onde o m etodo est a e depois retornar, o que consome tempo de processamento. A Figura 13.2 ilustra o processo considerando a seq u encia com m etodo normal e inline. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

13.10. METODOS EM LINHA INLINE

287

Observe que na seq u encia normal a fun ca o main() faz x = 3; e cria o objeto obj, do tipo C. Em seguida, o m etodo M() e chamado (P1), dentro do m etodo executa a seq u encia int z = x + 3; e faz z*z. Finalizado o m etodo M(), o mesmo retorna o valor de z*z (P2) e armazena em y. O valor de y e enviado para a tela e, ent ao, o programa e encerrado. Na seq u encia com m etodo inline, o c odigo de C::M() e copiado para dentro de main(), eliminando os passos intermedi arios (P1) e (P2).
// Declarao da classe class C { // Declara mtodo inline inline int M(int x); }; // Define mtodo M() int C::M(int x) { int z = x + 3; return z * z; } // Seqncia Normal #include "C.h" int main() { int x = 3; (P1) C obj; int y = obj.M(x); cout << "y = "<< y << endl; return 0; } // Seqncia com mtodo inline #include "C.h" int main() { int x = 3; Trecho de C obj; cdigo int z = x + 3; copiado de int y = z * z; C::M() cout << "y = "<< y << endl; return 0; }

(P2)

Figura 13.2: Como cam os m etodos inline. Veja a seguir algumas caracter sticas dos m etodos inline: M etodos inline devem ser m etodos pequenos, por isso o termo em linha. S ao m etodos que s ao executados mais rapidamente. Uma especica ca o inline e uma sugest ao para que seja feita a sua substitui ca o e n ao a sua chamada; o compilador e que decide. Se o m etodo for grande, o compilador ir a desconsiderar o especicador inline. Um m etodo inline e ideal para retorno de valores. Um m etodo denido dentro da deni ca o da classe e inline por default. Veja linhas 20-24 da Listagem 13.5. A utiliza ca o de m etodos inline torna o programa mais r apido, por em maior. Coloque o c odigo de todos os m etodos inline dentro da deni ca o da classe. Um m etodo recursivo (que chama a si mesmo) n ao pode ser inline. Isto ocorre porque o m etodo teria de ser substitu do onde e chamado, e, como e recursivo, o n umero de substitui co es e indenido ou implica na gera ca o de c odigos muito extensos. Veremos na Se ca o 28.1.2 fun co es expandidas em tempo de compila ca o, uma maneira de construir m etodos recursivos em tempo de compila ca o. Altera co es em um m etodo inline implicam na necessidade de se recompilar todas as bibliotecas que fa cam uso deste, ou seja, utilize inline com cuidado. Em resumo, os m etodos inline foram criados para otimizar o programa. Quando um m etodo inline e chamado, o compilador, em vez de chamar o m etodo, coloca uma c opia deste onde uma situa ele est a sendo chamado. E ca o semelhante ` a que ocorria com as antigas macros de C, com a vantagem de fazer verica ca o de tipo. Veja a seguir um exemplo: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

288 Exemplo: class CRetangulo { int base, altura; public: // inline impl cito, pois o int Base() const { void Base(int _base) { int Altura() const { void Altura(int _altura) { int Perimetro() const { // inline expl cito, uso da inline int Area() { };

13.10. METODOS EM LINHA INLINE

m etodo e definido dentro da classe return base; }; base = _base; }; return altura; }; altura = _altura; }; return base*base + altura*altura; }; palavra-chave inline return base*altura; };

Nota: no exemplo anterior usamos m etodos com mesmo nome, mas n umero de par ametros diferente. Veja o Cap tulo 14 Sobrecarga de m etodos. Veja na Figura 13.3 o diagrama UML da classe CPonto, cujo c odigo para implementa ca o e apresentado nas listagens 13.5 e 13.6. Observe a utiliza ca o de m etodos inline para acesso aos atributos da classe e o uso de m etodos const. A classe CPonto ser a utilizada na Listagem 13.7.
A classe CPonto inclui dois atributos normais do tipo inteiro e um atributo de classe.

CPonto
+x: int +y: int +contador: static int = 0 +Desenha(): virtual void

Figura 13.3: A classe CPonto. Listing 13.5: A classe CPonto.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # ifndef CPonto_h # define CPonto_h // Define a classe CPonto , o tipo de u s u a r i o CPonto . class CPonto { protected : int x ; int y ; static int contador ; public : // Seta a t r i b u t o s do ponto inline void Set ( CPonto & p ) // M e todo inline e x p l cito { x = p . X () ; y = p . Y () ; } void Set ( int & _x , int & _y ) { // M e todo inline i m p l cito

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

13.10. METODOS EM LINHA INLINE


22 23 24 25 26 27 28 29 30 31 32 33 34 x = _x ; y = _y ; } // Obt e m a t r i b u t o s do ponto // Usa m e t o d o s em linha - inline i m p l cito int X () const { return x ; }; int Y () const { return y ; }; void Desenha () ; static int Contador () ; }; # endif // M e todo normal , d e s e n h a o ponto // M e todo est a tico , r e t o r n a o c o n t a d o r

289

Listing 13.6: Implementa ca o da classe CPonto.


# include < iostream > # include " CPonto . h " // Define a t r i b u t o da classe int CPonto :: contador = 0; // Define m e todo e s t a t i c o da classe int CPonto :: Contador () { return contador ; } void CPonto :: Desenha () { std :: cout << " \ nCPonto : Coordenada x = " << x << " \ nCPonto : Coordenada y = " << y << std :: endl ; }

Na Listagem 13.7 um objeto do tipo CPonto e criado, CPonto ponto;, e utilizado ponto.Set(x,y); ponto.Desenha();. Quando o bloco e encerrado o objeto ponto sai de escopo e e destru do. Observe que, depois de destruir o objeto ponto, utilizamos o m etodo Contador(). Isto e poss vel porque o m etodo e p ublico e est atico. Listing 13.7: Usando m etodos e atributos de uma classe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # include < iostream > # include " CPonto . h " using namespace std ; // E x e m p l o de c r i a c~ a o e uso de um objeto do tipo CPonto int main () { int x = 5; int y = 4; { CPonto p1 ; // Cria objeto do tipo CPonto com nome p1 p1 . Set (x , y ) ; // Chama m e todo Set () do objeto p1 p1 . Desenha () ; // Chama m e todo D e s e n h a () do objeto p1 CPonto p2 ; p2 . Set ( p1 ) ; p2 . Desenha () ; // Cria objeto do tipo CPonto com nome p2 // Chama m e todo Set () do objeto p2 // Chama m e todo D e s e n h a () do objeto p2

CPonto p3 ; // Cria objeto do tipo CPonto com nome p3 x = p1 . X () + p2 . X () ; y = p1 . Y () + p2 . Y () ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

290
22 23 24 25 26 27 28 29 p3 . Set ( x , y ) ; p3 . Desenha () ; }

13.11. METODOS USO AVANCADO

// Sai de escopo e detr o i os o b j e t o s p1 , p2 , p3

// Chama m e todo e s t a t i c o e p u blico , o b s e r v e que n~ a o p r e c i s a de um objeto cout << " Contador = " << CPonto :: Contador () << endl ; return 0; } CPonto : Coordenada x = 5 CPonto : Coordenada y = 4 CPonto : Coordenada x = 5 CPonto : Coordenada y = 4 CPonto : Coordenada x = 10 CPonto : Coordenada y = 8 Contador = 0

13.11

M etodos uso avan cado

Inclu mos nesta se ca o refer encias para se co es que incluem o uso avan cado de m etodos em C++. Os m etodos n ao virtuais foram apresentados neste cap tulo. Veremos outras caracter sticas dos m etodos n ao virtuais na Se ca o 19.1. Veremos os m etodos virtuais, na Se ca o 19.2, e como implementar o polimorsmo, na Se ca o 19.3. Veremos os m etodos virtuais puros na Se ca o 19.4. Veremos os m etodos virtuais sobrecarregados na Se ca o 19.5. Apresentaremos um exemplo cobrindo o uso pr atico de polimorsmo na Se ca o 19.6.

13.12

Senten cas para m etodos

Os m etodos p ublicos formam a interface da classe e devem ter nomes claros e uniformes (veja Tabela 8.2). Se um m etodo manipula preferencialmente os atributos de um objeto, ele provavelmente e um m etodo desse objeto. Em C++, todos os m etodos precisam de uma declara ca o, a qual auxilia o compilador a encontrar erros. Objetos grandes devem ser passados por refer encia ou por ponteiros. Evite utilizar par ametros de m etodos com nome igual ao de outros objetos para evitar ambig uidades. Analise os par ametros dos m etodos. Se estes n ao forem alterados, dever ao ser declarados como const. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

13.12. SENTENCAS PARA METODOS

291

O uso de void como par ametro signica que o m etodo n ao recebe nenhum argumento. Exemplo: // Declarando uma fun c~ ao sem retorno e sem par^ ametro void fun c~ ao(void);// C void fun c~ ao(); // C++ Seguran ca se voc e quer ter certeza de que o par ametro n ao ser a alterado, deve pass a-lo como refer encia constante. Veja o exemplo a seguir. O especicador const informa que o objeto e constante e n ao pode ser alterado dentro do m etodo. Deste modo, o m etodo pode acessar o objeto, mas n ao pode modic a-lo. Exemplo: NomeM etodo(const Tipo& obj); Desempenho par ametros passados por refer encia aumentam a eci encia, pois os valores n ao s ao copiados. Voc e pode passar informa co es de uma classe para outra ou para objetos por meio de atributos est aticos da classe. Um objeto e criado por c opia quando: um par 1. E ametro de um m etodo. um retorno de um m 2. E etodo. lan 3. E cado como uma exce ca o (veja Cap tulo 26 Exce co es). Use inline somente quando houver ganho efetivo de desempenho. M etodos inline devem ter exatamente a mesma deni ca o em todos os arquivos. 2 Se voc e criar um ponteiro para uma fun ca o inline, o compilador criar a uma c opia n ao inline da fun ca o, e o ponteiro apontar a para esta c opia. 2 Na linkagem, os m etodos inline devem estar acess veis a todas as unidades de tradu ca o. 2 A lista de exce co es que um m etodo pode lan car n ao faz parte de sua assinatura. 2 Uma fun ca o friend denida dentro de uma classe e uma fun ca o inline impl cita. 2 Um m etodo est atico (static) n ao recebe um ponteiro this e, portanto, n ao pode ser utilizado para acessar os atributos e m etodos da classe. 2 Devo usar m etodos com par ametros predenidos ou sobrecarga de operador? De modo geral, usamos sobrecarga quando os par ametros s ao complexos (evitando a c opia desnecess aria dos par ametros). Se os par ametros s ao simples e o c odigo e complexo, prera par ametros predenidos, assim, o c odigo e escrito uma u nica vez [Lischner, 2003]. 2 Na chamada a uma fun ca o ou m etodo: i) primeiro e feita uma pesquisa pelos nomes, isto e, procura-se por m etodos com aquele nome; ii) em seguida e vericada a sobrecarga, isto e, qual m etodo atende melhor a assinatura do m etodo chamado; iii) nalmente, e vericada a acessibilidade. Na pr atica isso signica que um m etodo que tem uma assinatura mais conhecidente nem sempre e chamado, pois a sobrecarga e vericada antes. Veja Se ca o 14.3.1. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

292

13.13. RESUMO DO CAP ITULO

3 Outro aspecto interessante, relatado por [Sutter, 2006], e que a substitui ca o do c odigo dos m etodos inline pode ser feita a qualquer tempo, ou seja, na compila ca o, na linkagem, na instala ca o e at e na execu ca o. Tudo depende do compilador e de op co es de otimiza ca o. 3 Lembre-se que o uso de inline n ao garante que o m etodo/fun ca o seja efetivamente inline. Na pr atica, o compilador pode colocar um m etodo como sendo inline em uma parte do c odigo e n ao inline em outra parte. A decis ao e sempre do compilador, e n ao podemos fazer nenhuma suposi ca o sobre o que ser a feito. 3 Para ter maior robustez no seu c odigo, deixe os m etodos virtuais como privados ou protegidos. Monte a interface com m etodos normais. Veja Se ca o 11.5.3. Esta t ecnica e conhecida como NVI NonVirtual Interface [Sutter, 2006].

13.13

Resumo do cap tulo

Neste cap tulo vimos o prot otipo para declarar, denir e utilizar os m etodos de uma classe. Vimos em detalhes como funciona a declara ca o a deni ca o e o retorno dos m etodos. Aprendemos que o retorno 0 ou EXIT SUCESS indica sucesso e EXIT FAILURE ou != 0 indica fracasso. Aprendemos a utilizar os diferentes tipos de passagem de par ametros (c opia, refer encia, ponteiro). Entendemos o uso dos par ametros predenidos. Depois aprendemos a declarar e implementar os m etodos normais, os m etodos constantes, os m etodos est aticos e os m etodos em linha. Vimos que os m etodos est aticos s ao criados para manipular os atributos est aticos (de classe). Lembre-se que um atributo static faz parte da classe e n ao do objeto, sendo compartilhado como uma vari por todos os objetos. E avel global para os objetos daquela classe. Observe que a necessidade de atributos static e bastante real. Nota: os m etodos construtores ser ao apresentados no Cap tulo 16 M etodos construtores e destrutores. Veremos o uso avan cado da fun ca o main() e a entrada na linha de comando na Se ca o E.1 e fun co es recursivas na Se ca o E.3.

13.14

Exerc cios

1. Modique a Listagem 13.1, acrescentando um m etodo que recebe par ametros por c opia, refer encia, ponteiro e refer encia de ponteiro. 2. Monte um exemplo que use par ametros predenidos (Se ca o 13.6.4). 3. Monte uma classe CTriangulo que tenha um m etodo normal, um m etodo const, um m etodo static e um m etodo inline. 4. Reveja o exemplo da Listagem 13.1, prestando aten ca o na forma como os m etodos s ao declarados, denidos e usados. 5. Modique a Listagem 13.2, deixando os atributos nome e matr cula como privados. 6. Modique a Listagem 13.4. Crie duas classes, uma para o professor e outra para os alunos. 7. 2 Modique a Listagem 13.3 acrescentando sobrecarga para o operator(), isto e, substitua Random() pelo operator(). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

13.14. EXERC ICIOS

293

8. Implemente o exemplo da classe CRetangulo da Se ca o 13.10. Que tal criar as classes CQuadrado, CCirculo, CElipse? Coloque os atributos da Listagem 13.2 como private: e, em seguida, veja o que acontece na compila ca o. Modique a fun ca o main() de forma que o exemplo funcione mesmo com os atributos sendo privados.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

294

13.14. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 14

Sobrecarga de M etodos
Neste cap tulo apresentaremos a sobrecarga de m etodos, ou seja, a utiliza ca o de m etodos com o mesmo nome mas com n umero ou tipo de par ametros diferentes. Veremos o que e a sobrecarga de m etodos (Se ca o 14.1) e como implement a-la (Se ca o 14.2). Na Se ca o Sobrecarga de m etodos uso avan cado (Se ca o 14.3) veremos a rela c ao entre acessibilidade e visibilidade (Se ca o 14.3.1). Finalmente, veremos algumas senten cas para sobrecarga de m etodos (Se ca o 14.4).

14.1

Prot otipo para sobrecarga de m etodos

Sobrecarga de m etodos se refere ` a utiliza ca o de m etodos com o mesmo nome, mas com tipos ou n umero de par ametros diferentes. Veja o prot otipo a seguir. Observe que a ordem dos par ametros e importante. De modo geral, como os m etodos sobrecarregados t em o mesmo nome, devem ser utilizados para realizar tarefas semelhantes. Prot otipo: Retorno Retorno Retorno ... Retorno M etodo(Tipo1 p1); M etodo(Tipo1 p1, Tipo2 p2); M etodo(Tipo1 p1, Tipo2 p2, Tipo3 p3); M etodo(Tipo1 p1, Tipo2 p2, Tipo3 p3, ...,TipoN pn);

Observe que, como usaremos um mesmo nome para todos os m etodos que realizam coisas semelhantes, e muito importante escolher com cuidado o nome do m etodo. Adicionalmente, o nome deve indicar de forma clara o que vai ser realizado.

14.2

Como implementar a sobrecarga de m etodos

O exemplo a seguir declara m etodos com o mesmo nome, m etodos sobrecarregados. Exemplo: void M etodo(int x, int y); // Declara c~ ao (1)- par^ ametros int, int void M etodo(float x, float y); // Declara c~ ao (2)par^ ametros float, float void M etodo(int x, float y); // Declara c~ ao (3)par^ ametros int, float 295

296

14.2. COMO IMPLEMENTAR A SOBRECARGA DE METODOS

O exemplo a seguir usa o m etodo acima declarado. O compilador identica que xx e yy s ao do tipo int e chama o primeiro m etodo declarado, ou seja, o compilador reconhece qual m etodo voc e quer acessar, vericando o tipo e o n umero de par ametros. Exemplo: int xx = 3; int yy = 4; M etodo( xx , yy );

// Acessa m etodo (1)- int, int

Observe que mudar o nome dos par ametros n ao e uma sobrecarga; o compilador diferencia o tipo, e n ao o nome. No exemplo a seguir ocorre um erro na compila ca o do m etodo, pois este tem como par ametros dois inteiros, repetindo a declara c ao (1) void M etodo(int x,int y);. Exemplo int M etodo(int z, int r); // Declara c~ ao (4)- Erro repete (1)

Enm, voc e deve estar atento ` as convers oes de tipo quando declara m etodos sobrecarregados. Tome os seguintes cuidados: O tipo e a refer encia para o tipo. void M etodo(int a); void M etodo(int & a); // Erro, redeclara c~ ao

Somente a diferencia ca o do nome dos par ametros n ao e sobrecarga. void M etodo(int a, int b); void M etodo(int c, int d); // Erro, redeclara c~ ao

Um m etodo com par ametros predenidos e uma sobrecarga: void M etodo(int a, int b, int c = 1); como se voc E e criasse os m etodos seguintes: void M etodo(int a, int b, int c); void M etodo(int a, int b); Na Se ca o 13.3, declara ca o de um m etodo, montamos uma classe CSoma com dois m etodos, SomaInt() e SomaFloat(). Veja a seguir como a classe CSoma pode car considerando-se o uso de m etodos sobrecarregados. A grande vantagem e o uso do mesmo nome, Soma(), pois isso facilita a memoriza ca o dos objetos e suas funcionalidades. Exemplo: // Arquivo CSoma.h class CSoma { public: // Declara c~ ao do m etodo Soma, par^ ametro do tipo int, sem nome int Soma( int , int ); // Declara c~ ao do m etodo Soma, par^ ametro do tipo float, com nomes a e b float Soma( float a, float b ); }; Reveja a listagem 13.5, observe que o m etodo Set() e sobrecarregado. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

2 14.3. SOBRECARGA DE METODOS CONCEITOS AVANCADOS

297

14.3

Sobrecarga de m etodos conceitos avan cados2

Nesta Se ca o veremos alguns conceitos avan cados de sobrecarga de m etodos.

14.3.1

Acessibilidade x visibilidade: como e feita a sele c ao do m etodo a ser executado

Quando um m etodo e chamado, a seq u encia que envolve a deni ca o de qual m etodo vai ser executado passa por tr es etapas: 1. O compilador pesquisa por m etodos com mesmo nome e verica seu escopo, montando uma lista com os poss veis candidatos. Note que m etodos privados e protegidos far ao parte desta lista. 2. Em seguida o compilador verica a presen ca de sobrecarga e a assinatura dos m etodos. O objetivo e identicar qual m etodo se encaixa melhor (tem maior correspond encia), seguindo a seguinte ordem: (a) A assinatura do m etodo e totalmente coincidente. necess (b) E ario realizar promo co es integrais (exemplo: convers ao de um n umero unsigned int em int). necess (c) E ario usar convers oes-padr ao de C++. necess (d) E ario usar convers oes denidas pelo usu ario (veja Cap tulo 25 Convers oes). 3. O terceiro passo do compilador e fazer a verica ca o de acesso (public, protected e private). Um estudo detalhado dessa seq u encia deixa claro que nem sempre o m etodo com maior correspond encia e chamado, pois a verica ca o da acessibilidade eou ltimo item a ser considerado. Ou seja, se um m etodo com maior correspond encia for inacess vel, ent ao um m etodo com menor correspond encia ser a chamado. Se o que temos n ao e uma fun ca o, e um ponteiro, um template ou um objeto, ent ao a resolu ca o da chamada segue a seguinte ordem: 1. m etodo/fun ca o f(), 2. um ponteiro para m etodo/fun ca o f(), 3. uma fun ca o template f(), 4. a constru ca o de um objeto do tipo f(), ou a chamada do operador() de um objeto f(). Nota: para maiores detalhes consulte [Sutter, 2006, Meyers, 2005]. As convers oes ser ao discutidas no Cap tulo 25 Convers oes.

14.4

Senten ca para sobrecarga de m etodos

Os valores de retorno n ao s ao avaliados em uma sobrecarga. Um m etodo com par ametros predenidos e uma sobrecarga. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

298

14.5. RESUMO DO CAP ITULO

Se o m etodo sobrecarregado recebe int, fa ca uma an alise das poss veis convers oes autom aticas, ou seja, se for passado um tipo integral diferente de int, analise como este vai ser tratado. 2 Um conjunto de m etodos/fun co es sobrecarregados que executam os mesmos procedimentos, mas sobre tipos diferentes, podem ser substitu dos por m etodos/fun co es gabaritos. Veja Cap tulo 27 Templates (ou gabaritos).

14.5

Resumo do cap tulo

Neste cap tulo aprendemos o que e e como implementar a sobrecarga de m etodos em C++. A grande vantagem da sobrecarga e o uso do mesmo nome para fun co es/m etodos que ir ao receber como par ametros objetos de tipos diferentes. Vimos que a sobrecarga ocorre quando os par ametros t em tipo diferente ou n umero de par ametros diferente. Em alguns casos a sobrecarga pode apresentar ambig uidade; normalmente isto ocorre em fun ca o das convers oes impl citas de tipo.

14.6

Exerc cios

1. Fa ca as modica co es necess arias para que o programa da listagem 13.1 tenha todos os m etodos com o mesmo nome (e funcione). 2. Implemente a classe CRetangulo descrita na Se ca o 13.10. N ao se esque ca de fazer o diagrama de classes no umbrello. Inclua o uso de m etodos sobrecarregados.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 15

Ponteiros, Refer encias e Gerenciamento de Mem oria


Uma das grandes vantagens de C++ em rela ca o a outras linguagens de programa ca o e sua capacidade de fornecer ao programador um controle renado da mem oria consumida pelo programa. Isto e poss vel gra cas ao seu mecanismo de gerenciamento de mem oria din amica por meio do uso dos operadores de new e delete. Veremos neste cap tulo os ponteiros (Se ca o 15.2), a utiliza ca o destes para criar e usar objetos din amicos (Se ca o 15.3); o uso do operador new (Se ca o 15.3.1); o uso do operador delete (Se ca o 15.3.2); o ponteiro this (Se ca o 15.4); os ponteiros const (Se ca o 15.5); a utiliza ca o de refer encias (Se ca o 15.6); as diferen cas entre refer encia e ponteiro (Se ca o 15.6.1) e o uso de refer encias para ponteiros (Se ca o 15.6.2). Veremos ainda conceitos b asicos de gerenciamento de mem oria (Se ca o 15.7), como alinhamento (Se ca o 15.7.2), e d uvidas freq uentes no uso de new e delete (Se ca o 15.7.3). Conceitos avan cados de ponteiros ser ao descritos no Ap endice F Ponteiros Uso Avan cado. Veremos as opera co es com ponteiros (Se ca o F.1), o uso de ponteiro void* (Se ca o F.2) e de ponteiro para ponteiro (Se ca o F.3); a convers ao de ponteiros (Se ca o F.4) e o uso de auto_ptr (Se ca o F.5); como implementar ponteiro de fun ca o (Se ca o F.6); ponteiros para m etodos e atributos da classe (Se ca o F.7); e o uso de ponteiros em hierarquias (Se ca o F.8). Nota: o uso de ponteiros j a e conhecido por quem programa em C. As novidades deste cap tulo est ao associadas ao uso de const, new e delete e ao uso de refer encias.

15.1

Prot otipo para declarar e denir ponteiros e refer encias

Ponteiros s ao objetos cujo conte udo e o endere co de outros objetos. Para declarar ponteiros, precedemos o nome do objeto pelo asterisco *, ou seja, para um tipo T, T* e um ponteiro. Uma refer encia pode ser encarada como um outro nome para um objeto, um apelido. Para declararmos uma refer encia colocamos Tipo& nomeDaRefer^ encia. Note que toda refer encia precisa ser inicializada na sua declara ca o. O operador &, como em &objeto, retorna o endere co do objeto, uma refer encia para o objeto. Veja o prot otipo a seguir. Observe que e boa pr atica de programa ca o inicializar todo ponteiro com o valor 0 (zero) ou com NULL. Note ainda que algo deve ser do tipo Tipo: 299

300

15.2. PONTEIROS

Ponteiro

Objeto

&obj ptr

3 obj

int main() { int obj = 3; int* ptr; // (P1) ptr = &obj; // (P2) cout << obj << endl; cout << *ptr << endl; // P(3) return 0; }

Figura 15.1: Ilustra ca o da cria ca o e uso de ponteiros. Prot otipo: Tipo * ponteiro = 0; // Cria o ponteiro (1) Tipo objeto; // Cria o objeto ponteiro = &objeto; // Coloca o endere co do objeto no ponteiro (2) *ponteiro = algo; // Usa o ponteiro armazenando algo no objeto (3) // Cria uma refer encia para o objeto Tipo & nomeRefer encia = &objeto;

15.2

Ponteiros

O procedimento de cria ca o e uso de um ponteiro tem tr es etapas (veja Figura 15.1). Primeiro, cria-se o ponteiro (P1). Em seguida, coloca-se no ponteiro o endere co do objeto para o qual ele vai apontar, usando o operador endere co de & (P2). Finalmente, utiliza-se o ponteiro, usando o operador desreferencia * (P3). Na pr atica, os ponteiros s ao utilizados para substituir os objetos originais. Sua vantagem est a associada ao seu pequeno tamanho. Assim, passar um ponteiro como par ametro de um m etodo e mais r apido e econ omico que passar uma c opia do objeto (veja Se ca o 13.6). Vamos explicar o funcionamento e a utiliza ca o dos ponteiros por meio de um exemplo hipot etico. Digamos que o sistema de armazenamento de objetos em um programa funcione como o correio. A entrega de um pacote precisa do endere co de destino e de um carteiro, isto e, o carteiro deve pegar um valor e armazen a-lo no objeto. Para realizar este trabalho, o carteiro precisa do valor (ou seja, um pacote para entregar) e do endere co do objeto onde o valor deve ser armazenado (endere co de entrega). Quando voc e faz x = 3, est a dizendo para o carteiro pegar o valor 3 e levar at e a casa de x. Um ponteiro pode ser imaginado como um endere cador indireto para o objeto. Veja o exemplo a seguir, o qual e ilustrado na Figura 15.2. Cria objeto do tipo int, com nome x. O endere co de x e sua posi ca o na mem oria do computador; admita que o endere co de x e 1503. Exemplo: int x; // Figura 15.2 (a)

Diz para o carteiro levar o valor 3 at e a casa de x (no n umero 1503). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

E USO DE OBJETOS DINAMICOS 15.3. CRIAC AO COM PONTEIROS x = 3; // Figura 15.2 (b)

301

Constr oi um objeto ponteiro, do tipo int*, com nome ptr. Conte udo de ptr = NULL. int* ptr = NULL; // Figura 15.2 (P1) (c)

Pega o endere co de x (1503) e o armazena na casa de ptr, o mesmo que ptr = 1503. ptr = & x ; // Figura 15.2 (P2) (d)

O carteiro pega o valor 7, vai at e a casa de ptr, chegando a , ele encontra o endere co de x e recebe instru ca o para levar o pacote at e x. Em seguida, ele leva o valor 7 at e x. *ptr = 7; // Figura 15.2 (P3)

Memria do seu computador Memria do seu programa Memria de outro programa ....

.... Endereo de x = 1503

x = lixo

....

.... Endereo ptr=2673

x = 3 ptr=NULL

....

....

x = 3 ptr=1503

....

....

x = 7 ptr=1503

....

int main() { int x; // (a) x = 3; // (b) int * ptr = NULL;// (c) ptr = &x; // (d) *ptr = 7; // (e) std::cout << *ptr; return 0; }

Figura 15.2: Como declarar e usar um ponteiro. Note que para obter o endere co do objeto x, utiliza-se o operador de endere co (&), tamb em chamado operador refer encia. Para utilizar o ponteiro para acessar o objeto x, utiliza-se o operador desrefer encia (*ptr). A constante NULL e predenida com o valor 0. NULL e 0 s ao utilizados para zerar os ponteiros. Veremos a seguir como os ponteiros s ao usados para criar e manipular objetos criados em tempo de execu ca o (objetos din amicos).

15.3

Cria c ao e uso de objetos din amicos com ponteiros

Os ponteiros s ao utilizados na sua ess encia para criar, usar e apagar objetos dinamicamente. Mas por que devo usar objetos din amicos? A utiliza ca o de objetos din amicos possibilita ao programador ter um controle mais eciente e ex vel da mem oria utilizada. Quando os objetos s ao alocados durante a compila ca o, o programador deve denir previamente o tamanho deles. No exemplo a seguir e criado um vetor de C para armazenar uma string com 50 caracteres. char nome[50]; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

302

E USO DE OBJETOS DINAMICOS 15.3. CRIAC AO COM PONTEIROS

Mas o que acontece se o nome tiver mais de 50 caracteres? Ocorrer a um estouro de pilha (acesso a mem ` oria inv alida) e o seu programa ir a travar. E se o nome tiver apenas 20 caracteres? Ent ao voc e estar a desperdi cando 30 caracteres. Para evitar o estouro de pilha e o desperd cio de mem oria utilizam-se os objetos din amicos. Os objetos din amicos s ao alocados (criados) com o operador new (Se ca o 15.3.1) e usam o bloco de mem oria disponibilizado pelo sistema operacional (pilha ou heap ). Em seguida, s ao usados e, ent ao, devem ser destru dos utilizando-se o operador delete (Se ca o 15.3.2).

15.3.1

O operador new

O operador new e utilizado para alocar dinamicamente um bloco de mem oria. Primeiro new solicita ao sistema operacional um bloco de mem oria. Ap os alocar o bloco de mem oria, new retorna um ponteiro para o bloco alocado. Se new falhar, retorna um bad_aloc (veja Cap tulo 26 Exce co es). Veja a seguir o prot otipo para usar new. Observe que new Tipo cria um objeto do tipo Tipo, e new Tipo [dimens~ ao] cria um vetor de objetos. Prot otipo: Tipo* ptrObjeto = new Tipo ; Tipo* ptrVetor = new Tipo [dimens ao]; No exemplo que segue criamos um objeto inteiro com new e armazenamos o endere co em ptrInt. Exemplo: int * ptrInt = NULL; // Cria o ponteiro ptrInt = new int; // Aloca bloco de mem oria e cria objeto if( ptrInt == NULL ) // Se ocorreu erro na aloca c~ ao sai do programa cerr < < "Erro aloca c~ ao ptrInt" < < endl; ... usa ptrInt ... Neste outro exemplo criamos um vetor de caracteres e armazenamos o endere co em nomePessoa. Exemplo: char * nomePessoa = NULL; nomePessoa = new char [tamanhoNecess ario + 1]; if( nomePessoa == NULL ) cerr < < "Erro aloca c~ ao nomePessoa" < < endl; ... usa nomePessoa ... Nota: a macro NULL e denida no arquivo de cabe calho <cstdlib> e em outros cabe calhos de C. Nota: veremos na Se ca o 26.8.1 o uso de new (nothrow) e sua rela ca o com exce co es.

15.3.2

O operador delete

Para destruir o objeto e devolver a mem oria para o sistema operacional, utiliza-se o operador delete. Para deletar um vetor use delete [] ptrVetor;. Observe que apenas o bloco de mem oria e destru do. O ponteiro continua existindo e apontando para o bloco de mem oria que agora n ao existe mais, ou seja, depois de usar delete ptrObjeto, o ponteiro aponta para um monte de lixo e n ao deve ser utilizado. Depois de deletar o objeto e boa pr atica de programa ca o atribuir o valor NULL para o ponteiro. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

E USO DE OBJETOS DINAMICOS 15.3. CRIAC AO COM PONTEIROS

303

Se zermos uma analogia com vari aveis comuns, inicializar ou setar o conte udo do ponteiro com NULL equivale a denir um valor inicial para uma variv avel qualquer (como um int), ou seja, n ao existe muito sentido em termos vari aveis em nosso programa cujo conte udo e um monte de lixo. Prot otipo: delete ptrObjeto; ptrObjeto = NULL; delete [] ptrVetor; ptrVetor = NULL; No exemplo a seguir os ponteiros criados na Se ca o 15.3.1 s ao destru dos. Exemplo: delete ptrInt; delete [] nomePessoa; Veja no exemplo da listagem 15.1 a utiliza ca o de objetos din amicos com ponteiros. A listagem inicia-se com a inclus ao da biblioteca <iostream> para entrada e sa da de dados, incluindo ainda a classe CPonto (listagem 13.5). Observe que arquivos da biblioteca s ao inclu dos usando-se <> (est ao dentro do diret orio-padr ao para arquivos de inclus ao; exemplo, /usr/include), e arquivos do programador s ao inclu dos usando-se (est ao no diret orio de trabalho). Na linha 9 criamos um ponteiro para CPonto (CPonto*), e o igualamos a NULL. Na linha 11 o objeto e alocado com new CPonto, note que new retorna o endere co do objeto criado para o ponteiro (agora o ponteiro aponta para o objeto criado). Na linha 12 vericamos a aloca ca o com if(ptr == NULL). Depois de criado o objeto din amico, o objeto e utilizado, ptr->Set(x, y);, ptr->Desenha();. Compare este exemplo com o apresentado na listagem 13.7; naquele utiliz avamos mecanismos est aticos para criar o objeto CPonto; neste usamos mecanismos din amicos. Listing 15.1: Usando ponteiros para criar e usar objetos din amicos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # include < iostream > # include " CPonto . h " using namespace std ; // E x e m p l o de c r i a c~ a o e uso do objeto CPonto int main () { int x = 6; int y = 7; CPonto * ptr = NULL ; ptr = new CPonto ; if ( ptr == NULL ) { cout << " Falha aloca ca ~o . " return 1; } ptr - > Set (x , y ) ; ptr - > Desenha () ; int xx = ptr - > X () ; delete ptr ; return 0; }

// // // //

Cria p o n t e i r o para objeto do tipo CPonto Cria objeto do tipo CPonto e coloca e n d e r e c o em ptr . Testa a l o c a c~ ao

<< endl ;

// // // // // //

Chama m e todo Set () do objeto ptr Chama m e todo D e s e n h a () Chama m e todo X () que r e t o r n a x Destr~ o e o objeto a p o n t a d o por ptr Encerra o programa ptr sai de escopo e e destru do

[ b u e n o @ l d s c 0 5 Cap -15] $ make P r o g C P o n t o D i n a m i c o g ++ -g - O2 -o P r o g C P o n t o D i n a m i c o P r o g C P o n t o D i n a m i c o . o CPonto . o [ b u e n o @ l d s c 0 5 Cap -15] $ ./ P r o g C P o n t o D i n a m i c o TPonto : Coordenada x =6 TPonto : Coordenada y =7

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

304

15.4. PONTEIRO THIS

Observe que com objetos est aticos usa-se nomeobjeto.atributo, e com objeto din amicos, troca-se o ponto (.) pela seta (->) nomeobjeto->atributo. Se voc e deseja acessar um m etodo de um objeto din amico, pode usar uma das duas op co es que seguem: Exemplo: ptr->M etodo(); *ptr.M etodo(); Otimiza c ao: toda opera ca o de aloca ca o com new e desaloca ca o com delete tem um custo em termos de tempo de processamento. Se o desempenho do programa e importante, ent ao deve ser feita uma otimiza ca o do programa com o objetivo de reduzir as o n umero de opera co es com new e delete.

15.4

Ponteiro this

Na parte de an alise orientada a objeto (Cap tulo 3 Conceitos B asicos de POO), vimos que a classe e denida como uma f abrica de objetos e que e a classe que dene a forma do objeto. Vimos ainda que, quando se cria um objeto, e reservado espa co na mem oria para inclus ao de todos os atributos n ao est aticos do objeto e n ao e reservado espa co para os m etodos. Assim, um objeto na mem oria do computador cont em somente atributos (veja as Figuras 12.1 e 12.2). Os m etodos n ao s ao criados para cada objeto; eles cam armazenados na classe. Isto faz sentido, pois dois objetos da mesma classe ter ao atributos diferentes, mas os m etodos ser ao os mesmos. Quando um objeto acessa um de seus m etodos, ele est a acessando os m etodos da classe. Como os m etodos s ao os mesmos para todos os objetos da classe e necess ario um dispositivo de identica ca o de qual objeto est a acessando o m etodo. Esse dispositivo e implementado por meio do ponteiro this. Por meio deste, o m etodo da classe sabe qual objeto o est a acessando. Veja a seguir um exemplo de m etodo que usa o ponteiro impl cito this para acessar o atributo x. Exemplo: class CPonto { int x, y; public: int X(int _x) { x = _x ; } int X() { return this->x; } }; int main() { CPonto objeto; int vx = 4; objeto.X(vx); cout < < objeto.X(); return 0; }

// Atributos // M etodo que seta x // M etodo que retorna x // Uso de this

// Cria objeto // Acessa m etodo int X(int) da classe CPonto // Acessa m etodo int X() da classe CPonto

O compilador traduz a sua chamada ao m etodo X(int) da seguinte forma: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

15.5. PONTEIROS CONST E PONTEIROS PARA CONST Exemplo: X(const Tipo* this = &objeto, vx);

305

// Tradu c~ ao para C

Ou seja, this e um ponteiro para o objeto que e passado implicitamente para o m etodo. Exemplo: this = &objeto;

// this cont em o endere co do objeto.

Observe que, quando um objeto chama um m etodo da classe, ele passa para o m etodo o seu endere co por meio do ponteiro this. Dessa forma, ao utilizar um atributo x, na realidade o m etodo est a utilizando this->x. Assim, this e um ponteiro que e passado implicitamente a um m etodo da classe, informando qual objeto o est a acessando. Um ponteiro this da classe T e do tipo T* const, isto e, aponta sempre para o mesmo objeto. Um m etodo est atico n ao recebe um ponteiro this, ou seja, n ao sabe qual objeto est a acessando. Este e o motivo pelo qual um m etodo est atico s o pode acessar atributos est aticos. Se um m etodo e const, seu ponteiro this e do tipo const T* const, isto e, aponta sempre para o mesmo objeto, e este n ao pode ser alterado. Exemplo com uso de this e apresentado na listagem 17.2.

15.5

Ponteiros const e ponteiros para const

A palavra-chave const e utilizada para informar que o objeto e constante, n ao muda. Pode ser utilizada com ponteiros, signicando que o ponteiro aponta sempre para o mesmo local de mem oria ou que o objeto apontado n ao muda, ou ambos. Entenda a seguir as diferentes formas de uso de const com ponteiros.

15.5.1

Ponteiro para um objeto constante

O conte udo do objeto apontado e constante, mas o ponteiro pode ser utilizado para apontar para outros objetos. Exemplo: int a = 1; int b; const int *ptrC = &a; b = *ptrC; *ptrC = 6; ado e const ptrC = &b;
&a ptrC b =1 a=1

// // // //

Cria ponteiro para const int que aponta para a. Ok, b recebe o conte udo de a Erro, ptrC n~ ao pode ser desreferenci-

// Ok, ponteiro aponta para b


&b ptrC b =1 a=6 ptrC pode apontar para a ou b, mas no pode mudar o contedo de a ou b.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

306

15.6. REFERENCIAS (&)

15.5.2

Ponteiro constante

Quando o ponteiro aponta para o mesmo local da mem oria, o objeto apontado pode ser alterado. Exemplo: int a = 3; int b = 4; int* const cPtr = &a; b = *cPtr; *cPtr = 5; cPtr = &b; jeto.
&a cPtr b =4 a=3

// // // //

Ok, cria o ponteiro e inicializa Ok, b recebe o conte udo de a (b = 3) Ok, a recebe o valor 5 (a = 5) Erro, cPtr aponta sempre para o mesmo ob-

&a cPtr

a=5

b =4

cPtr pode mudar o contedo de a. Mas no pode apontar para b.

15.5.3

Ponteiro constante para um objeto constante

Neste caso tanto o ponteiro como o objeto apontado n ao podem ser alterados. Exemplo: double a = 3.1415; const double * const cPtrC = &a; double b = 7.2; *cPtrC = 6.2; // Erro, o conte udo do objeto apontado n~ ao pode mudar cPtrC = &b; // Erro, cPtrC aponta sempre para o mesmo endere co
&a cPtrC b =7.2 a = 3,1415 &a cPtrC b =4 a=5 cPtrC no pode apontar para b, nem mudar o contedo de a.

15.6

Refer encias (&)

Uma refer encia pode ser encarada como um outro nome para um objeto, um apelido. Ela deve ser denida uma u nica vez, dessa forma apontar a sempre para o mesmo local da mem oria (para o mesmo objeto). Na pr atica refer encias s ao utilizadas como par ametros de m etodos e fun co es. Veja Se ca o 13.6. Refer encias para ponteiros costumam ser utilizadas como par ametros de m etodos. Uma refer encia n ao pode ser alterada para referenciar outro objeto ap os sua inicializa ca o (ou seja, uma refer encia se comporta como um ponteiro constante). Como as refer encias n ao s ao objetos, n ao podem existir matrizes de refer encias. Com rela ca o ` as refer encias n ao podemos: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

15.6. REFERENCIAS (&) N ao podemos declarar refer encias de refer encias. N ao podemos declarar refer encias para membros de classe. N ao podemos declarar um ponteiro para uma refer encia. N ao podemos declarar um array de refer encias. Veja a seguir o prot otipo e um exemplo de uso de refer encias. Prot otipo: Tipo & nomeRefer encia = &objeto; Exemplo: int v1 = 5; int algo = 3; int v2; // Declara uma refer^ encia a v1, ou seja, refV1 e o mesmo que v1 int& refV1 = v1; // Para armazenar v1 em v2 v2 = refV1; // Para armazenar algo em v1 usando a refer^ encia refV1 = algo; // O endere co da refer^ encia e igual ao endere co do objeto referenciado. // Armazena endere co de v1 em ptr int* ptr = &refV1; A listagem 15.2 mostra o uso de refer encias. Listing 15.2: Usando refer encias.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # include < iostream > using namespace std ; int main () { int x = 3; // tipo = int , nome =x , valor =3 int & ref = x ; // tipo = r e f e r ^ e n c i a para inteiro , nome = ref , valor = x // Daqui para frente , ref e a mesma coisa que x . cout << " Valor de x = " << x << " \ tValor da ref = " << ref << endl ; ref = 156; cout << " Mudou ref " << endl ; cout << " Valor de x = " << x << " \ tValor da ref = " << ref << endl ; x = 6; cout << " Mudou x " << endl ; cout << " Valor de x = " << x << " \ tValor da ref = " << ref << endl ; return 0; } bash -3.00 $ Valor de x Mudou ref Valor de x Mudou x Valor de x ./ a . out = 3 = 156 = 6

307

Valor da ref = 3 Valor da ref = 156 Valor da ref = 6

Vimos na Se ca o 13.6 a passagem de par ametros em m etodos, incluindo o uso de refer encias. Reveja a listagem 13.2. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

308

2 15.7. CONCEITOS BASICOS DE GERENCIAMENTO DE MEMORIA

15.6.1

Diferen cas entre refer encia e ponteiro

Uma refer encia n ao reserva espa co na mem oria para si pr opria, ao contr ario dos ponteiros, que reservam um espa co na mem oria. Observe que existe ponteiro de ponteiro (veja Se ca o F.3), mas n ao existe refer encia de refer encia.

15.6.2

Refer encias para ponteiros

Voc e pode declarar uma refer encia para um ponteiro, ou seja, um outro nome para um ponteiro. Veja o exemplo que segue e a listagem 13.2. Exemplo: int x = 3; int * ponteiro = &x; Tipo * & referenciaDePonteiro = ponteiro;

15.7

Conceitos b asicos de gerenciamento de mem oria2

O desenvolvimento de softwares avan cados, principalmente o de softwares cient cos, requer um controle mais renado da mem oria utilizada pelo programa. Um dos pontos cr ticos em programa ca o cient ca e o eciente controle da rela c ao mem oria consumida versus tempo de processamento. Veremos nesta se ca o alguns conceitos b asicos de gerenciamento de mem oria. Nota: veremos na Se ca o 21.8 como sobrecarregar o operador new de C++.

15.7.1

Entendendo o uso de new/delete com vetores

Quando uso int* v = new int[n]; aloco um vetor de inteiros de tamanho n. Posteriormente deleto o bloco de mem oria com delete [] v. A pergunta e: como o compilador sabe o tamanho do bloco a ser deletado? A maioria dos compiladores coloca, imediatamente antes da casa v[0], um espa co para um unsigned int (ou similar), no qual o tamanho n e armazenado. Note que se o vetor armazenar objetos grandes, o espa co consumido para armazenar a dimens ao do vetor continuar a sendo provavelmente do tamanho de um unsigned int. Veja Figura 15.3.

15.7.2

Alinhamento

Vamos iniciar nossa discuss ao apresentando um exemplo e uma pergunta. Na listagem 15.3, por que o sizeof(C1) e diferente de sizeof(C2)? Listing 15.3: Entendendo o alinhamento.
1 2 3 4 5 6 7 8 9 # include < iostream > using namespace std ; class C1 { char ca ; int x ; char cb ;}; class C2 { char ca ; char cb ; int x ;}; class C3 { char ca ; char cb ; char cc ; char cd ; int x ;}; int main () {

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

2 15.7. CONCEITOS BASICOS DE GERENCIAMENTO DE MEMORIA

309

Figura 15.3: Consumo real de mem oria de um vetor de inteiros.


int * v = new int[n]; A dimenso do vetor armazenada na posio v[-1]. Desta forma, delete [] v; sabe o tamanho do bloco a ser destrudo. v n v[0] v[1] v[2] v[3] sizeof(v) Bloco de memria solicitado v[4] ....... v[n-1]

Bloco de memria efetivamente alocado

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

C1 vC1 [10]; C2 vC2 [10]; C3 vC3 [10]; cout << " Consumo individual de C1 -> sizeof ( char ) *2 + sizeof ( int ) = " << sizeof ( char ) *2 + sizeof ( int ) << " \ nsizeof ( C1 ) = " << sizeof ( C1 ) << " \ tsizeof ( vC1 ) = " << sizeof ( vC1 ) << " \ n \ nConsumo individual de C2 -> sizeof ( char ) *2 + sizeof ( int ) = " << sizeof ( char ) *2 + sizeof ( int ) << " \ nsizeof ( C2 ) = " << sizeof ( C2 ) << " \ tsizeof ( vC2 ) = " << sizeof ( vC2 ) << " \ n \ nConsumo individual de C3 -> sizeof ( char ) *4 + sizeof ( int ) = " << sizeof ( char ) *4 + sizeof ( int ) << " \ nsizeof ( C3 ) = " << sizeof ( C3 ) << " \ tsizeof ( vC3 ) = " << sizeof ( vC3 ) << endl ; return 0; } Consumo individual de C1 -> sizeof ( char ) *2 + sizeof ( int ) = sizeof ( C1 ) = 12 sizeof ( vC1 ) = 120 Consumo individual de C2 -> sizeof ( char ) *2 + sizeof ( int ) = sizeof ( C2 ) = 8 sizeof ( vC2 ) = 80 Consumo individual de C3 -> sizeof ( char ) *4 + sizeof ( int ) = sizeof ( C3 ) = 8 sizeof ( vC3 ) = 80 6

A resposta e o alinhamento, um dos conceitos b asicos associados ao gerenciamento do consumo de mem oria. A id eia e simples: quando um bloco de mem oria e alocado, o mesmo e feito sempre em peda cos m nimos de bytes de tamanho m. Isto signica que, se alocamos um bloco de tamanho n, sendo n<m, o bloco que vai ser efetivamente alocado ter a tamanho m. O desperd cio ser a de m-n bytes. Observe na Figura 15.4(a) que cada objeto apresenta um desperd cio de mem oria em fun ca o do alinhamento de seus atributos. Note que o desperd cio com a cria ca o de C1 e maior do que com a cria ca o de C2, porque C2 tem um layout mais otimizado. A classe C3 tem o melhor aproveitamento da mem oria; n ao ocorre desperd cio com alinhamento. Lembre-se de que um char consome 1 byte, e um int, 4 bytes (na minha plataforma de 64 bits, processador AMD Opteron 64). Na sa da da listagem 15.3, vericamos que o consumo individual total dos atributos de C1 e de 6 bytes. J a o consumo da classe C1 e de 12 bytes e da classe C2 de 8 bytes. Ou seja, a Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

310

2 15.7. CONCEITOS BASICOS DE GERENCIAMENTO DE MEMORIA

Figura 15.4: Desperd cio de mem oria em fun ca o do alinhamento.


Um objeto: 1 ca 4 x 1 cb Um vetor de objetos: C1 desperdcio com alinhamento 1 ca 4 x 1 1 1 1 ca cb cc cd 4 x 1 cb C2 desperdcio com alinhamento C3 sem desperdcio

(a)

(b)

Objeto[0] atributos sizeof(Objeto)

Objeto[1] atributos

Objeto[2] atributos

.....

Desperdcio de memria com alinhamentos

declara ca o da classe C2 e mais econ omica, pois a ordem utilizada reduz a perda de mem oria provocada pelo alinhamento. Note que a classe C3 tem o melhor aproveitamento da mem oria. importante entender que podemos diminuir este desperd E cio mas n ao o evitar totalmente. A dica e simples: declare atributos do mesmo tipo em seq u encia. Em seguida, use o operador sizeof() para ver o tamanho efetivo da classe criada. Voc e pode reorganizar a ordem dos atribudos at e encontrar o menor sizeof() poss vel. Se tivermos um vetor de objetos, Figura 15.4(b), teremos um desperd cio maior, associado ao alinhamento entre os objetos. Isso tamb em depende do tamanho do objeto.

15.7.3

D uvidas frequ entes no uso de new, delete e gerenciamento de 2 mem oria

Veremos a seguir algumas d uvidas comuns associadas ao uso dos operadores new e delete e ao gerenciamento de mem oria, al em de algumas respostas curtas e diretas. D uvidas b asicas Se um ponteiro ptr tem valor NULL, qual o efeito de delete ptr? delete ptr n ao faz nada quando ptr == NULL. O comando delete ptr exclui o ponteiro ptr ou o dado apontado por *ptr? Exclui o dado; o ponteiro continua existindo. Posso deletar um bloco de mem oria alocado com new usando free? N ao. N ao podemos misturar o uso dos operadores de C++ new/delete com as fun co es de aloca ca o de C malloc() e free(). Veja a listagem ??. Um vetor de tamanho n e tipo T consome quanto bytes? Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

2 15.7. CONCEITOS BASICOS DE GERENCIAMENTO DE MEMORIA

311

Provavelmente n*sizeof(T) + sizeof(unsigned int), ou seja, o tamanho do bloco a ser utilizado mais o tamanho de um inteiro em que e armazenado o tamanho n do vetor criado. Veja Figura 15.3. 2 Ap os usar new, preciso realmente testar a aloca ca o com if(ptr != NULL)? N ao. Como visto no Cap tulo 26 Exce co es, quando new falha, ele lan ca exce co es que podem ser tratadas externamente (fora do bloco try). 2 Veremos como sobrecarregar o operador new na Se ca o 21.8. 2 Posso evitar que um objeto seja est atico? Sim, mas neste caso todos os construtores da classe CNome devem ser privados e voc e deve fornecer m etodos p ublicos e est aticos que criam objetos do tipo CNome usando new. Veja o exemplo a seguir; observe, dentro de main(), que precisamos chamar os m etodos p ublicos. Exemplo: class CNome { public: // M etodos p ublicos static CNome* New() { return new CNome(); } static CNome* New(int n) { return new CNome[n]; } static CNome* New(const CNome& obj) { return new CNome(obj); } // Construtores privados (n~ ao podem ser chamados) private: CNome(); CNome(const CNome& obj); }; int main() { CNome* p = CNome::New(); // Cria um objeto CNome* ptrV = CNome::New(10); // Cria um vetor de objetos delete p; delete ptrV; return 0; } D uvidas associadas ao uso de exce co es2 O que acontece se um construtor lan car uma exce ca o? O objeto e destru do, e a mem oria e devolvida para o sistemas operacional. O uso de set_new_handler(f)garante que a fun ca o denida f sempre ser a utilizada? N ao. Vimos na Se ca o 16.6.3 que objetos globais est aticos s ao constru dos antes da execu ca o de main(), ou seja, antes de executar set_new_handler(f). Isto signica que, se um objeto est atico chamar uma determinada fun ca o, que usa new, ser a utilizada a fun ca o new_handler padr ao do sistema e n ao a que denimos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

15.8. SENTENCAS PARA PONTEIROS, REFERENCIAS E GERENCIAMENTO DE 312 MEMORIA D uvidas associadas ao uso da STL21 O que s ao os gerenciadores de mem oria (ou alocadores) da STL? s ao objetos da STL utilizados para construir os containers. De modo geral, cada container tem um gerenciador de mem oria padr ao. Um container de tamanho n e tipo T consome quanto bytes? Depende do tipo de container e de informa co es associadas ao alinhamento dos atributos. A dica e simples: construa o container usando diferentes tipos de container e fa ca testes para ver qual consome menos mem oria. Qual container da STL e mais econ omico? O container mais econ omico e vector. Basicamente vector consome n*sizeof(T) + sizeof(int). N ao existe overhead em um vector. Em um container deque s ao criados diversos blocos de dados. O gerenciamento desses blocos implica em um pequeno aumento do consumo de mem oria (da ordem de 4%). Para saber o valor exato, construa um vector, um deque e veja a diferen ca no consumo de mem oria. Em uma lista <list>, veja Se ca o 32.2, cada elemento deve armazenar dois iteradores extras (veja Figura 32.3), ou seja, cada elemento da lista vai consumir pelo menos o tamanho do objeto armazenado mais o tamanho de dois iteradores. Os containers <set> e <multiset> trabalham com tr es ponteiros extras, ou seja, cada elemento do <set> vai consumir pelo menos o tamanho do objeto armazenado mais o tamanho de tr es iteradores. Os containers <map> e <multimap> tamb em trabalham com tr es ponteiros extras, mas neste caso s ao tr es pairs, de modo que first e a chave e second o valor, ou seja, cada elemento do <map> vai consumir pelo menos o tamanho do objeto armazenado mais o tamanho de tr es iteradores para pares pair<const key, T>. A dica de otimiza ca o de mem oria e: construa seu programa utilizando diferentes tipos de containers e verique qual o mais econ omico.

15.8

Senten cas para ponteiros, refer encias e gerenciamento de mem oria

Se o ponteiro aponta para NULL, o uso de delete ptr; n ao tem efeito. Se uma fun ca o retorna uma refer encia para um objeto, ela pode aparecer ` a esquerda do operador =. Exemplo: // Declara c~ ao e defini c~ ao de m etodo int & Valor(int &i){ return i; }; int x; Valor(x) = 234;
1 Veremos

a STL na Parte III: Introdu c ao a STL.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

15.9. RESUMO DO CAP ITULO

313

Evite retornar refer encias, ponteiros ou iteradores para atributos internos do objeto. Isto deixa o c odigo mais encapsulado. Em C a chamada a f(a,b) passa para f uma c opia de a e de b (a e b n ao ser ao alterados); a chamada a f2(&a,&b), por sua vez, passa para f2 ponteiros para a e b, indicando que a e b poder ao ser alterados. Em C++, a chamada a f(a,b) n ao informa se a e b ser ao necess passados por c opia ou por refer encia. E ario conferir isso no arquivo de declara ca o da classe. Se o par ametro de um m etodo/fun ca o e do tipo integral e n ao pode ser alterado, ele pode ser passado por c opia. Isto se justica porque os tipos integrais s ao copiados de forma muito r apida, sendo inclusive mais r apidos que o uso de refer encias. Ao criar objetos locais, usando new, verique se eles s ao destru dos. Para possibilitar a chamada de m etodos encadeados, o m etodo deve retornar um objeto (um lvalue). No exemplo a seguir o m etodo retorna uma refer encia ao pr oprio objeto. Exemplo: Tipo& CNomeClasse::M1() { return *this; } // Uso ( (obj.M1() ).M2() ).M3(); Em linguagens como Smalltalk e Java todos os objetos s ao acessados com ponteiros. Somente sobrecarregue new e delete como m etodos est aticos. 2 Lembre-se de que delete ptr executa operator delete(void*); j a delete[] ptr chama operator delete[] (void*). 3 Bugs : Digamos que voc e deseja passar um objeto como par ametro para um m etodo M etodo(nomeclasse obj). Como voc e est a passando o objeto por c opia, vai criar uma c opia do objeto. Depois vai usar o objeto dentro do m etodo e, ao encerrar o m etodo, o objeto ser a deletado. Se o objeto original tinha algum ponteiro com aloca ca o din amica, esse ponteiro ser a deletado, sendo deletado o bloco de mem oria por ele acessado. Assim, o ponteiro do objeto original aponta agora para um monte de lixo. Para que isso n ao ocorra, voc e deve passar uma refer encia do objeto, de forma que e passado o pr oprio objeto e n ao uma c opia deste, e, quando sair de escopo, o objeto n ao ser a eliminado. Outra solu ca o e sempre implementar o construtor de c opia (veja Se ca o 16.5.1).

15.9

Resumo do cap tulo

Normalmente o aprendizado de ponteiros em C e confuso e complicado. Isto ocorre porque C n ao tem o conceito de refer encias, e, portanto, tem-se de usar em demasia os ponteiros. Mais do que isto, e normal em C o uso excessivamente elaborado de ponteiros. Programadores experientes abusam dos ponteiros e deixam o c odigo ileg vel para os programadores comuns. A dica e: use e abuse dos ponteiros, mas n ao deixe o c odigo rebuscado demais isto atrapalha mais do que ajuda. Neste cap tulo aprendemos que um ponteiro e um objeto pequeno que armazena o endere co de outro objeto. Aprendemos a criar e usar objetos din amicos usando o operador new e a delet a-los usando o operador delete. A grande vantagem e que temos um controle renado Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

314

15.10. EXERC ICIOS

do uso da mem oria. Vimos ainda que o ponteiro oculto this e um ponteiro para o objeto que chamou o m etodo. Aprendemos a usar as diferentes varia co es de ponteiros com const. Aprendemos a utilizar as refer encias de C++ e suas diferen cas em rela ca o aos ponteiros. No nal do cap tulo, vimos os conceitos b asicos de gerenciamento de mem oria. Nota: o uso de vetores no estilo de C e apresentado no Ap endice H Vetores e Matrizes Arrays.

15.10

Exerc cios

1. Qual a vantagem do uso de ponteiros e aloca ca o din amica de mem oria? 2. Releia a listagem 13.1. 3. Explique com suas palavras o funcionamento de new e delete. 4. Explique com suas palavras o funcionamento de this. 5. Comece modicando a listagem 15.1. Acrescente objeto com uso normal de CPonto e compare os c odigos. 6. Monte um exemplo que use os conceitos apresentados na Se ca o 15.2. Justique a vantagem do uso de ponteiros const. 7. Crie um exemplo que utilize ponteiros normais, ponteiros para objetos que n ao podem mudar, e ponteiros que n ao podem ser usados para apontar outros objetos. 8. Para que servem as refer encias? 9. Monte um exemplo que inclua o uso de refer encias. 10. Quando o uso de refer encias para ponteiros e interessante? Monte um exemplo. 11. Crie exemplo que inclua o uso de um vetor de bool com n elementos. Um ponteiro deve ser utilizado para alocar dinamicamente o vetor, e para acessar seus elementos. O usu ario deve poder visualizar e modicar cada bit, tendo como base perguntas simples cuja resposta seja sempre verdadeiro/falso. 12. Crie exemplo que tenha a seguinte congura ca o: duas fun co es globais que incluam a cria ca o de objetos est aticos com valores predenidos (inicializados com 0). A cada vez que uma fun ca o e chamada, seus valores s ao atualizados (por exemplo contadores). Crie uma classe com um m etodo normal, mas que tenha par ametros predenidos, os quais devem ser inicializados com os valores das fun co es globais. Comente o exerc cio.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 16

M etodos Construtores e Destrutores


Descreveremos neste cap tulo a implementa ca o e uso dos m etodos construtores e destrutores. Faremos uma introdu ca o aos m etodos construtores e destrutores (Se ca o 16.1), suas caracter sticas e prot otipos (Se ca o 16.2). A seguir veremos o construtor default (Se ca o 16.3);a inicializa ca o dos atributos no construtor (Se ca o16.4); o construtor de c opia T(const T& obj) (Se ca o 16.5); quando um objeto e constru do/destru do (Se ca o 16.6); a ordem de constru ca o dos atributos de um objeto (Se ca o 16.6.1) e a ordem de destrui ca o dos atributos (Se ca o 16.6.2); a constru ca o de objetos globais est aticos (Se ca o 16.6.3); conceitos b asicos de construtor e ambig uidade (Se ca o 16.7). Veremos ainda temas avan cados na Se ca o 16.8, incluindo: construtor e ambig uidade (Se ca o 16.8.1) e construtor e interface (Se ca o 16.8.2).

16.1

Introdu c ao aos m etodos construtores e destrutores

Veremos nesta se ca o uma introdu ca o aos m etodos construtores e destrutores, isto e, suas caracter sticas. Caracter sticas dos m etodos construtores Nas listagens apresentadas at e aqui, ap os construir um objeto precis avamos iniciar os atributos; m etodo Entrada() na listagem 13.2, m etodo Inicializa() na listagem 13.3, m etodo Set() na listagem 13.5. N ao seria interessante se pud essemos ter m etodos especiais para iniciar os objetos automa exatamente isso o que fazem os construtores. ticamente quando os mesmos s ao constru dos? E Veja a seguir algumas caracter sticas dos construtores: Um m etodo construtor e um m etodo como outro qualquer; a diferen ca e que esse e automaticamente executado quando o objeto e criado. O objetivo b asico dos construtores e inicializar os atributos do objeto. Al em de inicializar os atributos do objeto, podemos realizar outras tarefas. Por exemplo: se sua classe representa uma impressora, voc e pode vericar se existe uma impressora conectada ao sistema. 315

316

16.2. PROTOTIPO PARA CONSTRUTORES E DESTRUTORES

Um m etodo construtor tem o mesmo nome da classe e n ao retorna nada, nem mesmo void. Por padr ao da linguagem, os m etodos construtores n ao podem ser const nem volatile. ca o Crie vari aveis din amicas no construtor com new e apague no destrutor com delete (Se 15.3). 2 Um construtor n ao pode ser virtual, mas pode ser sobrecarregado (veja Cap tulo 14 Sobrecarga de M etodos). Quando criamos um objeto (exemplo: CNome objeto;), a seq u encia de constru ca o e dada por: Solicita ca o de mem oria para o sistema operacional (para armazenar os atributos do objeto). Cria ca o dos atributos do objetos. Execu ca o do c odigo do construtor da classe. Caracter sticas dos m etodos destrutores Os m etodos destrutores t em o objetivo de destruir o objeto e devolver para o sistema operacional a mem oria alocada, fazendo o trabalho inverso do construtor. Veja a seguir algumas caracter sticas do destrutor: Tem o mesmo nome da classe antecedido pelo til (~). N ao retorna nada, nem mesmo void. N ao pode ter par ametros. N ao pode ser sobrecarregado. N ao pode ser static, const nem volatile. Em cada classe, devemos ter um u nico destrutor. Faz o trabalho inverso do construtor. Deve liberar a mem oria alocada no construtor e destruir os objetos din amicos. O destrutor e automaticamente executado quando o objeto sai de escopo.

16.2

Prot otipo para construtores e destrutores

Veja a seguir o prot otipo para declara ca o dos m etodos construtores e destrutores. Ao lado do prot otipo est a o n umero da se ca o em que o mesmo ser a discutido. Observe que o m etodo construtor tem o mesmo nome da classe e n ao retorna nada, nem mesmo void. O m etodo destrutor tamb em n ao retorna nada e tem o mesmo nome da classe precedido do til (~). Prot otipo: class CNome { CNome(); Programa ca o Orientada a Objeto com C++

// Construtor default, veja se ca o 16.3 Andr e Duarte Bueno

16.3. CONSTRUTOR DEFAULT T()

317

CNome(par ametros); // Construtor sobrecarregado, veja se ca o 16.3 CNome(const CNome & obj); // Construtor de c opia, veja se ca o 16.5 CNome(const CNome & obj, int=0); // Construtor de c opia, veja se ca o 16.5 Tipo(); // Construtor de convers ao, veja se ca o 25.3 CNome(); // Destrutor , veja se ca o 16.1 virtual CNome(); // Destrutor virtual, veja se ca o 19.2 }; // Implementa ca o dos construtores CNome::CNome(par ametros) : atributo1(valorInicial), atributo2(valorInicial),... // veja se ca o 16.4 {....c odigo do construtor.... } // Implementa ca o dos destrutores CNome::CNome() {....c odigo do destrutor.... }

16.3

Construtor default T()

Se voc e n ao criar um m etodo construtor, o compilador cria automaticamente um construtor vazio, que n ao recebe nenhum par ametro e e chamado de construtor default. Veja o prot otipo na Se ca o 16.2. No exemplo a seguir, o compilador cria um m etodo construtor default para a classe CNomeClasse. Exemplo: class CNomeClasse { int a; // O compilador cria automaticamente o construtor // a seguir, sem par^ ametros e vazio // CNomeClasse(){}; }; int main() { CNomeClasse obj2(); // ok, usa o construtor default. } Caso seja de seu interesse, voc e pode implementar o construtor default. class CNomeClasse { int a; public: CNomeClasse(){ a = 0; }; };

// (1)

Observe que, se voc e criar um construtor com par ametros, deixa de existir o construtor default. Exemplo: class CNomeClasse Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

318

DOS ATRIBUTOS DA CLASSE NOS CONTRUTORES 16.4. INICIALIZAC AO { int a; public: // Construtor criado CNomeClasse(int _a){ }; int main() { CNomeClasse obj1(5); CNomeClasse obj2(); }

pelo programador, recebe um int a = _a; }; // (2)

// ok, usa (2) // Erro, n~ ao existe um construtor default

Se na classe existirem atributos refer encias ou atributos const, o compilador n ao criar a o construtor default. Neste caso, voc e ter a de implementar o construtor default (sem par ametros). Isto ocorre porque voc e precisa inicializar os atributos const e as refer encias. Exemplo: class CNomeClasse { public: int a, b; const int c;

// Atributos normais // Atributo const // Construtor com par^ ametros CNomeClasse(int _a,int _b,int _c) : a(_a),b(_b),c(_c) {}; };

Um vetor no estilo de C s o pode ser contru do se a classe tiver um construtor default. Veja o exemplo: int main() { // Cria vetor de objetos do tipo CNomeClasse, com 30 elementos CNomeClasse vetorEstatico [30]; // ok, usa (1) return 0; } Se um atributo CX da classe CNomeClasse for um tipo do usu ario que n ao tem um construtor default, ent ao o construtor de CX deve ser explicitamente chamado. Crie sempre um construtor default, assim voc e evita problemas.

16.4

Inicializa c ao dos atributos da classe nos contrutores

Os atributos do objeto podem (e devem) ser inicializados no construtor, o prot otipo de inicializa ca o dos atributos da classe no construtor e dado a seguir. Depois do nome do construtor e de seus par ametros, observe o uso de : e, em seguida, a lista de atributos com seus valores separados por v rgula. Observe que, ao inicializar o atributo ap os :, este e inicializado na sua constru ca o, o que e mais r apido do que atribuir um valor ao atributo dentro do construtor. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

16.5. CONSTRUTOR DE COPIA T(CONST T& OBJ) Prot otipo: CNomeClasse(T1 v1, T2 v2,..,TN vn) :atributo1(v1),atributo2(v2),...,atributon(vn) { ..deni ca o do construtor.. };

319

No exemplo a seguir a op ca o (1) constr oe a e b e j a inicializa com _a e _b. A op ca o (2) e mais lenta primeiro constr oe a e b e depois atribue valores a = _a; b = _b;. Exemplo: class CNomeClasse { public: int a, b; const int c; // Atributos // Op c~ ao 1: Inicializa atributos ap os : CNomeClasse(int _a,int _b,int _c) : a(_a),b(_b),c(_c) {}; // Op c~ ao 2: Inicializa dentro do construtor CNomeClasse(int _a, int _b, int _c) :c(_c) { a = _a; b = _b; }; };

16.5

Construtor de c opia T(const T& obj)

Outro construtor bastante utilizado e o construtor de c opia, o qual e utilizado para criar uma c opia de um objeto existente (veja o prot otipo e o exemplo). Se voc e n ao criar um construtor de c opia e utilizar o operador de atribui ca o (=), ent ao o compilador ir a construir automaticamente o construtor de c opia. Veja no prot otipo a seguir que o par ametro recebido pelo construtor de c opia e um objeto da pr opria classe; o const informa que o objeto recebido n ao pode ser alterado, o que faz sentido pois estamos criando um objeto novo e nosso interesse e apenas copiar os atributos do objeto antigo para o novo. Prot otipo: CNomeClasse(const CNomeClasse & obj); No exemplo a seguir, o construtor de c opia e utilizado para construir os objetos p2 e p3 a partir de p1. Exemplo: CPonto p1;

// // CPonto p2 = p1; // // // CPonto p3(p1); // // CPonto p4; // p4 = p3; // if( p4 == p2 ) // {...}

Cria objeto do tipo CPonto com nome p1, utiliza o construtor default. Cria objeto do tipo CPonto com nome p2, utiliza o construtor de c opia, os atributos de p2 ser~ ao iguais aos de p1. Cria objeto p3, utiliza o construtor de c opia, os atributos de p3 ser~ ao iguais aos de p1 Cria objeto p4, utiliza o construtor default. Utiliza o operador =, igualando p4 a p3. Utiliza o operador ==, comparando p4 e p2.

Na listagem 16.1, mostra-se a utiliza ca o do construtor default e do construtor de c opia. Note que, tanto no construtor default como no de c opia, inicializamos os valores de nome, matricula Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

320

16.5. CONSTRUTOR DE COPIA T(CONST T& OBJ)

e iaa e enviamos uma mensagem para tela. Note que o construtor de c opia copia um a um os atributos do objeto. No destrutor decrementamos o n umero de objetos e enviamos mensagem para tela; o objetivo das mensagens e acompanhar os processos de constru ca o e destrui ca o (did atico). Observe que, para cada atributo, criamos dois m etodos um para deni ca o e outro para leitura do valor do atributo. Os m etodos de Entrada() e Saida() s ao utilizados para entrada e sa da de todos os dados do objeto. Outros coment arios s ao embutidos no texto. Observe na sa da que <vector> cria um objeto usando o construtor default : Criou objeto 2 construtor default . Em seguida, ele cria os objetos 3, 4 usando o construtor de c opia. Posteriormente, apaga o objeto criado com o construtor default Destruiu o objeto 4. Na pr atica, isso signica que voc e deve sempre criar um construtor de c opia. Observe que os atributos nome, matricula e iaa ( ndice de aproveitamento acumulado) s ao inicializados no construtor. ao criados utilizando o construtor de Note que, tanto o professor2 quanto o professor3, s c opia. Listing 16.1: Usando construtor default e de c opia.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # include < iostream > # include < string > # include < vector > using namespace std ; class CPessoa { private : string nome ; string matricula ; double iaa ; static int n u m e r o A l u n o s ; public : // C o n s t r u t o r default , c h a m a d o a u t o m a t i c a m e n t e // na c o n t r u c~ a o do objeto CPessoa () : nome ( " " ) , matricula ( " " ) , iaa (0) { n u m e r o A l u n o s ++; cout << " Criou objeto " << n u m e r o A l u n o s << " construto r default " << endl ; } // C o n s t r u t o r de c o pia , cria uma c o pia de um objeto e x i s t e n t e CPessoa ( const CPessoa & obj ) { nome = obj . nome ; matricula = obj . matricula ; iaa = obj . iaa ; n u m e r o A l u n o s ++; cout << " Criou objeto " << n u m e r o A l u n o s << " construto r de c o pia " << endl ; } ~ CPessoa () // M e todo Destrutor , c h a m a d a a u t o m a t i c a m e n t e { // na d e s t r u i c~ a o do objeto cout << " Destruiu objeto " << n u m e r o A l u n o s << endl ; numeroAlunos - -; } void void void void Entrada () ; Nome ( string _nome ) { Matricula ( string _m ) { Iaa ( double _iaa ) {

nome = _nome ; matricula = _m ; iaa = _iaa ;

} } }

void Saida () const ; string Nome () const string Matricula () const

{ {

return nome ; return matricula ;

} }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

16.5. CONSTRUTOR DE COPIA T(CONST T& OBJ)


44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 double Iaa () const { return iaa ; }

321

static int N u m e r o A l u n o s () { }; int CPessoa :: n u m e r o A l u n o s = 0;

return n u m e r o A l u n o s ;};

void CPessoa :: Entrada () { cout << " Entre com o nome : " ; getline ( cin , nome ) ; cout << " Entre com a matr cula : " ; getline ( cin , matricula ) ; cout << " Entre com o iaa : " ; cin >> iaa ; cin . get () ; } void CPessoa :: Saida () const { cout << " Nome do aluno : " << nome << " Matr cula : " << matricula << " iaa : " << iaa << endl ; } int main () { string linha = " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\ n " ; CPessoa professor ; // Usa c o n s t r u t o r d e f a u l t cout << " Entre com o nome do professor : " ; string nome ; getline ( cin , nome ) ; professor . Nome ( nome ) ; cout << " Entre com a matr cula do professor : " ; string matricula ; getline ( cin , matricula ) ; professor . Matricula ( matricula ) ; cout << " Entre com o n u mero de alunos da disciplina ( ex : 3) : " ; int n u m e r o A l u n o s ; cin >> n u m e r o A l u n o s ; cin . get () ; // Cria vetor do tipo C P e s s o a com nome aluno , usa c o n s t r u t o r d e f a u l t vector < CPessoa > aluno ( n u m e r o A l u n o s ) ; for ( int contador = 0; contador < aluno . size () ; contador ++) { cout << " Aluno " << contador << endl ; aluno [ contador ]. Entrada () ; } cout << linha << " RELA C~ A O DE PROFESSOR ES E ALUNOS : \ n " << linha ; cout << " Nome do professor : " << professor . Nome () << endl ; cout << " Matr cula : " << professor . Matricula () << endl ; for ( int contador = 0; contador < aluno . size () ; contador ++) { cout << linha << " Aluno " << contador << endl ; aluno [ contador ]. Saida () ; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

322
106 107 108 109 110 111 112 113 114 115 116 117 118

16.5. CONSTRUTOR DE COPIA T(CONST T& OBJ)

cout << linha << " N u mero de alunos = " << CPessoa :: N u m e r o A l u n o s () << endl ; cout << linha << " chamando : CPessoa professor2 ( professor ) ; " << endl ; CPessoa professor2 ( professor ) ; // Usa c o n s t r u t o r de c o pia professor2 . Saida ( cout ) ; { cout << linha << " chamando : CPessoa professor 3 = professor2 ; " << endl ; CPessoa professor 3 = professor2 ; // Usa c o n s t r u t o r de c o pia professor3 . Saida ( cout ) ; } // <- D e s t r o i professor3 , professor2 , alunos e p r o f e s s o r return 0; } Criou objeto 1 construto r default Entre com o nome do professor : Andr e Duarte Bueno Entre com a matr cula do professor : 123 Entre com o n u mero de alunos da disciplina ( ex : 3) : 2 Criou objeto 2 construto r default Criou objeto 3 construto r de c o pia Criou objeto 4 construto r de c o pia Destruiu objeto 4 Aluno 0 Entre com o nome do aluno : Danilo Marques Entre com a matr cula do aluno : 343 Entre com o IAA do aluno : 8 Aluno 1 Entre com o nome do aluno : Tiago Schaewer Entre com a matr cula do aluno : 123 Entre com o IAA do aluno : 9 ------------------------------------------------------RELA C~ A O DE PROFESSOR E S E ALUNOS : ------------------------------------------------------Nome do professor : Andr e Duarte Bueno Matr cula : 123 ------------------------------------------------------Aluno 0 Nome do aluno : Danilo Marques Matr cula : 343 IAA : 8 ------------------------------------------------------Aluno 1 Nome do aluno : Tiago Schaewer Matr cula : 123 IAA : 9 ------------------------------------------------------N u mero de alunos = 3 ------------------------------------------------------chamando : TPessoa professor2 ( professor ) ; Criou objeto 4 construto r de c o pia Nome do aluno : Andr e Duarte Bueno Matr cula : 123 IAA : 0 ------------------------------------------------------chamando : TPessoa professor 3 = professor2 ; Criou objeto 5 construto r de c o pia Nome do aluno : Andr e Duarte Bueno Matr cula : 123 IAA : 0 Destruiu objeto 5 Destruiu objeto 4 Destruiu objeto 3 Destruiu objeto 2

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

16.5. CONSTRUTOR DE COPIA T(CONST T& OBJ)

323

Figura 16.1: Por que devemos criar um construtor de c opia.


v1 ptr v2 ptr (a) ops! v2.ptr aponta para v1.ptr Cuidado! v1 ptr v2 ptr (b) v2 sai de escopo e destrudo Cuidado!!

v1 ptr v1.Saida() acessa o vetor que foi destrudo! v1 tenta destruir novamente o bloco CRASH! (c)

v1 ptr v2 ptr Soluo implementar o construtor de cpia (d)

Destruiu objeto 1

Nota: a listagem F.2 apresenta um problema que est a associado ` a falta do construtor de c opia.

16.5.1

Construtor de c opia e objetos din amicos

A Figura 16.1 mostra um problema t pico quando utilizamos atributos din amicos e esquecemos de implementar o construtor de c opia. O objeto v1 tem um ponteiro ptr que aponta para um bloco de mem oria que e alocado no construtor com new. Se criarmos um objeto v2 utilizando o construtor de c opia, o ponteiro v2.ptr vai apontar para o mesmo bloco de mem oria de v1.ptr (Figura 16.1(a)). O exemplo da listagem 16.2 mostra o problema. O exemplo e auto-explicativo. Na linha CVetor v1 (5); cria objeto do tipo CVetor, com nome v1 (Figura 16.1(a)), e, em seguida, mostra o vetor na tela. Na linha CVetor v2 = v1; cria o vetor v2, uma c opia de v1. Observe que v2.ptrV e v1.ptrV apontam para o mesmo bloco de mem oria (Figura 16.1(a)). Ap os executar v2.Saida(); o bloco em que v2 foi criado e destru do, e o destrutor de v2 e chamado. Note que o destrutor ir a deletar o bloco de mem oria (compartilhado) (Figura 16.1(b)). At e aqui nenhum problema. O problema ocorre quando chamamos v1.Saida(); O m etodo Saida() tenta acessar um bloco de mem oria que n ao existe mais; v1.ptrV aponta para um monte de lixo (Figura 16.1(c)). O que ocorre e indenido, provavelmente um bug a qualquer momento. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

324

16.5. CONSTRUTOR DE COPIA T(CONST T& OBJ)

Na mensagem de erro apresentada na sa da, o bug ocorre quando o destrutor de v1 e executado. O mesmo tenta destruir o bloco de mem oria compartilhado novamente. Listing 16.2: Problemas com a falta do construtor de c opia em objetos com atributos din amicos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 # include < iostream > using namespace std ; class CVetor { private : int dimensao ; int * ptrV ; public : void Saida () ; // Cria classe CVetor

// D i m e n s ~ a o do vetor // P o n t e i r o para o vetor

// C o n s t r u t o r d e f a u l t e ao mesmo tempo com par^ a metros , // aloca o vetor d i n a m i c a m e n t e . CVetor ( int n = 10) : dimensao ( n ) { cout << " Construtor default de CVetor : " << endl ; ptrV = NULL ; ptrV = new int ( dimensao ) ; if ( ptrV == NULL ) { cerr << " \ nFalha aloca ca ~ o " << ends ; exit (0) ; // E n c e r r a o p r o g r a m a } for ( int i = 0; i < dimensao ; i ++) ptrV [ i ] = i ; // P r e e n c h e v a l o r e s do vetor } virtual ~ CVetor () // D e s t r u t o r { cout << " Destrutor do vetor : " << endl ; delete [] ptrV ; } }; void CVetor :: Saida () { for ( int i = 0; i < dimensao ; i ++) cout << " " << ptrV [ i ] << " " ; cout << endl ; } int main () { CVetor v1 (5) ; // Cria objeto do tipo CVetor , com nome v1 cout << " Sa da de v1 . Saida () " << endl ; v1 . Saida () ; // Mostra o vetor na tela { CVetor v2 = v1 ; // Cria v2 , uma c o pia de v1 cout << " Sa da de v2 . Saida () ap o s CVetor v2 = v1 " << endl ; v2 . Saida () ; } // v2 sai de escopo e e deletado cout << " Sa da de v1 . Saida () ap o s dele ca ~ o de v2 " << endl ; v1 . Saida () ; // Efeito i n e s p e r a d o return 0; } // v1 sai de escopo e e d e l e t a d o ( BUG ) Construto r do vetor : Sa da de v1 . Saida ()

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

CONSTRU 16.6. QUANDO O OBJETO E IDO/DESTRU IDO


0 1 2 3 4 Sa da de v2 . Saida () ap o s CVetor v2 = v1 0 1 2 3 4 Destrutor do vetor : Sa da de v1 . Saida () ap o s dele ca ~ o de v2 0 0 2 3 4 Destrutor do vetor : *** glibc detected *** ./ a . out : double free or corruption ( fasttop ) : 0 x 0 0 0 0 0 0 0 0 0 0 6 0 2 0 1 0 *** ======= Backtrace : ========= / lib64 / libc . so .6[0 x39e486ea3 0 ] .... ./ a . out ( _ _ g x x _ p e r s o n a l i t y _ v 0 +0 x69 ) [0 x400a29 ] ======= Memory map : ======== 00400000 -00402000 r - xp 00000000 08:05 6059456 / home / bueno / Bueno / A p o s t i l a s P e s s o a i s / LivroCPP / listagens / Parte - II / a . out 7 fff7bb32000 -7 fff7bb4700 0 rw - p 7 fff7bb320 0 0 00:00 0 [ stack ] ffffffffff600 00 0 - f f f f f f f f f f e 0 0 0 0 0 --- p 00000000 00:00 0 [ vdso ] Abortado

325

A solu ca o para este problema e implementar manualmente o construtor de c opia, alocando a mem oria com new para os objetos din amicos (Figura 16.1(d)). Acrescente na classe CVetor (da listagem 16.2) o construtor de c opia apresentado a seguir. Observe que o novo objeto vai ter um vetor com a mesma dimens ao e os mesmos valores. Exemplo: CVetor::CVetor(const CVetor& obj) { // obj e this ter~ ao a mesma dimens~ ao this->dimensao = obj.dimensao; this->ptrV = NULL; // Cria um novo vetor para this this->ptrV = new int (this->dimensao); if(this->ptrV == NULL) { cerr < < "\nFalha aloca c~ ao" < < ends; exit(0);} // Copia os valores de v1 para this for(int i = 0; i < dimensao; i++) this->ptrV[i] = obj.ptrV[i]; } Nota: o objeto cerr e utilizado para enviar mensagens de erro para a tela, da mesma forma que cout. A diferen ca e que cerr n ao tem buer, sendo o texto enviado imediatamente para tela. A fun ca o exit(0) encerra a execu ca o do programa.

16.6

Quando o objeto e constru do/destru do

Vimos ao longo deste cap tulo uma s erie de m etodos construtores e destrutores. Uma pergunta que pode ser feita e: quando um objeto e criado e quando um objeto e destru do? Segundo [Lischner, 2003], as possibilidades s ao: Quando criamos um objeto autom atico. Exemplo: int x; CEndereco endereco; CAluno aluno; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

326

CONSTRU 16.6. QUANDO O OBJETO E IDO/DESTRU IDO

Quando criamos um objeto est atico. Exemplo: static int x; static CEndereco endereco; Quando criamos um objeto dinamicamente. Exemplo: const int dimensao = 10; int * ptrVetor = new int[dimensao]; Quando criamos objetos tempor arios. No exemplo a seguir a soma de 4+5 e armazenada em um objeto tempor ario, que e criado, usado para armazenar o valor 9, e, em seguida, usado para copiar o valor 9 para x. Vale lembrar que a cria ca o do objeto tempor ario e interna, transparente. Exemplo: int x = 4 + 5; Quando usamos retorno e par ametros de um m etodo. No exemplo a seguir quando entra no m etodo Metodo() o par ametro int x e criado. Quando o m etodo e encerrado, uma c opia de x e retornada. Exemplo: int CNomeClasse::Metodo(int x) {... return x; } Quando usamos convers oes impl citas. No exemplo a seguir, um n umero tempor ario do tipo int e criado e usado para armazenar o n umero 3 (o n umero utuante 3.1415 e truncado para 3); depois, este n umero tempor ario e copiado para x. Exemplo: int x = 3.1415; Quando usamos construtores com inicializadores. Exemplo: CCirculo::CCirculo(int _r,int _x,int _y): CPonto(_x,_y), r(_r){...} Todos os objetos anteriormente constru dos s ao destru dos quando os mesmos saem de escopo. A exce ca o ocorre quando usamos constru ca o din amica. Neste caso o objeto deve ser explicitamente destru do com delete.

16.6.1

Ordem de constru c ao dos atributos

A ordem de constru ca o dos atributos de uma classe e dada pela ordem em que os mesmos foram declarados, e n ao pela ordem passada para o construtor. Veja exemplo na listagem 16.3. Observe que a classe Y tem tr es atributos agregados do tipo X, e que os mesmos s ao declarados na ordem x1, x2, x3. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

CONSTRU 16.6. QUANDO O OBJETO E IDO/DESTRU IDO

327

A lista passada para o construtor da classe Y e dada por Y() : x2(2), x3(3), x1(1), mas observe na sa da que os objetos foram criados na ordem em que foram declarados; ou seja, vai criar x1 depois x2 e depois x3, mesmo que no construtor tenhamos colocado x2, x3, x1. Depois de construir seus atributos o construtor do objeto obj_y e executado. Listing 16.3: Ordem de constru ca o dos atributos de um objeto.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # include < iostream > using namespace std ; class X { public : X ( int n ) { cout << " Criou X : " << n << endl ; }; }; class Y { public : Y () : x2 (2) , x3 (3) , x1 (1) { cout << " Criou Y . " << endl ; }; private : X x1 , x2 , x3 ; // D e c l a r a os a t r i b u t o s na ordem x1 , x2 , x3 }; int main () { Y obj_y ; return 0; } Criou Criou Criou Criou X :1 X :2 X :3 Y.

16.6.2

Ordem de destrui c ao dos atributos

Quando um objeto e criado, s ao criados os atributos internos e depois e executado o corpo do construtor. Os atributos internos s ao criados na ordem em que foram declarados (veja Se ca o 16.6.1). A seq u encia de destrui ca o e inversa ` a da cria ca o, isto e, primeiro e executado o m etodo destrutor e depois s ao eliminados os objetos internos da classe, na ordem inversa a que foram declarados. Se for criado um vetor de objetos de tamanho n, a seq u encia de cria ca o e obj[0], obj[1], obj[2],..., obj[n-1] e a seq u encia de destrui ca o obj[n-1], obj[n-2], obj[n-3],..., obj[1], obj[0]. Exemplo: class V { int n; int * ptr; V(int _n = 30):n(_n),ptr(0) { ptr = new int (n); }; ~V() { delete [] ptr; };

// Construtor // Destrutor

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

328 }; int main() { V objeto; return 0; }

CONSTRU 16.6. QUANDO O OBJETO E IDO/DESTRU IDO

// Cria objeto // Objeto sai de escopo e e destru do

No exemplo anterior, dentro da fun ca o main() e criado um objeto do tipo V. Primeiro cria o atributo n e inicializa com 30 e, em seguida, cria o ponteiro ptr e inicializa com NULL. Depois e executado o corpo do construtor, que aloca mem oria para um vetor de 30 inteiros e armazena o endere co do bloco alocado em ptr. Quando o bloco de main() termina os objetos criados s ao destru dos, logo, o destrutor do objeto e executado. Na seq u encia de destrui ca o, primeiro e executado o corpo do destrutor, que deleta o conte udo do ponteiro; em seguida e eliminado o atributo ptr e posteriormente o atributo n. Observe que a ordem de destrui ca o e inversa a de constru ca o. A melhor maneira de entender a seq u encia de cria ca o e destrui ca o dos objetos e acompanhar a execu ca o passo a passo do programa em um debugger. No Dev-C++ (veja Figura 6.27), usa-se tulo ?? Como Evitar Bugs e Utilizar o Debuger da GNU (gdb), a fun ca o f7. Veja, no Cap como usar o debugger da GNU.

16.6.3

Constru c ao de objetos globais est aticos

Lembre-se de que um objeto global e um objeto criado fora do escopo das classes e fun co es globais. Exemplo: ..escopo global.. Retorno FuncaoGlobal(parametros){..escopo da fun c~ ao global..} ..escopo global.. class CNomeClasse{...escopo da classe..}; ..escopo global.. Retorno CNomeClasse::Metodo(parametros){..escopo do m etodo..} ..escopo global.. int main() {..escopo de main()..} Objetos globais est aticos s ao criados quando o programa e carregado (antes de main()) e destru dos quando o programa e encerrado. Isto signica que podemos criar uma fun ca o global e execut a-la antes de main() para iniciar um objeto est atico. Veja exemplo na listagem 16.4. Listing 16.4: Objetos est aticos globais.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # include < iostream > int f () // Fun c~ a o Global { std :: cout << " Executada antes de main () . " << std :: endl ; return 0; } // x e uma v a r i a v e l global e s t atica static int x = f () ; // que e i n i c i a l i z a d a com o r e t o r n o de f () int main () { std :: cout << " Ol a " << std :: endl ; return 0; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

16.7. CONSTRUTOR E AMBIGUIDADE


Executada antes de main () . Ol a

329

16.7

Construtor e ambigu idade

Uma ambig uidade ocorre quando o compilador n ao consegue identicar qual atributo ou m etodo deve ser acessado. O exemplo a seguir mostra uma ambig uidade hipot etica do dia-adia. Exemplo: /* Al o, com quem deseja falar? Com o Fernando. Mas qual Fernando, o Henrique ou o Collor?. */ De modo geral ocorrer a ambig uidade quando, no mesmo escopo, tivermos atributos ou m etodos com o mesmo nome. A verica ca o de ambig uidade e feita antes do controle de acesso, assim, o compilador primeiro verica se o objeto n ao e amb g uo e depois se pode ser acessado (Se ca o 14.3.1). As ambig uidades podem ser resolvidas explicitamente com o operador de resolu ca o de escopo (::) ou com o uso da palavra-chave using (Se ca o 10.3). Ao tentar compilar o exemplo da listagem 16.5, aparece uma mensagem de erro. Na linha (11) "X obj1(5);" o compilador cria o objeto obj1 usando o construtor sobrecarregado. Na linha (12) "X obj2;" o compilador ca em d uvida deve usar o construtor default ou o construtor sobrecarregado? A solu ca o deste problema e um dos exerc cios deste cap tulo. Listing 16.5: Erro ao denir o construtor default e um construtor sobrecarregado com inicializadores.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class X { int x ; public : // Sejam os c o n s t r u t o r e s : X () { }; // C o n s t r u t o r _ 1 ( d e f a u l t ) X ( int _x = 0) { x = _x ; }; // C o n s t r u t o r _ 2 ( s o b r e c a r r e g a d o ) }; int main () { X obj1 (5) ; X obj2 ; return 0; }; : In :14: :8: :7: function int main () : error : call of overloade d X () is ambiguous note : candidates are : X :: X ( int ) note : X :: X ()

// // // //

Se na t e n t a t i v a de criar um objeto voc^ e faz : Cria objeto 1 , usa c o n s t r u t o r _ 2 Ambig u idade , qual c o n s t r u t o r ? X () ou X ( int _x =0)

16.8

Construtor e destrutor conceitos avan cados2

Nesta se ca o veremos alguns conceitos avan cados de construtores e destrutores. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

330

2 16.8. CONSTRUTOR E DESTRUTOR CONCEITOS AVANCADOS

16.8.1

Construtor e ambigu idade

Por deni ca o do comite ANSI C++, quando o compilador ca em d uvida se uma determinada linha de c odigo signica a declara ca o de uma nova fun ca o ou a cria ca o de um objeto, por padr ao, assume que o programador est a declarando uma nova fun ca o e n ao criando um novo objeto. A listagem 16.6 mostra um exemplo. O programa inicia denindo uma classe T (observe que, quando o construtor e executado, ele envia uma sa da para tela). Em seguida mostra o problema das ambig uidades. A linha (18) T f1(); declara uma fun ca o f1() que n ao recebe nada e retorna T ou cria um objeto f1 do tipo T? Obedecendo o padr ao, estamos declarando uma fun ca o f1() que retorna T. A linha (21) T (obj1); cria um novo objeto, do tipo T, com nome obj1. A linha (26) T obj2(1); cria um novo objeto, do tipo T, com nome obj2, e usa construtor que recebe um int. A linha (34) T f3(T(x)); declara uma fun ca o f3(). Observe que podemos informar que queremos criar um objeto usando o cast (T obj3(static_cast<T>(x));). Listing 16.6: Construindo objetos ou declarando fun co es?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 // A m b i g u i d a d e : C o n s t r u i n d o o b j e t o s ou d e c l a r a n d o f u n c~ o e s? # include < iostream > class T // Cria uma classe T { // Acesso p ublico public : // C o n s t r u t o r e s T () { std :: cout << " \ tConstrut or T () \ n " ; } T ( int ) { std :: cout << " \ tConstrut or T ( int ) \ n " ; } }; int main () { int x ; // Fun c~ ao principal // Cria objeto do tipo int , com nome x

// A m b i g u i d a d e ? // D e c l a r a fun c~ a o f1 () , que n~ a o recebe nada e r e t o r n a T ? ou // Cria objeto f1 do tipo T ? std :: cout << " T f1 () ; -> Declara ca ~ o de fun ca ~ o . " << std :: endl ; T f1 () ; std :: cout << " T ( obj1 ) ; -> Cria obj1 , usa construtor T () " << std :: endl ; T ( obj1 ) ; // A m b i g u i d a d e ? std :: cout << " T obj2 (1) ; -> Cria objeto obj2 , do tipo T , " << " usa construtor T ( int ) " << std :: endl ; T obj2 (1) ; std :: cout << " T f2 ( int ) ; -> Declara fun ca ~ o f2 , retorna T , " << " argumento int sem nome " << std :: endl ; T f2 ( int ) ; // A m b i g u i d a d e ? std :: cout << " T f3 ( T ( x ) ) ; - > Declara fun ca ~ o f3 , retorna T , " << " e recebe T " << std :: endl ; T f3 ( T ( x ) ) ; std :: cout << " T obj3 ( static_cast <T >( x ) ) ; " << " -> Cria objeto obj3 , do tipo T " << std :: endl ; T obj3 ( static_cast <T >( x ) ) ; std :: cout << std :: endl ; return 0; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

2 16.8. CONSTRUTOR E DESTRUTOR CONCEITOS AVANCADOS

331

T f1 () ; -> Declara ca ~ o de fun ca ~o . T ( obj1 ) ; -> Cria obj1 , usa construtor T () Construtor T () T obj2 (1) ; -> Cria objeto obj2 , do tipo T , usa construtor T ( int ) Construtor T ( int ) T f2 ( int ) ; -> Declara fun ca ~ o f2 , retorna T , argumento int sem nome T f3 ( T ( x ) ) ; - > Declara fun ca ~ o f3 , retorna T , e recebe T T obj3 ( static_cast <T >( x ) ) ; -> Cria objeto obj3 , do tipo T Construtor T ( int )

16.8.2

Construtor e interface

Em alguns casos a classe e denida corretamente, mas um usu ario distra do pode criar o objeto de forma incorreta. Veja exemplo na listagem 16.7. Observe que o objeto e criado com o nome da cidade e da pessoa trocados. Um erro n ao detectado pelo compilador, porque nome e cidade s ao do tipo string, e o compilador diferencia os tipos e n ao os nomes. Este erro ocorre porque a interface (ou protocolo) de acesso ao construtor n ao impede que o usu ario entre com dados trocados. Listing 16.7: Construtor e interface: erro na passagem de par ametros.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # include < iostream > # include < string > using namespace std ; class CPessoa { int idade ; string nome ; string cidade ; public : CPessoa ( int i , string n , string c ) : idade ( i ) , nome ( n ) , cidade ( c ) {} }; int main () { // Erro na ordem de p a s s a g e m dos p a r ^ ametros CPessoa joao (32 , " Rio de Janeiro " , " Jo~ a o da Silva " ) ; return 0; }

Pode-se contornar este problema usando classes ou estruturas auxiliares. Veja o exemplo da listagem 16.8. Usamos struct porque SNome e SCidade n ao representam conceitos; s ao apenas estruturas auxiliares utilizadas para eliminar o problema. O uso de explicit ser a apresentado na Se ca o 25.5. Basicamente explicit garante que o construtor s o seja chamado explicitamente. Listing 16.8: Construtor e interface: erro na passagem de par ametros corrigidos.
1 2 3 4 5 6 7 8 9 10 # include < iostream > # include < string > using namespace std ; struct SNome { explicit SNome ( string n ) : nome ( n ) {}; string nome ; };

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

332
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

16.9. SENTENCAS PARA CONSTRUTORES E DESTRUTORES

struct SCidade { explicit SCidade ( string c ) : cidade ( c ) {}; string cidade ; }; class CPessoa { int idade ; string nome ; string cidade ; public : CPessoa ( int i , SNome n , SCidade c ) : idade ( i ) , nome ( n . nome ) , cidade ( c . cidade ) {} }; int main () { // Erro na p a s s a g e m de p a r ^ ametros corrigida // agora a p a s s a g e m dos p a r ^ a m e t r o s ficou mais clara CPessoa joao (32 , SNome ( " Jo~ a o da Silva " ) , SCidade ( " Rio de Janeiro " ) ) ; return 0; }

Veja a seguir outras dicas para classes de interface (reveja Se ca o 11.5.2): A interface de acesso a classe deve ser simples, pr atica e l ogica. Deve ter um controle rigoroso da entrada e sa da de dados (limites m nimos e m aximos de cada atributo). Os operadores-padr ao devem ser sobrecarregados (veja Cap tulo 21 Sobrecarga de Operador). As classes derivadas devem ter uma interface com a mesma l ogica da classe-base.

16.9

Senten cas para construtores e destrutores


Exemplo: { int x; }

Um objeto autom atico e constru do na sua deni ca o e destru do quando sai de escopo. // Objeto x e constru do // Objeto x sai de escopo e e destru do

Ao criar um vetor est atico de objetos, voc e e obrigado a utilizar o construtor default. Para utilizar um outro construtor, voc e ter a de criar os objetos um a um dinamicamente. No exemplo a seguir, utiliza-se um construtor sobrecarregado, que recebe uma lista de par ametros. Observe que os objetos s ao criados um a um, dinamicamente, dentro do for. Exemplo: CNomeClasse { public: CNomeClasse(){}; // Construtor default }; // Cria vetor est atico, com 30 objetos CNomeClasse vObjetos[30]; // Cria vetor com 50 ponteiros Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

16.9. SENTENCAS PARA CONSTRUTORES E DESTRUTORES CNomeClasse* vptrObj[50]; for ( int i = 0 ; i < 50 ; i++ ) vptrObj[i] = new CNomeClasse (parametros);

333

Em determinados casos e conveniente termos um m etodo de inicializa ca o, um m etodo utilizado para inicializar os atributos da classe e que pode ser chamado a qualquer momento para reinicializar os atributos com valores-padr ao, exemplo: Init();. Atributos est aticos da classe devem ser denidos fora da classe. Bugs um objeto autom atico, criado na avalia ca o de uma express ao, e destru do no m do bloco (ou do m etodo). Assim, n ao armazene nenhuma informa ca o (ponteiro, refer encia) em objetos autom aticos. O exemplo a seguir mostra um erro comum. Exemplo: int* f() { int x = 3; int * ptrX = &x; return ptrX; } // Aqui x e destru do e ptrX aponta para o lixo (um bug). Todos os atributos do objeto devem ser copiados um a um no construtor de c opia. Se um novo atributo for adicionado ` a classe, n ao esque ca de incluir sua c opia no construtor de c opia. A utiliza ca o de uma lista de inicializa ca o como no exemplo que segue n ao e permitida se voc e criou um construtor com par ametros e n ao existe um construtor default . Exemplo: Tipo a[] = { v1, v2, ..., vn }; Lembre-se de que o operador delete primeiro chama o m etodo destrutor do objeto e, em seguida, devolve a mem oria para o sistema operacional. Um objeto criado com new deve ser apagado com delete. N ao destruir um objeto alocado dinamicamente n ao causa um erro (bug ), mas e um desperd cio de mem oria. 2 O construtor de c opia e o operador de atribui ca o da classe derivada devem chamar o m etodo equivalente da classe-base. Veja o exemplo: Exemplo: Derivada& operator=( const Derivada& d ) { Base::operator=(d); this->atributo = d.atributo; } 2 O construtor de uma classe-derivada chama automaticamente o destrutor da classe-base. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

334

16.10. RESUMO DO CAP ITULO

2 O corpo de um destrutor e executado antes dos destrutores para os objetos membros. De maneira geral, a ordem de destrui ca o dos objetos e inversa ` a ordem de constru ca o (veja Se co es 16.6.2). 2 Como regra b asica, sempre declare o destrutor como virtual (veja Se ca o 19.2). 2 Se durante a execu ca o do programa e chamada a fun ca o exit(), os destrutores locais n ao ser ao executados e os globais sim. Se for chamada a fun ca o abort(), nenhum destrutor ser a executado. 2 Destrutores n ao devem lan car exce co es. Se um m etodo chamado pelo destrutor pode chamar uma exce ca o, o tratamento deve ser feito no destrutor. 2 O destrutor, assim como o construtor, n ao deve chamar m etodos virtuais. 2 Como vimos, quando n ao criamos um construtor, o compilador cria um. O mesmo ocorre para o construtor de c opia, o operador de atribui ca o e o destrutor. Todos esses m etodos, quando criados pelo compilador, s ao m etodos inline [Lischner, 2003]. 2 Se voc e criou um construtor de c opia, um operador de atribui ca o, ou um destrutor, ent ao voc e provavelmente precisa criar todos os tr es [Lischner, 2003]. Isto ocorre normalmente quando a classe tem membros de dados din amicos. 2 As classes containers da STL e a classe string n ao t em um destrutor virtual. Assim, tome cuidado no uso de heran ca dessas classes. No exemplo a seguir, delete ptr invoca o destrutor de string e n ao de MinhaString. Exemplo: class MinhaString: public std::string {...}; string * ptr = new MinhaString(); delete ptr; 2 Por default, se um construtor de uma classe X recebe um u nico argumento do tipo Y, este tamb em dene uma convers ao de Y para X. Para evitar a convers ao autom atica, use a palavra-chave explicit (veja Se ca o 25.5).

16.10

Resumo do cap tulo

Vimos que o m etodo construtor e utilizado para inicializar os atributos do objeto, podendo ainda realizar alguma atividade extra. Quando n ao criamos um construtor, o compilador cria um construtor vazio chamado construtor default, o qual n ao recebe nenhum par ametro. Vimos ainda que o construtor pode ser sobrecarregado, isto e, podemos ter mais de um construtor. Vimos que a implementa ca o do construtor de c opia, T(const T& obj), e importante principalmente quando o objeto tem atributos din amicos. Aprendemos a inicializar os atributos do objeto no construtor. A inicializa ca o dos atributos ap os : e mais r apido que a inicializa ca o dentro do bloco do construtor. Aprendemos ainda que a ordem de constru ca o dos atributos e a ordem em que os mesmos foram declarados. O destrutor faz o trabalho inverso, destr oi o objeto. Aprendemos que o m etodo destrutor deve ser u nico, de prefer encia virtual, e deve ser utilizado para destruir os atributos e nalizar o objeto. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

16.11. EXERC ICIOS

335

Aprendemos que a ordem de destrui ca o dos atributos de um objeto e inversa ` a ordem de constru ca o. Finalmente, aprendemos conceitos como ambig uidade e interface. Vimos que podemos eliminar problemas com a passagem dos par ametros do construtor usando estruturas de interface.

16.11

Exerc cios

1. Na listagem 16.1 acrescente um construtor que recebe todos os atributos do objeto. Com ele elimina-se a necessidade de se chamar os m etodos Set(). 2. Modique a listagem 16.1 acrescentando novos atributos. Por exemplo, acrescente o uso de CEndereco. 3. Comente em detalhes a listagem 16.2. 4. Acrescente a listagem 16.2 as corre co es indicadas na Se ca o 16.5.1. 5. Releia a listagem 13.3. 6. Releia a Se ca o 16.7 e corrija o problema da listagem 16.5. 7. Indique duas op co es para eliminar a ambig uidade na listagem 16.5. A seguir, implemente as modica co es sugeridas. 8. Modique a listagem 13.3 substituindo Inicializa() por um construtor. 9. Arrume a listagem 16.3 chamando os objetos na ordem em que s ao declarados. Em seguida, veja a sa da gerada. 10. Como os construtores podem ser sobrecarregados, podemos ter v arias formas para construir um objeto. Alguns programadores gostam de fornecer uma alternativa que passa pela deni ca o de todos os construtores como privados e o acesso a cada um deles usando um m etodo est atico e p ublico com nome diferente. Este m etodo e conhecido como Named Constructor Idiom. Como exerc cio, fa ca uma pesquisa por Named Constructor Idiom no Google. 11. Se um objeto do tipo CNome e constru do estaticamente no escopo global, ent ao ele e executado antes de main(). Isto deve ser evitado, pois se o construtor de CNome criar outros objetos est aticos, ent ao n ao existe garantia de que a seq u encia de cria ca o seja correta. Como exerc cio, fa ca uma pesquisa por Construct on First Use Idiom no Google.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

336

16.11. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 17

Heran ca
Vimos nas se co es 3.6 e 6.4.10 o conceito de heran ca; na Se ca o 6.4.10, vimos como identicar heran cas e na Se ca o 6.4.11, como descrever a heran ca usando UML. Neste cap tulo veremos como implementar heran cas em C++. Veremos o prot otipo para heran ca (Se ca o 17.1), o uso de heran ca simples (Se ca o 17.2) e o uso do especicador de heran ca (Se ca o 17.3). Ademais, veremos as diferen cas entre heran ca p ublica e heran ca privada (Se ca o 17.4); como usar using em heran cas (Se ca o 17.5); como chamar os construtores das classes-base explicitamente (Se ca o 17.6); a redeclara ca o de m etodo ou atributo na classe-derivada (Se ca o 17.7) e algumas senten cas para heran ca (Se ca o 17.8). No Cap tulo 18 Heran ca M ultipla, veremos como implementar o conceito de heran ca m ultipla.

17.1

Prot otipo para heran ca simples

O conceito de heran ca permite a cria ca o de uma classe-derivada a partir de uma classebase. A classe-derivada herda todos os atributos e m etodos da classe-base. Neste cap tulo vamos apresentar a utiliza ca o do conceito de heran ca em C++. Veja a seguir o prot otipo para implementar heran ca em C++: Nota: seria interessante neste momento voc e reler a Se ca o 3.6. Prot otipo: // Arquivo Base.h class Base { // Deni ca o dos atributos e m etodos da classe-base }; // Arquivo Derivada.h #include Base.h class Derivada: especicadorDeHeran ca Base // veja se co es 17.2 e 17.3 { // Deni ca o dos atributos e m etodos da classe-derivada }; 337

338

17.2. COMO IMPLEMENTAR A HERANCA SIMPLES

17.2

Como implementar a heran ca simples

Observe no prot otipo anterior a linha, class Derivada: especificadorDeHeran ca Base Nessa linha, informa-se que a classe-derivada e herdeira da classe-base. Como s o temos uma classe-base temos uma heran ca simples. O especicador de heran ca dene a forma como a classe-derivada pode acessar os atributos e m etodos da classe-base. O uso do especicador de heran ca e detalhado na Se ca o 17.3. Veja na Figura 17.1 o diagrama UML da classe CCirculo e, na listagem 17.1, seu c odigo. A classe CCirculo e herdeira da classe CPonto.
CPonto
+x: int +y: int +contador: static int +Desenha(): virtual void

CCirculo
+r1: int +Desenha(): virtual void

Figura 17.1: Heran ca simples: CPonto e CCirculo. Observe a forma como e declarada a heran ca da classe CCirculo com a classe CPonto. class CCirculo : public CPonto A classe CCirculo cria o atributo r1 e inclui o m etodo R1(). Agora preste aten ca o no construtor da classe CCirculo e observe a chamada do construtor da classe-base CPonto. A classe CCirculo chama explicitamente o construtor da classe CPonto para passar os atributos x e y. CCirculo(int _x,int _y, int _raio) : CPonto(_x,_y), r1(_raio) {}; Alguns m etodos Set() de CPonto s ao sobrecarregados (mesmo nome, mas par ametros diferentes). Observe no m etodo CCirculo::Set(CCirculo& C) que a classe CCirculo pode acessar os atributos x e y diretamente, pois esses foram herdados da classe CPonto. Note no m etodo inline void Set (int _x, int _y, int raio); que podemos chamar CPonto::Set ( x, y); da classe-base. Observe que o m etodo Desenha() e declarado como sendo virtual. Veremos os m etodos virtuais na Se ca o 19.2. Listing 17.1: A classe CCirculo.
1 2 3 4 # ifndef CCirculo_h # define CCirculo_h # include " CPonto . h " // C o m p i l a c~ ao condicional // Inclui classe - base

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

17.3. ESPECIFICADOR DE HERANCA


5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class CCirculo : public CPonto { protected : int r1 ; // Define o tipo de u s u a r i o C C i r c u l o. // H e r d e i r a de CPonto

339

public : // Construtor , o b s e r v e que p r i m e i r o passa para o c o n s t r u t o r da classe - base // os a t r i b u t o s x e y , e a seguir define r1 . CCirculo ( int _x , int _y , int _raio ) : CPonto ( _x , _y ) , r1 ( _raio ) { }; // M e todo Set () Seta a t r i b u t o s do c i r c u l o x , y e raio inline void Set ( int _x , int _y , int raio ) { CPonto :: Set ( _x , _y ) ; // Chama Set () da classe - base this - > r1 = raio ; // Uso de this e opcional } // Seta a t r i b u t o s do c i r c u l o a partir de um ponto e um raio . inline void Set ( CPonto & p , int _raio ) { x = p . X () ; y = p . Y () ; r1 = _raio ; } // Seta a t r i b u t o s do c i r c u l o a partir de outro c i r c u l o inline void Set ( CCirculo & c ) { this - > x = c . x ; this - > y = c . y ; this - > r1 = c . r1 ; } int R1 () const { return r1 ; }; virtual void Desenha () ; }; # endif

Veja na listagem 17.2 a implementa ca o da classe CCirculo, a qual redene o m etodo Desenha(). Note que na implementa ca o de Desenha() chamamos o m etodo Desenha() da classebase CPonto::Desenha() e fazemos mais alguma coisa, ou seja, CCirculo vai executar Desenha() de uma forma diferente. Listing 17.2: Implementa ca o da classe CCirculo.
1 2 3 4 5 6 7 8 9 # include < iostream > # include " CCirculo . h " // U t i l i z a o m e todo D e s e n h a da classe - base e a c r e s c e n t a o d e s e n h o do c rculo void CCirculo :: Desenha () { CPonto :: Desenha () ; // Chama m e todo da classe - base std :: cout << " \ nTCirculo : Coordenada r1 = " << r1 << std :: endl ; }

17.3

Especicador de heran ca

O especicador de heran ca altera a forma como se processa a heran ca, alterando o tipo de acesso herdado. Pode-se utilizar os especicadores public, protected e private. Veja o Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

340 prot otipo a seguir. Prot otipo: class Derivada: public Base {}; class Derivada: protected Base {}; class Derivada: private Base {};

17.3. ESPECIFICADOR DE HERANCA

O acesso aos membros da classe-base ir a depender do especicador de heran ca (public, protect e private) e dos especicadores de acesso na classe-base (public, protect e private). A Tabela 17.1 mostra o acesso herdado. Na primeira coluna, o especicador de acesso utilizado na classe-base; na segunda, o especicador de heran ca; e na terceira, o acesso efetivamente herdado. Observe na primeira linha da Tabela que, se o atributo e public e o especicador de heran ca tamb em, o acesso herdado e public; e se o atributo e protected e o especicador de heran ca e private, o acesso herdado ser a private. Observe que C++ utiliza as palavras-chave public, protected e private com dois objetivos: o primeiro, especicar a forma de encapsulamento dos atributos do objeto (veja Se ca o 11.2); o segundo, especicar a forma da heran ca. Tabela 17.1: Acesso herdado Especicador de acesso na classe-base public protected private public protected private public protected private Especicador de heran ca public public public protected protected protected private private private Acesso herdado public protected inacess vel protected protected inacess vel private private inacess vel

Vamos esclarecer a utiliza ca o do especicador de acesso na classe-base e do especicador de heran ca por meio da listagem 17.3. Este exemplo cont em erros, os quais s ao detectados pelo compilador. Veja a sa da. Listing 17.3: Usando especicador de acesso e de heran ca.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include < iostream > using namespace std ; class Base { public : int x ; protected : int y ; private : int z ; }; class DerivadaA : public Base { public : int X () { return x ; }; int Y () { return y ; }; int Z () { return z ; };

// Acesso p ublico // Acesso p r o t e g i d o // Acesso p r i v a d o

// Ok x e p ublico // Ok y e protegido // Erro n~ a o tem acesso a z

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

17.4. DIFERENCA ENTRE HERANCA PUBLICA E PRIVADA


17 18 19 20 21 22 23 24 25 }; class DerivadaB : private { public : int X () { return x ; int Y () { return y ; int Z () { return z ; }; Base

341

}; }; };

// Ok x e privado // Ok y e privado // Erro n~ a o tem acesso a z

especificador - heranca . cpp : In member function int DerivadaA :: Z () : especificador - heranca . cpp :8: error : int Base :: z is private especificador - heranca . cpp :16: error : within this context especificador - heranca . cpp : In member function int DerivadaB :: Z () : especificador - heranca . cpp :8: error : int Base :: z is private especificador - heranca . cpp :24: error : within this context make : ** [ especificador - heranca . o ] Erro 1

17.4

Diferen ca entre heran ca p ublica e privada

Se a heran ca e p ublica, um objeto D da classe-derivada e um tipo de objeto da classe-base, ou seja, quando necess ario, o compilador converte o objeto D em um objeto do tipo B. Quando a heran ca e privada, tal convers ao n ao e realizada [Meyers, 2005]. Logo, se voc e quer implementar uma rela ca o do tipo e um, a heran ca deve ser p ublica. A heran ca privada e usada ent ao para reaproveitamento de c odigo; por exemplo, use heran ca privada se precisar reaproveitar membros protegidos ou renar m etodos virtuais [Meyers, 2005]. Na maioria dos casos a heran ca privada pode ser substitu da por uma composi ca o. O uso de heran ca privada ou sua substitui ca o por composi ca o e uma decis ao de projeto.

17.5

Mudando a visibilidade em heran cas com using

Vimos o uso da palavra-chave using na Se ca o 10.3. Podemos utilizar a palavra-chave using para mudar a visibilidade (p ublica, protegida) dos membros de uma classe em heran cas. Veja o exemplo da listagem 17.4. Observe na sa da que podemos transformar um membro protected em public, mas n ao podemos mudar um membro private. Para que a mensagem de erro apare ca, voc e deve tirar o coment ario da linha // private. Listing 17.4: Usando using em heran cas.
1 2 3 4 5 6 7 8 9 10 11 12 # include < iostream > class Base { protected : const static int x = 123456; // p r i v a t e: const static int y = 789; }; class Derivada : public Base { public :

// D e c l a r a que x e protegido // Tirar o c o m e n t ario // D e c l a r a que y e privado

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

342
13 14 15 16 17 18 19 20 21 22 23

17.6. CHAMANDO CONSTRUTORES DA CLASSE-BASE EXPLICITAMENTE


// Agora x e p u b l i c o - ok // Agora y e p u b l i c o - Erro

using Base :: x ; using Base :: y ; };

int main () { Derivada d ; std :: cout << " d . x = " << d . x << std :: endl ; // ok std :: cout << " d . y = " << d . y << std :: endl ; // Erro return 0; } d . x = 123456 d . y = 789 [ b u e n o @ l d s c 0 5 ] $ g ++ U s a n d o U s i n g E m H e r a n c a s . cpp U s a n d o U s i n g E m H e r a n c a s . cpp :7: error : const int Base :: y is private U s a n d o U s i n g E m H e r a n c a s . cpp :11: error : within this context

17.6

Chamando construtores da classe-base explicitamente

Se a classe-base B s o tem construtores com par ametros (n ao tem o construtor default , Se ca o 16.3), a classe-derivada D deve chamar explicitamente um dos construtores de B. Veja o exemplo: Exemplo: class B { int a1, a2; public: // Declara c~ ao do construtor (n~ ao tem construtor default ) B(int a1, int a2); }; // Defini c~ ao do construtor da classe B B::B(int _a1, int _a2): a1(_a1), a2(_a2){}; class D: public B { int a3; public: D(int a1,int a2,int a3); }; // Defini c~ ao do construtor da classe D. // Observe a chamada do construtor de B passando os par^ ametros _a1 e _a2 D::D(int _a1,int _a2,int _a3):B(_a1,_a2),a3(_a3) {};

17.7

Redeclara c ao de m etodo ou atributo na classe-derivada

No Cap tulo 3 Conceitos B asicos de POO, vimos que uma classe-derivada herda os atributos e os m etodos da classe-base, e que a forma como tudo acontece na classe-derivada e um pouco diferente da que ocorre na classe-base. Para que os objetos derivados sejam efetivamente diferentes, por em, voc e precisa redeclarar e redenir alguns m etodos da classe-base ou acrescentar novos m etodos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

DE METODO 17.7. REDECLARAC AO OU ATRIBUTO NA CLASSE-DERIVADA

343

A classe-derivada pode acrescentar novos m etodos ou alterar os m etodos da classe-base. Podemos ter dois casos: no primeiro, a classe-derivada realiza a mesma opera ca o que a classe-base, mas de uma outra forma. No segundo, a classe-derivada realiza a mesma opera ca o da classe-base e algo mais. Isto signica que a classe-derivada pode reescrever totalmente o m etodo herdado ou pode chamar o m etodo da classe-base e depois acrescentar algo mais (veja m etodo Set(int,int,int) da listagem 17.1). Se voc e criar um atributo na classe-derivada com o mesmo nome de um atributo da classe-base, o atributo da classe-base continuar a existindo, mas para acess a-lo, voc e dever a utilizar o operador de resolu ca o de escopo (::). Veja listagem 17.5. Exemplo: NomeClasseBase::nomeAtributoRedeclarado; Se voc e redeclarar um m etodo na classe-derivada, este oculta o m etodo de mesmo nome da classe-base. O m etodo da classe-base pode ser acessado utilizando-se o operador de resolu ca o de escopo. Exemplo: NomeClasseBase::nomeM etodoRedeclarado(); 2 N ao confundir redeclara ca o (m etodo com mesmo nome e par ametros na classe-derivada) com utiliza ca o de sobrecarga de m etodos (m etodos com mesmo nome, mas com n umero ou tipos dos par ametros diferentes) ou com a utiliza ca o de m etodos virtuais (m etodo com mesmo nome e par ametros, mas com especicador virtual). Listing 17.5: Redeclara ca o de m etodo ou atributo na classe-derivada.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # include < iostream > int x = 0; // V a r i a v e l global - escopo global class B { public : const int x ; B () : x (1) { std :: cout << << << << } }; class D : public B { public : const int x ; D () : x (2) { std :: cout << << << << } }; int main () {

// Escopo da classe B " \ n \ tIn cio do construtor de B ( escopo de B ) : " " \ n \ t :: x = " << :: x " \ n \ tx = " << x " \ n \ tFim do construtor " << std :: endl ;

// Escopo da classe D // Oculta x da classe - base " \ n \ tIn cio do construtor de D ( escopo de D ) : " " \ n \ t :: x = " << :: x " \ n \ tx = " << x " \ n \ tB :: x = " << B :: x << std :: endl ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

344
30 31 32 33 34 35 36 37 38 std :: cout B obj_b ; std :: cout D obj_d ; std :: cout return 0; } Fun ca ~ o main () ( escopo de main () ) : :: x =0

17.8. SENTENCAS PARA HERANCA


<< " Fun ca ~ o main () ( escopo de main () ) : " << " \ n :: x = " << :: x << std :: endl ; << " obj_b . x = " << obj_b . x << std :: endl ;

<< " obj_d . x = " << obj_d . x <<

std :: endl ;

In cio do construto r de B ( escopo de B ) : :: x =0 x =1 Fim do construto r obj_b . x =1 In cio do construto r de B ( escopo de B ) : :: x =0 x =1 Fim do construto r In cio do construto r de D ( escopo de D ) : :: x =0 x =2 B :: x =1 obj_d . x =2

17.8

Senten cas para heran ca

A classe-base de uma hierarquia tamb em e chamada de classe-pai ou de superclasse. As demais classes s ao denominadas classes-derivadas, subclasses ou classes-lho. A maior diculdade em uma hierarquia e modelar com clareza as classes e seus relacionamentos. Observe que a classe-derivada n ao altera em nada a classe-base, de forma que, se a classederivada for alterada, somente ela precisar a ser recompiladaA utiliza ca o de protected e private deixa o c odigo mais encapsulado e, portanto, mais facilmente depurado. Uma classe vazia pode ser utilizada temporariamente quando o programador quer criar uma classe-base, mas ainda n ao identicou as rela co es entre as classes-derivadas. Uma classe vazia pode criar objetos. Note que, nestes casos, voc e tamb em pode criar uma classe de interface (Se ca o 11.5.2). Em uma heran ca e aconselh avel que um m etodo construtor chame os m etodos construtores ancestrais para a declara ca o dos atributos ancestrais, em vez de atribuir ele mesmo esses atributos (Se ca o 17.6). Se a heran ca e publica voc e tem um tipo de, ou seja, a classe-derivada cria um tipo de objeto que pode ser utilizado no lugar de um objeto da classe-base. M etodos da hierarquia podem ser desabilitados colocando-os como private. Ao colocar o m etodo como private, ele n ao poder a mais ser acessado (sendo desabilitado o acesso ao mesmo). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

17.9. RESUMO DO CAP ITULO

345

Objetos (nomes) criados em um escopo local, de fun ca o ou m etodo, ocultam objetos com mesmo nome criados no escopo global ou de classe, mesmo sendo de tipos diferentes. Em heran cas isto tamb em ocorre. Um atributo ou m etodo com mesmo nome em uma classe-derivada oculta o atributo/m etodo da classe-base (Se ca o 17.7). Em uma hierarquia as classes devem ter operadores de convers ao (veja Cap tulo 25 Convers oes). Segundo [Parga, 2006], heran ca e um tipo de relacionamento de alto acoplamento, posto que altera co es realizadas na superclasse s ao reetidas em toda hierarquia abaixo dela. Sendo assim, a cria ca o de uma hierarquia de classes muito profunda torna o sistema extremamente sens vel a altera co es, fazendo com que sua manuten ca o que dif cil. 2 Em uma hierarquia, se um m etodo e reescrito nas classes-derivadas, ele deve ser virtual. 2 O operador de atribui ca o e os construtores da classe-base n ao s ao herdados pelas classesderivadas, ou seja, todas as classes devem ter construtores default e de c opia, destrutores virtuais e operadores sobrecarregados. 2 A utiliza ca o de classes, heran ca e m etodos virtuais e a base para o polimorsmo, que possibilita o desenvolvimento de sistemas complexos (veja Cap tulo 19 Polimorsmo). 2 Em uma hierarquia de classes, os destrutores devem ser virtuais. Se voc e tiver heran ca e destrutores n ao virtuais, na destrui ca o de um objeto din amico o destrutor que ser a executado e o denido pelo tipo do ponteiro utilizado.
2

Um ponteiro para classe-derivada pode acessar um m etodo da classe-base [Meyers, 2005]. Derivada* ptr = new Derivada(); ptr->Base::Desenhar();

3 Em uma heran ca, se os m etodos virtuais t em par ametros predenidos, eles devem ser iguais em toda hierarquia, pois os argumentos predenidos s ao denidos em tempo de compila ca o. 3 Atributos, m etodos privados e m etodos n ao virtuais s ao invariantes para as classesderivadas [Meyers, 2005]. 3 Em heran cas, m etodos virtuais podem ser substitu dos por m etodos que recebem ponteiros para fun co es. Voc e tamb em pode utilizar a classe utilit aria da biblioteca boost (std::tr1::function). Veja Cap tulo ??.

17.9

Resumo do cap tulo

Nesce cap tulo aprendemos a implementar o conceito de heran ca simples em C++. Basicamente, basta incluir, ap os o nome da classe, o trecho de c odigo : public Base. Vimos que podemos ter heran ca p ublica, protegida ou privada. Lembre-se de que, para ser um tipo de, a heran ca deve ser p ublica. Isto signica que heran cas protegidas e privadas s ao pouco utilizadas. Aprendemos que quando a classe-base n ao tem um construtor default, o construtor existente deve ser explicitamente chamado. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

346

17.10. EXERC ICIOS

Aprendemos que a redeclara ca o de atributos na classe-derivada deve ser evitada, pois teremos dois atributos com o mesmo nome, mas em escopos diferentes. J a a redeclara ca o de m etodos e normal quando o m etodo e virtual. No Cap tulo 18 Heran ca M ultipla, veremos como implementar o conceito de heran ca m ultipla em C++.

17.10

Exerc cios

1. Use o debuger da GNU (gdb ou ddd) para rodar passo a passo as listagens com heran ca simples e heran ca m ultipla. Veremos os depuradores nos cap tulos ?? Uma Introdu ca o aos Bugs e a Debugagem de Programas e ?? Os Programas gdb, ddd e o bugzilla. 2. Corrija a listagem 17.3, incluindo m etodos X()/X(int), Y()/Y(int), Z()/Z(int) para os atributos x, y, z. 3. Comente a listagem 17.5 4. Desenhe e implemente uma hierarquia com as classes CQuadrado, CRetangulo, CTriangulo, CTrapezio utilizando o conceito de heran ca.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 18

Heran ca M ultipla
Na Se ca o 3.6, vimos a deni ca o de heran ca e heran ca m ultipla, e na Se ca o 6.4.11, como UML modela o conceito de heran ca m ultipla. No Cap tulo 17 Heran ca, vimos como implementar o conceito de heran ca em C++. Veremos neste cap tulo uma introdu ca o e o prot otipo para implementar heran ca m ultipla (Se ca o 18.1), al em de uma introdu ca o ao conceito de heran ca m ultipla em C++ (Se ca o 18.2). Veremos tamb em como resolver os problemas de ambig uidade em heran ca m ultipla (Se ca o 18.3), o uso de heran ca m ultipla com base comum (Se ca o 18.4), a ordem de cria ca o e destrui ca o dos objetos em uma heran ca (Se ca o 18.5) e a heran ca m ultipla virtual (Se ca o 18.6).

18.1

Prot otipo para heran ca m ultipla

Vimos na Se ca o 3.6 o conceito de heran ca e heran ca m ultipla. Neste cap tulo veremos como implementar heran ca m ultipla em C++. A heran ca m ultipla ocorre quando uma classe tem mais de um pai, isto e, quando uma classe-derivada e herdeira de mais de uma classe-base; ocorre em muitos casos reais, quando um objeto n ao e composto de outros objetos, mas de uma evolu ca o de outros objetos, ou seja, dois ou mais objetos foram unidos para criar um novo, e o objeto novo n ao pode ser identicado como sendo uma agrega ca o de B1 ou B2. Veja a seguir o prot otipo para os diferentes tipos de heran ca m ultipla. Prot otipo: class Derivada : especicadorHeran ca Base1, especicadorHeran ca Base2,... {}; // Heran ca m ultipla (veja se ca o 18.2) class Derivada : virtual especicadorHeran ca Base1, virtual especicadorHeran ca Base2 {}; // Heran ca m ultipla virtual (veja se ca o 18.6)

18.2

Como implementar a heran ca m ultipla

Veja no exemplo a seguir como implementar a heran ca m ultipla apresentada na Figura 18.1. Observe que a classe D e herdeira das classes B1 e B2. Note ainda que a heran ca se d a da esquerda para a direita; primeiro herda os atributos e m etodos de B1, depois de B2. 347

348

18.2. COMO IMPLEMENTAR A HERANCA MULTIPLA

Figura 18.1: Heran ca m ultipla.

B1
+atr_b1 +atr_b +f1() +f2() Herana

B2
+atr_b2 +atr_b +f1() +f2() A classe D herdeira de B1 e de B2.

D
+atr_d

Exemplo: class B1 { public: int atr_b1; int atr_b; }; class B2 { public: int atr_b2; int atr_b; }; class D: public B1, public B2 { public: int atr_d; }; int main() { B1 b1; B2 b2; D d; return 0; }

// Heran ca m ultipla

Observe na Figura 18.2 como cam os objetos b1, b2 e d na mem oria de seu computador. O objeto b1 tem os atributos atr_b1 e atr_b; o objeto b2 tem os atributos atr_b2 e atr_b; e o objeto d, os atributos atr_b1 e atr_b (herdados da classe B1), atr_b2 e atr_b (herdados da classe B2) e atr_d (da pr opria classe D).

Figura 18.2: Como cam os objetos b1, b2 e d em uma heran ca m ultipla.


Objeto b1 na memria

atr_b1 atr_b

atr_b1 atr_b atr_b2 atr_b atr_d


Objeto d na memria

Objeto b2 na memria

atr_b2 atr_b

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

18.3. RESOLVENDO AMBIGUIDADE EM HERANCA MULTIPLA COM USING

349

18.3

Resolvendo ambigu ca m ultipla com idade em heran using

Quando voc e utiliza heran ca m ultipla, pode ocorrer que as classes B1 e B2 tenham um atributo com o mesmo nome (veja na Figura 18.1 o atributo atr_b); esse atributo ser a criado duas vezes, uma pelo caminho D-B1 e outra pelo caminho D-B2. Quando voc e tentar acessar esse atributo em um m etodo da classe D, o compilador exibir a uma mensagem de erro por ambig uidade, ou seja, quando voc e acessa atr_b, voc e quer acessar atr_b herdado da classe B1 ou atr_b herdado da classe B2? Para contornar esse problema voc e deve utilizar o operador de resolu ca o de escopo (::). Veja o prot otipo a seguir:

Prot otipo: base1::nomeAtributoAmb guo; base2::nomeAtributoAmb guo;

Exemplo: B1::atr_b; B2::atr_b;

Alternativamente, pode-se eliminar o problema da ambig uidade utilizando-se a palavra-chave using. Com as declara co es using, voc e pode selecionar, em uma classe-derivada, os m etodos e atributos a serem utilizados. Veja o exemplo:

Exemplo: class D: public B1, public B2 { public: int atr_d; using B1::atr_b; // Quando chamar atr_b usar atr_b da classe B1 };

18.4

Heran ca m ultipla com base comum

O diagrama UML ilustrado na Figura 18.3 mostra uma heran ca m ultipla com base comum. A classe D e herdeira das classes B1 e B2 e estas s ao herdeiras de B0. A classe B0 e uma classe-base comum (uma superclasse). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

350

18.4. HERANCA MULTIPLA COM BASE COMUM

Figura 18.3: Heran ca m ultipla com classe base comum.

B0
+atr_b0 O atributo atr_b0 vai ser criado duas vezes, uma pelo caminho D->B1->B0, e outra pelo caminho D->B2->B0.

Herana

B1
+atr_b1

B2
+atr_b2

Herana

D
+atr_d

Veja a seguir como implementar a hierarquia da Figura 18.3.

Exemplo: class B0 { public: int atr_b0; }; class B1: public B0 { public: int atr_b1; }; class B2: public B0 { public: int atr_b2; }; class D: public B1, public B2 { public: int atr_d;}; int main() { B0 b0; B1 b1; B2 b2; D d;

return 0;

Quando voc e tem heran ca m ultipla com D herdando de B1 e B2, a classe D ir a percorrer os construtores das classes B1 e B0 e, em seguida, os contrutores de B2 e B0, criando duas vezes o atributo atr_b0. Observe na Figura 18.4 que o atributo atr_b0 e criado duas vezes, uma pelo caminho D::B1::B0 e outra pelo caminho D::B2::B0. Novamente, o acesso em D ao atributo atr_b0 e ambiguo e precisa ser resolvido com o operador de resolu ca o de escopo (::) ou usando a palavra-chave using. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

E DESTRUIC DOS OBJETOS EM HERANCAS 18.5. ORDEM DE CRIAC AO AO

351

Figura 18.4: Como cam os objetos b0, b1, b2 e d em uma heran ca m ultipla com base comum.
Objeto b0 na memria Objeto b1 na memria Objeto d na memria

atr_b0

atr_b0 atr_b1 atr_b0 atr_b2


Objeto b2 na memria

B1::atr_b0 atr_b1 B2::atr_b0 atr_b2 atr_d

18.5

Ordem de cria c ao e destrui c ao dos objetos em heran cas

Em uma heran ca m ultipla (veja Figura 18.3), a seq u encia de cria ca o dos objetos ocorre da esquerda para a direita. A Figura 18.5 ilustra a seq u encia de cria ca o dos objetos b0, b1, b2 e d. Para o objeto d, primeiro executa o construtor de B0, depois o construtor de B1, novamente o construtor B0, o construtor B2 e nalmente o construtor de D. A seq u encia de destrui ca o e inversa ` a da cria ca o. Primeiro executa o destrutor de D depois o destrutor de B2, B0, e nalmente o destrutor de B1 e B0.

Figura 18.5: Seq u encia de constru ca o e destrui ca o dos objetos em uma heran ca.
int main() { B0 b0;

B0() B0() B0() B0() B1() B2() B1() B0() B2() D()
Sequncia de criao dos objetos b0,b1,b2,d.

B1 b1;

B2 b2;

D d;

return 0; }

~D() ~B2() ~B1() ~B0()

~B2 ~B0() ~B0()

~B0()

~B1()

~B0()

Sequncia de destruio dos objetos b0,b1,b2 e d quando os mesmos saem de escopo.

Agora encerra programa retornando o valor 0.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

352

18.6. HERANCA MULTIPLA VIRTUAL

18.6

Heran ca m ultipla virtual

Vimos na Se ca o 18.3 que, ao criar uma classe-derivada de mais de uma classe-base (heran ca m ultipla), o compilador cria todos os atributos da classe-base B1 e depois todos os atributos da classe-base B2 (veja guras 18.1 e 18.2). Vimos na Se ca o 18.4 que, se as classes B1 e B2 s ao herdeiras da classe B0, ent ao o compilador ir a criar os atributos de B0 e B1 e, em seguida, os atributos de B0 e B2, de forma que o atributo de B0 (atr_b0) ser a criado duas vezes (veja guras 18.3 e 18.4). Se voc e deseja ter o atributo repetido, tudo bem (veja exemplo em nota no nal da se ca o). Por em, se voc e deseja ter apenas uma c opia dele, voc e precisar a denir a heran ca como virtual. O prot otipo a seguir mostra a sintaxe da heran ca virtual. Prot otipo: class Derivada: virtual especicadorDeHeran caBase1, virtual especicadorDeHeran ca Base2, ... {.... }; Veja na Figura 18.6 o diagrama UML de uma heran ca m ultipla virtual. Neste caso, como a heran ca e declarada como virtual, s o ser a criada uma c opia do atributo da classe-base, ou seja, atr_b0 s o e criado uma vez pelo caminho D-B1-B0. Veja no exemplo a seguir como implementar a hierarquia da Figura 18.6. Observe a utiliza ca o da palavra-chave virtual. Veja na Figura 18.7 que o atributo atr_b0 e criado apenas uma vez, pelo caminho D::B1::B0. Compare com a Figura 18.4. Figura 18.6: Heran ca m ultipla virtual.
B0
+atr_b0 O atributo atr_b0 vai ser criado apenas uma vez, pelo caminho D->B1->B0.

<<virtual>>

<<virtual>>

B1
+atr_b1

B2
+atr_b2

D
+atr_d

Exemplo: class B0 { public: class B1: { public: class B2: { public: class D:

int atr_b0; }; virtual public B0 int atr_b1; }; virtual public B0 int atr_b2; }; public B1, public B2 Andr e Duarte Bueno

Programa ca o Orientada a Objeto com C++

E DESTRUIC DOS OBJETOS EM HERANCA 18.7. ORDEM DE CRIAC AO AO MULTIPLA VIRTUAL { public: int atr_d; }; int main() { B0 b0; B1 b1; B2 b2; D d; return 0; }

353

Figura 18.7: Como cam os objetos b0, b1, B2 e d em uma heran ca m ultipla com base virtual.
Objeto b0 na memria Objeto b1 na memria Objeto d na memria

atr_b0

atr_b0 atr_b1

atr_b0 atr_b1 atr_b2

atr_b0 atr_d
Objeto b2 na memria

atr_b2

Nota: vamos a um exemplo em que a repeti ca o do atr_b0 e u til. Imagine que a classe D precisa herdar informa co es de acesso a sites de internet. No caso, dois sites de pesquisa, B1 e B2. A informa ca o do endere co de internet e armazenada em atr_b0. Neste caso, atr_b0 pelo caminho D::B1 vai retornar o endere co do site B1, e atr_b0 pelo caminho D::B2 vai retornar o endere co do site B1.

18.7

Ordem de cria c ao e destrui c ao dos objetos em heran ca m ultipla virtual

Em uma hierarquia com classes virtuais, a ordem de cria ca o dos atributos e dada por: primeiro s ao inicializadas as classes-base virtuais, depois as classes normais (da esquerda para direita), depois os atributos n ao-est aticos e, nalmente, o corpo do construtor. No exemplo a seguir, uma classe X tem heran ca normal de Y e virtual de Z. A seq u encia de cria ca o do objeto x e dada por Z(), Y(), X(), ou seja, primeiro s ao percorridas as heran cas virtuais (da esquerda para a direita) e depois as heran cas normais. Exemplo: // Classe X com heran ca virtual de Z class X: public Y, virtual public Z {}; int main() { // Cria objeto do tipo X com nome x X x; return 0; } Veja na Figura 18.8 uma hierarquia de classes com heran cas normais e virtuais (B1, B2, D1, D2 e Top). As classes-base s ao B1 e B2. A classe D1 tem deriva ca o normal de B2 e virtual de B1. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

354

E DESTRUIC DOS OBJETOS EM HERANCA 18.7. ORDEM DE CRIAC AO AO MULTIPLA VIRTUAL

A classe D2 tem deriva ca o normal de B2 e virtual de B1. A classe Top tem deriva ca o normal de D1 e virtual de D2. Figura 18.8: Heran ca m ultipla normal e virtual.

B1
+atr_b1 virtual virtual

B2
+atr_b2

D1

D2

virtual

Top

A hierarquia da Figura 18.8 e implementada na listagem 18.1. Observe na sa da a seq u encia de constru ca o e destrui ca o de um objeto do tipo Top. Listing 18.1: Seq u encia de constru ca o e destrui ca o em heran ca m ultipla virtual.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # include < iostream > class B1 { int atr_b1 ; public : B1 () { std :: cout << " Construtor de B1 - " ; ~ B1 () { std :: cout << " Destrutor de B1 - " ; }; class B2 { int atr_b2 ; public : B2 () { std :: cout << " Construtor de B2 - " ; ~ B2 () { std :: cout << " Destrutor de B2 - " ; }; class D1 : public B2 , virtual public B1 { public : D1 () { std :: cout << " Construtor de D1 - " ; ~ D1 () { std :: cout << " Destrutor de D1 - " ; };

}; };

}; };

}; };

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

18.8. SENTENCAS PARA HERANCA MULTIPLA


24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

355

class D2 : public B2 , virtual public B1 { public : D2 () { std :: cout << " Construtor de D2 -" ; ~ D2 () { std :: cout << " Destrutor de D2 -" ; };

}; };

class Top : public D1 , virtual public D2 { public : Top () { std :: cout << " Construtor de Top -" ; }; ~ Top () { std :: cout << " Destrutor de Top -" ; }; }; int main () { Top p ; return 0; } [bueno@ldsc05 Construtor de Construtor Destrutor Parte - II ] $ ./ a . out B1 - Construtor de B2 - Construtor de D2 - Construtor de B2 de D1 - Construtor de Top - Destrutor de Top - Destrutor de D1 de B2 - Destrutor de D2 - Destrutor de B2 - Destrutor de B1 -

A seq u encia de cria ca o do objeto p e dada por: Primeiro a seq u encia de D2 que e virtual: cria B1, que e virtual, cria B2 e, ent ao, cria D2. Depois a seq u encia de D1 que e normal:como a classe B1 e virtual, e a mesma j a foi criada pelo caminho Top::D2::B1, n ao precisa ser criado novamente. A seguir cria B2 e, depois cria D1. Finalmente cria Top. Assim, os construtores default das classes virtuais s ao chamados antes dos construtores das classes n ao virtuais. Releia a frase anterior; veja que escrevemos os construtores default das classes virtuais. Se a classe-base virtual n ao tem um construtor default (sem par ametros), um dos construtores com par ametros deve ser explicitamente chamado. Lembre-se de que toda classe tem um construtor, sem par ametros, que e criado automaticamente pelo compilador. Vimos que voc e pode reescrever o construtor da forma que quiser, e que, se criar qualquer construtor com par ametros, o construtor default deixa de ser criado pelo compilador. Como o construtor default deixa de ser criado, o construtor existente precisa ser explicitamente chamado (Se ca o 16.3).

18.8

Senten cas para heran ca m ultipla

Observe que a chamada do construtor da classe-base s o ser a importante se ele for efetivamente implementado e contiver, por exemplo, a cria ca o de objetos din amicos. Uma classe D n ao pode ter deriva ca o m ultipla de uma classe B. Este procedimento n ao e permitido por ser amb guo. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

356

18.8. SENTENCAS PARA HERANCA MULTIPLA Exemplo: class B { }; class D : public B, public B {}; // Erro de ambig uidade

Voc e pode criar um m etodo de inicializa ca o (Inicializa()), que pode ser utilizado para inicializa ca o dos atributos do objeto. Voc e pode chamar Inicializa() no construtor da classe-derivada. A utiliza ca o de heran ca virtual e interessante, permitindo construir classes mais complexas a partir da montagem de classes mais simples, com economia de mem oria e de implementa ca o. A heran ca virtual deve ser utilizada com crit erio e com cuidado. O uso excessivo de heran ca virtual deixa o c odigo mais lento. O acesso a atributos em classes com heran ca virtual e mais lento que em classes com heran ca comum. Se em uma heran ca virtual a classe-base n ao tiver um construtor default (pois foi denido um construtor com par ametros), o construtor da classe-base virtual deve ser explicitamente chamado. Veja o exemplo: Exemplo: // Arquivo CMinhaJanela.h class CFrameWindow: virtual public CWindow {...}; class CMinhaJanela: public CFrameWindow { // Construtor CMinhaJanela(string titulo); }; // Arquivo CMinhaJanela.cpp - Defini c~ ao do construtor // Chama construtor da classe-base e o // construtor da classe-base virtual explicitamente CMinhaJanela::CMinhaJanela(string titulo) :CFrameWindow(titulo),Window(titulo) {} A dica para simplicar o uso de classes com heran ca virtual e sempre incluir um construtor default. Se a classe-base e declarada como virtual, inclua um construtor default. Isto e necess ario para a cria ca o de uma matriz de objetos, pois quando esta e criada, o construtor executado e o construtor default. Se voc e deseja ter um mecanismo para identicar de que classe e um objeto (dado que voc e tem apenas um ponteiro para a classe-base), voc e deve incluir um m etodo que retorne o nome da classe. Isto e utilizado na programa ca o em ambientes de janela (como Windows, Mac OS X, Gnome, KDE), em que cada classe tem um m etodo que retorna o nome da classe. Esse m etodo e chamado GetClassName(). Mais recentemente, C++ incluiu a palavra-chave typeid que retorna dinamicamente o tipo de um objeto (veja Se ca o 9.5.4). Procure criar uma classe-base que tenha somente m etodos virtuais e p ublicos, uma classe de interface (veja Se ca o 11.5.2). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

18.9. EXEMPLO DE HERANCA SIMPLES E HERANCA MULTIPLA

357

Note que uma hierarquia com heran cas simples e uma arvore (tree ). Se a hierarquia inclui heran cas m ultiplas, ent ao ela gera um grafo e n ao uma arvore. No exemplo a seguir usamos sizeof() para vericar o tamanho da classe-base e da classederivada. Exemplo: NomeClasseBase *ptr = new CNomeClasseDerivada; sizeof(CNomeClasseBase); // Retorna o tamanho da classe-base sizeof(CNomeClasseDerivada);// Retorna o tamanho da classederivada sizeof(ptr); // Retorna o tamanho da classe-base 2 Nunca redena um m etodo n ao virtual. Isto elimina o conceito de invari ancia de m etodos n ao virtuais [Meyers, 2005]. 2 Quando se utiliza o mecanismo do polimorsmo e fundamental que o destrutor da classebase seja virtual. Do contr ario, o destrutor da classe-derivada n ao ser a executado.

18.9

Exemplo de heran ca simples e heran ca m ultipla

Observe na Figura 18.9 a hierarquia de classes CPonto. A classe CCirculo e herdeira de CPonto e a classe CElipse e herdeira de CCirculo. A classe CCirculoElipse e herdeira de CCirculo e de CElipse. As classes CPonto e CCirculo foram apresentadas nas listagens 13.5 e 17.1, respectivamente. Veja na listagem 18.2 a classe CElipse e, na listagem 18.4, um programa que utiliza as classes denidas. Figura 18.9: Hierarquia de classes CPonto, CCirculo, CElipse, CCirculoElipse.
CPonto
+x +y +Desenha() Hierarquia de classes CPonto.

CCirculo
+r1 +Desenha() CCirculoElipse tem Herana mltipla

CElipse
+r2 +Desenha()

CCirculoElipse
+Desenha()

Listing 18.2: A classe CElipse.


1 # ifndef CElipse_h

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

358
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

18.9. EXEMPLO DE HERANCA SIMPLES E HERANCA MULTIPLA

# define CElipse_h # include " CCirculo . h " class CElipse : public CCirculo // H e r a n ca simples { protected : int r2 ; public : // C o n s t r u t o r CElipse ( int x , int y , int raio1 , int raio2 ) ; // Seta a t r i b u t o s do objeto void Set ( int x , int y , int raio1 , int raio2 ) ; virtual void Desenha () ; // R e d e c l a r a d a }; # endif

Observe na listagem 18.3 que o m etodo Desenha() de CElipse chama Desenha() de CCirculo e, depois, acrescenta coisas novas. Isto e, o m etodo Desenha() da classe-base e redenido na classe-derivada, fazendo o que CCirculo::Desenha fazia e algo mais. Listing 18.3: Implementa ca o da classe CElipse.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # include < iostream > # include " CElipse . h " // O b s e r v e que a c h a m a d a e x p l c i t a do c o n s t r u t o r da classe - base C C i r c u l o // e necess a r i a porque C C i r c u l o n~ a o tem um c o n s t r u t o r d e f a u l t e // quero passar os a t r i b u t o s x , y e raio1 CElipse :: CElipse ( int x , int y , int raio1 , int raio2 ) : CCirculo (x , y , raio1 ) , r2 ( raio2 ) {} void CElipse :: Set ( int x , int y , int raio1 , int raio2 ) { // Herdou x e y de CPonto this - > x = x ; this - > y = y ; r1 = raio1 ; // Herdou r1 de C C i r c u l o r2 = raio2 ; // Criou o a t r i b u t o r2 na classe C E l i p s e } void CElipse :: Desenha () { CCirculo :: Desenha () ;

// I n s t r u c~ a o para d e s e n h a r o c rculo;

// Aqui voc^ e pode a c r e s c e n t a r i n s t r u c~ o e s r e f e r e n t e s ao d e s e n h o da elipse std :: cout << " \ nCElipse : Coordenada r2 = " << r2 << std :: endl ; }

Veja na listagem 18.4 um programa que utiliza as classes denidas. Listing 18.4: Usando as classes CPonto, CCirculo e CElipse.
1 2 3 4 5 6 7 8 9 10 11 12 # include < iostream > using namespace std ; # include " CElipse . h " int main () { int x = 5; int y = 4; { cout << " \n - - - - - - - - - - - - - - - - Testando CPonto : " << endl ; CPonto ponto ; // Cria objeto do tipo CPonto com nome ponto ponto . Set (x , y ) ; // Chama m e todo Set () do objeto ponto

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

18.10. ANALISE DOS ERROS EMITIDOS PELO COMPILADOR2


13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ponto . Desenha () ; } // Chama m e todo D e s e n h a () do objeto ponto // Sai de escopo e detr o i objeto ponto

359

cout << " \n - - - - - - - - - - - - - - - - Testando CPonto din^ a mico : " << endl ; CPonto * ptr = NULL ; // Cria p o n t e i r o para CPonto ptr = new CPonto ; // Cria objeto do tipo CPonto x = 6; y = 7; ptr - > Set (x , y ) ; // Chama m e todo Set () do objeto usando ptr ptr - > Desenha () ; int xx = ptr - > X () ; delete ptr ; // Chama m e todo e s t a t i c o da classe CPonto , // o b s e r v e que n~ a o p r e c i s a de um objeto // U t i l i z a o nome da classe s e g u i d o do o p e r a d o r de r e s o l u c~ a o de escopo . cout << " Contador = " << CPonto :: Contador () << endl ; cout << " \n - - - - - - - - - - - - - - - - Testando CCirculo : " << endl ; CCirculo c (55 , 44 , 33) ; c . Desenha () ; cout << " \n - - - - - - - - - - - - - - - - Testando CElipse : " << endl ; CElipse e (555 , 444 , 333 , 222) ; e . Desenha () ; return 0; } - - - - - - - - - - - - - - - - Testando CPonto : CPonto : Coordenada x = 5 CPonto : Coordenada y = 4 - - - - - - - - - - - - - - - - Testando CPonto din^ a mico : CPonto : Coordenada x = 6 CPonto : Coordenada y = 7 Contador = 2 - - - - - - - - - - - - - - - - Testando CCirculo : CPonto : Coordenada x = 55 CPonto : Coordenada y = 44 CCirculo : Coordenada r1 =33 - - - - - - - - - - - - - - - - Testando CElipse : CPonto : Coordenada x = 555 CPonto : Coordenada y = 444 CCirculo : Coordenada r1 =333 CElipse : Coordenada r2 =222

18.10

An alise dos erros emitidos pelo compilador2

No exemplo da listagem 18.5, dene-se a classe CCirculoElipse. Esta representa um c rculo dentro de uma elipse (um olho). Na listagem 18.6 apresenta-se a implementa ca o da classe CCirculoElipse. Observe que o processo de compila ca o de CCirculoElipse falha, e o compilador apresenta erros que ser ao discutidos a seguir. Listing 18.5: A classe CCirculoElipse.
1 2 3 4 5 6 7 8 # ifndef C C i r c u l o E l i p s e _ h # define C C i r c u l o E l i p s e _ h # include < iostream > using namespace std ; # include " CCirculo . h " # include " CElipse . h " // Quero um c i r c u l o e uma elipse ( um olho ) , as c o o r d e n a d a s do ponto c e n t r a l

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

360
9 10 11 12 13 14 15 16 17 18

18.10. ANALISE DOS ERROS EMITIDOS PELO COMPILADOR2

// s~ a o as mesmas . H e r a n c a m u ltipla , herda de C C i r c u l o e de C E l i p s e class C C i r c u l o E l i p s e : public CCirculo , public CElipse { public : C C i r c u l o E l i p s e ( int xc , int yc , int rc , int r1e , int r2e ) ; C C i r c u l o E l i p s e ( CCirculo & circulo ) ; // C o n s t r u t o r de c o n v e r s ~ ao void Set ( int xc , int yc , int rc , int r1e , int r2e ) ; virtual void Desenha () ; // R e d e c l a r a d a }; # endif

Listing 18.6: Implementa ca o da classe CCirculoElipse.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 # include " C C i r c u l o E l i p s e . h " C C i r c u l o E l i p s e :: C C i r c u l o E l i p s e ( int xc , int yc , int rc , int r1e , int r2e ) { // U t i l i z a o o p e r a d o r de r e s o l u c~ a o de escopo para a c e s s a r m e todo a n c e s t r a l CCirculo :: Set ( xc , yc , rc ) ; // C E l i p s e :: C C i r c u l o :: Set ( xc , yc , rc ) ; CElipse :: Set ( xc , yc , r1e , r2e ) ; } void C C i r c u l o E l i p s e :: Set ( int xc , int yc , int rc , int r1e , int r2e ) { CCirculo :: Set ( xc , yc , rc ) ; // C E l i p s e :: C C i r c u l o :: Set ( xc , yc , rc ) ; CElipse :: Set ( xc , yc , r1e , r2e ) ; } // C o n s t r u t o r de c o n v e r s ~ a o . Como o c r c u l o n~ ao preenche totalmente // o C C i r c u l o E l i p s e e quero c o n s t r u i r um C C i r c u l o E l i p s e a partir de um // CCirculo , crio um c o n s t r u t o r de c o n v e r s ~ ao C C i r c u l o E l i p s e ( CCirculo & circulo ) { CCirculo :: Set ( circulo ) ; // O b s e r v e abaixo que passa c i r c u l o . r1 como r1 e r2 da C E l i p s e CElipse :: Set ( circulo .x , circulo .y , circulo . r1 , circulo . r1 ) ; } // I m p l e m e n t a c~ a o de Desenha , uso do o p e r a d o r de r e s o l u c~ a o de escopo // para i d e n t i f i c a r o m e todo da classe - base void C C i r c u l o E P o n t o :: Desenha () { CElipse :: Desenha () ; // D e s e n h a a elipse CCirculo :: Desenha () ; // D e s e n h a o c r c u l o // C E l i p s e :: C C i r c u l o :: D e s e n h a () ; } C C i r c u l o E l i p s e . h :11: warning : direct base CCirculo i n a c c e s s i b l e in C C i r c u l o E l i p s e due to ambiguity C C i r c u l o E l i p s e . cpp : In construct or C C i r c u l o E l i p s e :: C C i r c u l o E l i p s e ( int , int , int , int , int ) : C C i r c u l o E l i p s e . cpp :3: error : no matching function for call to CCirculo :: CCirculo () CCirculo . h :13: note : candidate s are : CCirculo :: CCirculo ( int , int , int ) CCirculo . h :6: note : CCirculo :: CCirculo ( const CCirculo &) C C i r c u l o E l i p s e . cpp :3: error : no matching function for call to CElipse :: CElipse () CElipse . h :11: note : candidates are : CElipse :: CElipse ( int , int , int , int ) CElipse . h :6: note : CElipse :: CElipse ( const CElipse &) C C i r c u l o E l i p s e . cpp :6: error : cannot call member function void CCirculo :: Set ( int , int , int ) without object C C i r c u l o E l i p s e . cpp : In member function void C C i r c u l o E l i p s e :: Set ( int , int , int , int , int ) :

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

18.11. RESUMO DO CAP ITULO

361

C C i r c u l o E l i p s e . cpp :12: error : cannot call member function void CCirculo :: Set ( int , int , int ) without object C C i r c u l o E l i p s e . cpp : At global scope : C C i r c u l o E l i p s e . cpp :19: error : expected ) before & token C C i r c u l o E l i p s e . cpp :29: error : C C i r c u l o E P o n t o has not been declared C C i r c u l o E l i p s e . cpp : In function void Desenha () : C C i r c u l o E l i p s e . cpp :31: error : cannot call member function virtual void CElipse :: Desenha () without object C C i r c u l o E l i p s e . cpp :32: error : cannot call member function virtual void CCirculo :: Desenha () without object make : ** [ C C i r c u l o E l i p s e . o ] Erro 1

A classe CCirculoElipse n ao compila em virtude da presen ca de alguns erros. O primeiro erro est a na ambig uidade no acesso ` a classe CCirculo. Isto ocorre porque esta classepode ser acessada pelo caminho CCirculo e pelo caminho CElipse::CCirculo. Outro erro apresentado e a falta da chamada expl cita dos construtores de CCirculo. Como CCirculo n ao tem um construtor default, o construtor de CCirculo precisa ser explicitamente chamado. O erro se repete para CElipse. Ocorre novo erro ao tentar converter CCirculoElipse para CCirculo, pois existem dois CCirculo e a base e amb gua. Existe um erro na deni ca o do m etodo construtor de CCirculoElipse: est a faltando o nome da classe e ::, isto e, CCirculoElipse::CCirculoElipse(...). Como voc e pode ver, a sa da gerada pelo compilador pode ser muito grande. De modo geral, um pequeno erro de digita ca o (de sintaxe) pode gerar v arias mensagens de erro. Um exemplo cl assico de erro de digita ca o e que gera uma sa da confusa e a falta ou excesso de colchetes {}. Com isso, voc e conclui que e necess ario compreender bem a sintaxe de C++ e digitar o programa com cuidado. Dica: veremos o uso do compilador da GNU, o g++ no Cap tulo ?? Compilando com gcc e g++, e a debugagem de programas no Cap tulo ?? Uma Introdu ca o aos Bugs e a Debugagem de Programas.

18.11

Resumo do cap tulo

Vimos uma pequena introdu ca o e o prot otipo para implementar heran ca m ultipla. Aprendemos a implementar heran ca m ultipla em C++ e, ainda, como cam os objetos na mem oria do computador. Em seguida, aprendemos a resolver os problemas de ambig uidade em heran ca m ultipla e o uso de heran ca m ultipla com base comum. Tamb em vimos o conceito de heran ca m ultipla virtual e a ordem de cria ca o e destrui ca o dos objetos em uma heran ca. Finalmente, aprendemos a analisar os erros emitidos pelo compilador. Dica: este e um dos cap tulos mais complexos de C++. N ao se preocupe se n ao entendeu tudo em uma primeira leitura. Esses conceitos ser ao assimilados ap os um certo per odo de uso de C++.

18.12

Exerc cios

1. Comente as listagens apresentadas. 2. Implemente as classes B1, B2 e D, descritas na Se ca o 18.2. 3. Implemente as classes B0, B1, B2 e D descritas na Se ca o 18.4. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

362

18.12. EXERC ICIOS

4. Monte o programa main() descrito na Figura 18.5. Rode o programa e veja se a ordem de constru ca o e destrui ca o descrita est a correta (voc e pode rodar o programa de dentro do debuger ddd; Veja Se ca o ??). 5. Modique a listagem 18.1 acrescentando um par ametro no construtor de B1. Veja a sa da gerada. Em seguida, adicione a chamada ao construtor de B1. 6. Fa ca as corre co es necess arias no c odigo das listagens 18.5 e 18.6, de forma que a classe CCirculoElipse funcione e possa ser inclu da no c odigo do programa da listagem 18.4. 7. Na Se ca o 18.9 apresentamos uma hierarquia de classes gen ericas. A pergunta e,: um c rculo e um tipo de ponto? Corrija a hierarquia. 8. Acrescente a hierarquia as classes CQuadrado, CRetangulo, CTriangulo e CTrapezio.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 19

Polimorsmo
Veremos neste cap tulo como implementar o conceito de polimorsmo apresentado na Se ca o 3.7. Iniciamos explicando, na Se ca o 19.1, o funcionamento dos m etodos n ao virtuais (m etodos normais e m etodos est aticos). Em seguida apresentaremos os m etodos virtuais, Se ca o 19.2, os quais s ao a base para implementar o polimorsmo, descrito na Se ca o 19.3. Os m etodos virtuais puros, utilizados para implementar classes abstratas ou de interface, s ao descritos na Se ca o 19.4 e os m etodos virtuais sobrecarregados na Se ca o 19.5. Finalmente, apresentaremos um exemplo cobrindo o uso pr atico de polimorsmo na Se ca o 19.6.

19.1

M etodos n ao virtuais

Os m etodos de uma classe podem ser normais, inline, est aticos ou virtuais. Os m etodos normais, os m etodos est aticos e os m etodos em linha t em seu endere co denido a priori, na compila ca o, tendo uma liga ca o est atica. O termo liga ca o est atica signica que quando o compilador encontra uma chamada do m etodo, ele substitui esta pelo endere co de mem oria onde o m etodo est a localizado. J a os m etodos com liga ca o din amica t em seu endere co denido durante a execu ca o. Veja na Tabela 19.1 exemplos de m etodos com liga ca o est atica. Observe que m etodos sem a palavra-chave virtual s ao m etodos com liga ca o est atica. Tabela 19.1: M etodos com liga ca o est atica Prexo __ inline static inline static __ inline Retorno Tipo Tipo Tipo Tipo Tipo Tipo NomeM etodo NomeM etodo NomeM etodo NomeM etodo NomeM etodo NomeM etodo NomeM etodo Par ametro ( Tipo p ) ( Tipo p ) ( Tipo p ) ( Tipo p ) ( Tipo p ) ( Tipo p ) Suxo __ __ __ __ const const

A Tabela 19.2 mostra m etodos com liga ca o din amica. Observe o uso da palavra-chave virtual como prexo. Note ainda que um m etodo virtual pode ser const, mas n ao pode ser static nem inline. 363

364

VIRTUAIS 19.1. METODOS NAO

Tabela 19.2: M etodos com liga ca o din amica Prexo virtual virtual Retorno Tipo Tipo Nome Nome Nome Par ametro ( Tipo p ) ( Tipo p ) Suxo __ const

Vamos tentar esclarecer o funcionamento da liga ca o est atica com um exemplo. Seja a classe B, com os m etodos M1(), M2(), M3(). Verique que M3() chama M1() e M2(). A classe D e derivada de B e redene os m etodos M1() e M2(). Na fun ca o main(), cria um objeto do tipo D com nome d e chama os m etodos M1(), M2(), e M3(). Exemplo: class B { public: void M1(){...}; void M2(){...}; void M3(){ M1(); }; class D: public B { public: void M1() {...}; void M2() {...}; }; int main() { D d; d.M1(); d.M2(); d.M3(); return 0; } Como os m etodos M1() e M2() t em liga ca o est atica, o m etodo M3() denido apenas na classe B vai chamar os m etodos M1() e M2() da classe B e n ao da classe D, ou seja, como a liga ca o e est atica, o compilador traduz a fun ca o main() da seguinte forma: Exemplo: int main() { D d; D::M1(&d); // Chama M1() da classe D D::M2(&d); // Chama M2() da classe D B::M3(&d); // Chama M3() da classe B // O comando B::M3(&d); vai ser traduzido por // B::M1(&d); B::M2(&d); return 0; } Observe no exemplo anterior que foi criado um objeto do tipo D e que o m etodo M3() est a executando os m etodos M1() e M2() da classe B. Por em, se criamos uma classe D e redenimos Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

M2(); };

// // // //

Chama M1() da Chama M2() da Chama M3() da pois M3() n~ ao

classe D classe D classe B, foi redefinida na classe D

19.2. METODOS VIRTUAIS

365

M1() e M2(), normalmente iremos querer que os m etodos M1() e M2() sejam sempre usados, mesmo quando chamamos M3(). Para que o m etodo M3() chame os m etodos M1() e M2() da classe D, os m etodos M1() e M2() devem ser declaradas como m etodos virtuais. Veremos a seguir como funcionam os m etodos virtuais.

19.2

M etodos virtuais

Os m etodos virtuais t em seu endere co denido dinamicamente, ou seja, durante a execu ca o do programa. Nesta se ca o, vamos discutir como isso funciona. Veja a seguir o prot otipo de declara ca o dos m etodos virtuais. A u nica diferen ca em rela ca o aos m etodos normais e a inclus ao da palavra-chave virtual. Veja na Tabela 19.2 exemplos de m etodos com liga ca o din amica. Prot otipo: class B { // Declara m etodo virtual virtual Tipo M etodoA(); // Declara m etodo virtual com par ametros virtual Tipo M etodoB(par ametros); // Declara m etodo virtual com par ametros e const virtual Tipo M etodoC(par ametros) const; }; class D: public B { // Redeclara m etodo virtual virtual Tipo M etodoA(); // Redeclara m etodo virtual com par ametros virtual Tipo M etodoB(par ametros); // Redeclara m etodo virtual com par ametros e const virtual Tipo M etodoC(par ametros) const; }; Toda classe que possui m etodos virtuais cont em uma tabela chamada VMT - Virtual Memory Table ou Tabela de M etodos Virtuais. Essa tabela cont em o endere co em tempo de execu ca o dos m etodos virtuais. Assim, quando o programa est a rodando, a deni ca o de qual m etodo vai ser executado e dada pela tabela VMT. Como funciona? A classe-base tem o endere co de seus m etodos virtuais na sua tabela VMT e acessa-os vericando seus endere cos na tabela. A classe-derivada tamb em tem uma VMT, onde h a o endere co de seus m etodos virtuais. Desta forma, quando um objeto da classe-derivada chama um m etodo, o endere co e obtido durante a execu ca o da sua VMT. Por meio desse mecanismo, a identica ca o de qual m etodo ser a executado e realizada dinamicamente atrav es da verica ca o do endere co dos m etodos na tabela VMT. Esse mecanismo tamb em recebe o nome de liga ca o din amica, pois o m etodo que ser a executado, ser a denido durante a execu ca o. A Figura 19.1 ilustra o funcionamento da liga ca o din amica. Toda chamada a M1() e M2() passa pela VMT. Quando voc e cria um objeto do tipo B, este utiliza a VMT da classe B e sempre acessa os m etodos M1() e M2() da classe B. Isso tamb em e v alido para a classe D. Quando voc e Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

366

19.2. METODOS VIRTUAIS

cria um objeto do tipo D, este utiliza a VMT da classe D e sempre acessa os m etodos M1() e M2() da classe D. Observe que quando um objeto da classe D acessa o m etodo M3(), acessa o m etodo M3() da classe B porque este n ao foi redenido na classe D. Mas quando M3() acessa M1() e M2(), est a acessando os m etodos M1() e M2() da classe D porque passa pela VMT da classe D. Veremos a seguir senten cas para m etodos virtuais e logo ap os, como usar os m etodos virtuais para implementar o polimorsmo. Figura 19.1: Ilustra ca o do funcionamento da liga ca o din amica.
Classe B
+M1(): virtual +M2(): virtual +M3() VMT_CLASSE_B M1 M2 M3() { M1(); M2(); }

Herana

void main() { D* ptr = new D(); ptr->M1(); ptr->M2(); ptr->M3(); delete ptr; }

Classe D
+M1(): virtual +M2(): virtual VMT_CLASSE_D M1 M2

19.2.1

Senten cas para m etodos virtuais

N ao devemos chamar m etodos virtuais de dentro do construtor, pois o construtor da classe sempre ir a chamar os m etodos da pr opria classe. Isto ocorre porque a tabela VMT da classe derivada ainda n ao foi criada. Uma vez que um m etodo e declarado como virtual, este o ser a para sempre e em todas as classes derivadas. Se um m etodo M() e declarado como virtual na classe-base B, e, em uma classe-derivada D, o programador omite a palavra chave virtual, ent ao ele est a indicando que este m etodo n ao deve ser redenido nas classes derivadas de D. Os m etodos virtuais devem ter exatamente o mesmo prot otipo; se o nome for igual e os par ametros diferentes, teremos sobrecarga de m etodos. Veja o Cap tulo 14 Sobrecarga de M etodos e a Se ca o 19.5. Retorno diferente n ao diferencia m etodos; o que diferencia os m etodos e o seu nome e os seus par ametros. Note que um m etodo virtual pode ser const, mas n ao pode ser static (porque m etodos static n ao recebem o ponteiro this) nem inline (porque m etodos inline s ao substitu dos/resolvidos em tempo de compila ca o). A utiliza ca o de m etodos virtuais em heran cas permite a implementa ca o do conceito de polimorsmo e elimina muitas das estruturas switch (veja Se ca o 19.3). Quando voc e cria classes com m etodos virtuais voc e deve declarar o destrutor como sendo virtual, garantindo, desta forma, a execu ca o do destrutor correto. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

19.3. COMO IMPLEMENTAR O POLIMORFISMO

367

Cuidado com par ametros predenidos em m etodos virtuais. Embora o m etodo a ser executado seja denido em tempo de execu ca o, os par ametros s ao denidos em tempo de compila ca o, tendo como base o tipo do ponteiro utilizado. Este problema e facilmente contornado. As assinaturas de todos os m etodos virtuais devem ser exatamente iguais. Se o m etodo e virtual, voc e deve evitar o uso de par ametros predenidos ou ter certeza de que todas as declara co es e deni co es de um m etodo virtual t em exatamente os mesmos valores predenidos (veja Se ca o 13.6.4). 2 Em uma hierarquia de classes, um m etodo virtual deve ter o mesmo tipo de retorno. Se o tipo de retorno for diferente, ent ao temos um retorno covariante. Este caso e poss vel somente se o retorno for um ponteiro ou refer encia para um tipo derivado da classe-base. No exemplo a seguir o retorno do m etodo M(); e covariante: Exemplo: class Base { virtual Base* M();}; class Derivada1: public Base { virtual Derivada1* M();}; class Derivada2: public Derivada1 { virtual Derivada2* M();};

19.3

Como implementar o polimorsmo

Vimos anteriormente que polimorsmo signica muitas formas (Se ca o 3.7), ou seja, para cada classe-derivada o m etodo virtual ser a redenido, mas de forma diferente. Vimos ainda que o m etodo virtual que vai ser efetivamente executado e endere cado pela VMT. Para implementar o polimorsmo e necess ario uma hierarquia de classes com m etodos virtuais e a cria ca o dos objetos de forma din amica (com o uso de um ponteiro para a classe-base). Veja na listagem 19.1 um exemplo que esclarece a utiliza ca o do polimorsmo. O programa Polimorfismo.cpp utiliza as classes CPonto, CCirculo e CElipse denidas anteriormente (veja Figura 18.9). O programa inicia-se criando um ponteiro para a classebase da hierarquia, a classe CPonto. Dentro do la co do..while() (veja Se ca o D.3.3), o usu ario seleciona qual objeto deve ser criado, isto e, CPonto, CCirculo ou CElipse. Em seguida, dentro do switch (veja Se ca o D.2.4), cria o objeto selecionado. ao existe nenhuma refer encia ou informa ca o Observe que na chamada a ptr->Desenha();; n sobre qual foi o objeto criado. Por em, com a utiliza ca o do mecanismo de polimorsmo, o m etodo Desenha() que ser a executado e aquele do objeto que foi criado (usa a VMT do objeto criado). Observe que, depois que o objeto foi criado, pode-se utilizar os m etodos p ublicos da classe CPonto. Se o usu ario solicitar a cria ca o de um objeto CPonto o programa ir a executar o m etodo Desenha() de CPonto;; se o usu ario criar um objeto CCirculo, o programa ir a executar o m etodo Desenha() de CCirculo; e se criar um objeto CElipse, o programa ir a executar o m etodo Desenha() de CElipse. Isso quer dizer que o m etodo executado depender a do objeto criado. Veja no nal da listagem como car a a sa da do programa, selecionando-se os diferentes tipos de objetos. Para compilar a listagem Polimorfismo.cpp, digite: g++ Polimorsmo.cpp CCirculo.cpp CElipse.cpp CPonto.cpp Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

368

19.3. COMO IMPLEMENTAR O POLIMORFISMO

Nota: o la co do..while() e descrito na Se ca o D.3.3, e o uso de switch na Se ca o D.2.4. As listagens utilizadas s ao: 13.5, 17.1, 18.2.

Listing 19.1: Exemplo de uso do polimorsmo.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # include < iostream > # include " CPonto . h " # include " CCirculo . h " # include " CElipse . h " using namespace std ; // E x e m p l o de c r i a c~ ao e utiliza c~ a o do objeto CPonto , C C i r c u l o e C E l i p s e int main () { CPonto * ptr = NULL ; // 1. Crie um p o n t e i r o para a classe - base int selecao ; while ( true ) { // 2. P e r g u n t e qual objeto ser a criado cout << " \ nQual objeto criar ? " ; cout << " \ nCPonto ..(1) , CCirculo ..(2) , CElipse ..(3) , Para sair (4) ?: " ; cin >> selecao ; cin . get () ; switch ( selecao ) // 3. Crie o objeto s e l e c i o n a d o { case 1: ptr = new CPonto (1 , 2) ; break ; case 2: ptr = new CCirculo (1 , 2 , 3) ; break ; case 3: ptr = new CElipse (1 , 2 , 3 , 4) ; break ; case 4: return 0; default : ptr = new CCirculo (1 , 2 , 3) ; break ; } ptr - > Desenha () ; // 4. U t i l i z a o objeto criado ptr - > O u t r o s M e t o d o s () delete ptr ; // 5. Para d e s t r u i r o objeto criado use delete ptr = NULL ; } return 0; } Qual objeto criar ? CPonto ..(1) , CCirculo ..(2) , CElipse ..(3) , Para sair (4) ?:1 CPonto : Coordenada x = 1 CPonto : Coordenada y = 2 Qual objeto criar ? CPonto ..(1) , CCirculo ..(2) , CElipse ..(3) , Para sair (4) ?:3 CPonto : Coordenada x = 1 CPonto : Coordenada y = 2 CCirculo : Coordenada r1 =3 CElipse : Coordenada r2 =4 Qual objeto criar ? CPonto ..(1) , CCirculo ..(2) , CElipse ..(3) , Para sair (4) ?:4

Releia o exemplo com cuidado e observe que depois que o objeto e criado dentro do switch, este pode ser utilizado (chamada a ptr->desenhar()), mas voc e n ao saber a qual foi o objeto que o usu ario criou. Trata-se de um mecanismo de programa ca o incomum e muito inteligente. Voc e escreve boa parte do c odigo de forma gen erica, sem se preocupar se foi criado um ponto, um c rculo ou uma elipse. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

19.4. METODOS VIRTUAIS PUROS

369

19.3.1

Senten cas para polimorsmo

Todo objeto criado sabe a qual classe pertence e utiliza a tabela VMT da sua classe. O mecanismo virtual existe para permitir que as opera co es sobre um objeto sejam realizadas sem o conhecimento do tipo do objeto que ser a criado. O polimorsmo deixa o programa mais simples e gen erico, pois seu desenvolvimento e simplicado. Toda classe com m etodos virtuais tem uma tabela VMT, e todo objeto de uma classe com m etodos virtuais tem oculto um ponteiro para esta tabela (virtual pointer ). Como conseq u encia da implementa ca o da hereditariedade e do polimorsmo, quando um programa orientado a objeto e executado, as mensagens s ao recebidas por objetos. Normalmente, o m etodo para manipula ca o de uma mensagem e armazenado no alto de uma biblioteca de classes ( e uma classe de Interface). O m etodo e localizado dinamicamente, quando necess ario, e a liga ca o ocorre no u ltimo momento poss vel (utilizando a VMT).

19.4

M etodos virtuais puros

M etodos virtuais puros s ao m etodos que s ao declarados como virtuais na classe-base e que n ao s ao implementados (n ao s ao denidos). Eles s ao utilizados para criar uma classe de Interface. Veja no prot otipo que o m etodo e igualado ao valor 0. Como o m etodo s o foi declarado e n ao denido, n ao posso criar um objeto da classe-base abstrata porque ele poderia chamar um m etodo que n ao existe. Prot otipo: class Base { virtual Tipo M etodoA() =0; virtual Tipo M etodoB(par ametros)=0; virtual Tipo M etodoC(par ametros) const =0; }; Se a classe-derivada n ao implementa o m etodo virtual puro, ela tamb em e uma classe abstrata, que n ao pode criar objetos. Se voc e tiver uma classe com um ou mais m etodos virtuais puros, ter a uma classe abstrata, uma classe que n ao poder a criar objetos (mas pode ser usada para criar ponteiros). Uma classe de interface normalmente e uma classe-base ou superclasse, podendo ser utilizada como uma interface para acessar, por meio de um ponteiro, as classes derivadas. Uma classe de interface e uma classe que n ao tem atributos, e todos os seus m etodos s ao p ublicos.

19.5

M etodos virtuais sobrecarregados

M etodos virtuais podem ser sobrecarregados, mas a redeclara ca o de um destes m etodos na classe-derivada oculta todos os m etodos com mesmo nome na classe-base. Veja o exemplo: class Base { virtual Area(); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

370

19.6. EXEMPLO COMPLETO COM POLIMORFISMO }; class Derivada : public Base { virtual Area(Funcao* f); // Sobrecarga, oculta Area(). };

No exemplo anterior, se criarmos um objeto do tipo da classe-derivada, s o poderemos acessar o m etodo virtual Area(Funcao* f); // Sobrecarga

pois o mesmo ocultou o m etodo Area() da classe-base. A id eia de ocultar os m etodos da classe-base teve como motiva ca o a preocupa ca o em se evitar que heran cas com sobrecarga sejam realizadas acidentalmente, sobretudo em programas e bibliotecas grandes [Meyers, 2005]. Esse problema pode ser contornado de duas formas: usando a palavra-chave using ou redenindo todos os m etodos na classe-derivada e chamando os m etodos da classe-base. Veja a seguir a solu ca o usando using. class Derivada : public Base { virtual Area(Funcao* f);// Sobrecarga using Base::Area; // Informa que esta usando m etodo da classe-base }; A segunda solu ca o consiste em redenir os m etodos na classe-derivada. class Derivada : public Base { virtual Area(Funcao* f); // Sobrecarga virtual Area() // Redefinida { Base::Area(); } }; Observe que a solu ca o usando using e mais simples.

19.6

Exemplo completo com polimorsmo

O diagrama UML da hierarquia de classes que ser a implementado e ilustrado na Figura 19.2. Note que a classe CAlunoFuncionario tem heran ca m ultipla. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

19.6. EXEMPLO COMPLETO COM POLIMORFISMO

371

CPessoa
+nome: string +matricula: string +Entrada(): void +Saida(): void

CAluno
+iaa: float +numeroAlunos: static int +universidade: static string +Entrada(): virtual +Saida(): virtual

CFuncionario
+indiceProdutividade: float +Entrada(): virtual +Saida(): virtual

CAlunoFuncionario
+indicePobreza: double +Entrada(): virtual +Saida(): virtual

Figura 19.2: Hierarquia CPessoa, CAluno, CFuncionario, CAlunoFuncionario. Veja na listagem 19.2 a classe CPessoa. Listing 19.2: A classe CPessoa.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # ifndef CPessoa_h # define CPessoa_h # include < string > // U t i l i z a r e i o b j e t o s string s

/* A classe C P e s s o a r e p r e s e n t a uma pessoa . Tem um nome , e m etodos b asicos para e n t r a d a e sa da de dados . Tem alguns c o n s t r u t o r e s e um d e s t r u t o r. A m a t r i c u l a foi a c r e s c e n t a d a na etapa de p r o j e t o . */ class CPessoa { private : std :: string nome ; std :: string matricula ;

// Acesso p r i v a d o ( s o m e n t e nesta classe )

public : // Acesso p ublico CPessoa () ; // C o n s t r u t o r CPessoa ( const CPessoa & obj ) ; // C o n s t r u t o r de c o pia // C o n s t r u t o r s o b r e c a r r e g a d o CPessoa ( std :: string _nome , std :: string _matricula ) ; virtual ~ CPessoa () ; // D e s t r u t o r virtual void Entrada () ; // E n t r a d a e sa da de dados virtual void Saida () const ; std :: string Nome () const { return nome ; }; std :: string Matricula () const { return matricula ;}; void Nome ( std :: string _nome ) { nome = _nome ; }; void Matricula ( std :: string _m ) { matricula = _m ; }; }; # endif

Listing 19.3: Implementa ca o da classe CPessoa.


1 # include < iostream >

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

372
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 # include " CPessoa . h " using namespace std ;

19.6. EXEMPLO COMPLETO COM POLIMORFISMO

// C o n s t r u t o r d e f a u l t ( sem p a r ^ ametros) CPessoa :: CPessoa () : nome ( " " ) , matricula ( " " ) { cout << " Criou objeto CPessoa construtor default " << endl ; } // C o n s t r u t o r de c o pia CPessoa :: CPessoa ( const CPessoa & obj ) { nome = obj . nome ; matricula = obj . matricula ; cout << " Criou objeto CPessoa construtor de c o pia " << endl ; } CPessoa :: CPessoa ( string _nome , string _matricula ) : nome ( _nome ) , matricula ( _matricula ) { cout << " Criou objeto CPessoa construtor s o b r e c a r r e g a d o " << endl ; } // D e s t r u t o r CPessoa ::~ CPessoa () { cout << " destruiu objeto CPessoa " << endl ; } // E n t r a d a de dados void CPessoa :: Entrada () { cout << " Entre com o nome : " ; getline ( cin , nome ) ; cout << " Entre com a matricula : " ; getline ( cin , matricula ) ; } // Sa da de dados void CPessoa :: Saida () const { cout << " Nome : " << nome << " Matricula : " << matricula << endl ; }

Veja na listagem 19.4 a classe CAluno. Listing 19.4: A classe CAluno.


1 2 3 4 5 6 7 8 9 10 11 12 13 # ifndef CAluno_h # define CAluno_h # include < string > # include " CPessoa . h " /* A classe CAluno e h e r d e i r a da classe C P e s s o a r e p r e s e n t a um aluno da u n i v e r s i d a d e . R e d e f i n e os m e t o d o s E n t r a d a/ Saida e a d i c i o n a o a t r i b u t o iaa e os m e t o d o s Iaa ( int ) , Iaa () . */ class CAluno : virtual public CPessoa { private : double iaa ; // Indice de a p r o v e i t a m e n t o static int n u m e r o A l u n o s ; // N u mero total de alunos

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

19.6. EXEMPLO COMPLETO COM POLIMORFISMO


14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 // Nome da u n i v e r s i d a d e static const std :: string u n i v e r s i d a d e ; public : CAluno () ; CAluno ( const CAluno & obj ) ; CAluno ( std :: string _nome , std :: string _matricula , double _iaa = 0) ; virtual ~ CAluno () ; virtual void Entrada () ; virtual void Saida ( std :: ostream & os ) const ; double Iaa () const { return iaa ; } void Iaa ( double _iaa ) { iaa = _iaa ; } static int N u m e r o A l u n o s () { return n u m e r o A l u n o s ; }; static const std :: string U n i v e r s i d a d e () { return u n i v e r s i d a d e ; }; }; # endif

373

Listing 19.5: Implementa ca o da classe CAluno.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 # include < iostream > using namespace std ; # include " CAluno . h " // I n i c i a l i z a a t r i b u t o s e s t aticos int CAluno :: n u m e r o A l u n o s = 0; const string CAluno :: u n i v e r s i d a d e = " U n i v e r s i d a d e Estadual do Norte Fluminense " ; CAluno :: CAluno () : iaa (0.0) { n u m e r o A l u n o s ++; cout << " Criou objeto CAluno ( " << n u m e r o A l u n o s << " ) construtor default " << endl ; } CAluno :: CAluno ( const CAluno & obj ) : CPessoa ( obj ) { iaa = obj . iaa ; n u m e r o A l u n o s ++; cout << " Criou objeto CAluno ( " << n u m e r o A l u n o s << " ) construtor de c o pia " << endl ; } CAluno :: CAluno ( string _nome , string _matricula , double _iaa ) : CPessoa ( _nome , _matricula ) , iaa ( _iaa ) { n u m e r o A l u n o s ++; cout << " Criou objeto CAluno ( " << n u m e r o A l u n o s << " ) construtor s o b r e c a r r e g a d o " << endl ; } CAluno ::~ CAluno () { cout << " Destruiu objeto CAluno : " << n u m e r o A l u n o s << endl ; numeroAlunos - -; } void CAluno :: Entrada () { CPessoa :: Entrada () ; // Chama M e todo da classe base // A d i c i o n a abaixo o que e d i f e r e n t e nesta classe cout << " Entre com o iaa do aluno : " ; cin >> iaa ; cin . get () ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

374
45 46 47 48 49 50 51 }

19.6. EXEMPLO COMPLETO COM POLIMORFISMO

void CAluno :: Saida () const { CPessoa :: Saida () ; cout << " iaa : " << iaa << endl ; }

Veja na listagem 19.6 a classe CFuncionario. Listing 19.6: A classe CFuncionario.


# ifndef C F u n c i o n a r i o _ h # define C F u n c i o n a r i o _ h # include < string > # include " CPessoa . h " /* A classe C F u n c i o n a r i o e h e r d e i r a da classe CPessoa , e r e p r e s e n t a um f u n c i o n a r i o de uma u n i v e r s i d a d e . R e d e f i n e os m e t o d o s E n t r a d a/ Saida e adiciona o indiceProdutividade e m e t o d o s para ler e setar o I n d i c e P r o d u t i v i d a d e ( int ) , I n d i c e P r o d u t i v i d a d e () */ class C F u n c i o n a r i o : virtual public CPessoa { protected : ndice de p r o d u t i v i d a d e double i n d i c e P r o d u t i v i d a d e ; // I public : C F u n c i o n a r i o () ; C F u n c i o n a r i o ( const C F u n c i o n a r i o & obj ) ; C F u n c i o n a r i o ( std :: string _nome , std :: string _matricula , double _ip = 0) ; virtual ~ C F u n c i o n a r i o () ; virtual void Entrada () ; virtual void Saida () const ; double I n d i c e P r o d u t i v i d a d e () const { return i n d i c e P r o d u t i v i d a d e ; } void I n d i c e P r o d u t i v i d a d e ( double _ip ) { i n d i c e P r o d u t i v i d a d e = _ip ; } }; # endif

Listing 19.7: Implementa ca o da classe CFuncionario.


# include < iostream > using namespace std ; # include " C F u n c i o n a r i o . h " C F u n c i o n a r i o :: C F u n c i o n a r i o () : i n d i c e P r o d u t i v i d a d e (0.0) { cout << " Criou objeto C F u n c i o n a r i o construtor default " << endl ; } C F u n c i o n a r i o :: C F u n c i o n a r i o ( const C F u n c i o n a r i o & obj ) : CPessoa ( obj ) { i n d i c e P r o d u t i v i d a d e = obj . i n d i c e P r o d u t i v i d a d e ; cout << " Criou objeto C F u n c i o n a r i o construtor de c o pia " << endl ; } C F u n c i o n a r i o :: C F u n c i o n a r i o ( string _nome , string _matricula , double _ip ) : CPessoa ( _nome , _matricul a ) , i n d i c e P r o d u t i v i d a d e ( _ip ) { cout << " Criou objeto C F u n c i o n a r i o construtor s o b r e c a r r e g a d o " << endl ; } C F u n c i o n a r i o ::~ C F u n c i o n a r i o () {

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

19.6. EXEMPLO COMPLETO COM POLIMORFISMO


cout << " Destruiu objeto C F u n c i o n a r i o : " << endl ; } void C F u n c i o n a r i o :: Entrada () { CPessoa :: Entrada () ; cout << " Entre com o i n d i c e P r o d u t i v i d a d e do funcionari o : " ; cin >> i n d i c e P r o d u t i v i d a d e ; cin . get () ; } void C F u n c i o n a r i o :: Saida () const { CPessoa :: Saida () ; cout << " i n d i c e P r o d u t i v i d a d e : " << i n d i c e P r o d u t i v i d a d e << endl ; }

375

Apresentaremos na listagem 19.8 a classe CAlunoFuncionario. Listing 19.8: A classe CAlunoFuncionario.


# ifndef C A l u n o F u n c i o n a r i o _ h # define C A l u n o F u n c i o n a r i o _ h # include " CAluno . h " # include " C F u n c i o n a r i o . h " /* A classe C A l u n o F u n c i o n a r i o r e p r e s e n t a um f u n c i o n a r i o que e aluno . Tem um nome , uma matr cula , e m etodos b a s i c o s para e n t r a d a e sa da de dados . Tem alguns c o n s t r u t o r e s e um d e s t r u t o r . A c r e s c e n t a indice de p o b r e z a */ class C A l u n o F u n c i o n a r i o : public CAluno , public C F u n c i o n a r i o { double i n d i c e P o b r e z a ; // Por d e f a u l t e private public : C A l u n o F u n c i o n a r i o () ; virtual ~ C A l u n o F u n c i o n a r i o () ; virtual void Entrada () ; virtual void Saida ( std :: ostream & os ) const ; void S e t i n d i c e P o b r e z a ( double _ i n d i c e P o b r e z a ) { i n d i c e P o b r e z a = _ i n d i c e P o b r e z a ;}; double G e t i n d i c e P o b r e z a () const { return i n d i c e P o b r e z a ; }; }; # endif

Veja na listagem ?? a implementa ca o da classe CAlunoFuncionario. Listing 19.9: Implementa ca o da classe CAlunoFuncionario.
# include < iostream > using namespace std ; # include " C A l u n o F u n c i o n a r i o . h " C A l u n o F u n c i o n a r i o :: C A l u n o F u n c i o n a r i o () { cout << " Criou objeto C A l u n o F u n c i o n a r i o construto r default " << endl ; } C A l u n o F u n c i o n a r i o ::~ C A l u n o F u n c i o n a r i o () { cout << " Destruiu objeto C A l u n o F u n c i o n a r i o " << endl ; } // A seguir c o digo o p c i o n a l /* void C A l u n o F u n c i o n a r i o :: E n t r a d a ()

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

376
{

19.6. EXEMPLO COMPLETO COM POLIMORFISMO

CAluno :: E n t r a d a () ; T F u n c i o n a r i o :: E n t r a d a () ; cout << " Entre com o ndice de p o b r e z a : "; cin >> i n d i c e P o b r e z a ; cin . get () ; } */ // S o l u c~ a o para n~ a o chamar nome e m a t r c u l a 2 vezes . void C A l u n o F u n c i o n a r i o :: Entrada () { CAluno :: Entrada () ; // E n t r a d a de nome , matr cula , iaa // E n t r a d a do i n d i c e P r o d u t i v i d a d e cout << " Entre com o n d i c e P r o d u t i v i d a d e do funcionar i o : " ; cin >> i n d i c e P r o d u t i v i d a d e ; cin . get () ; cout << " Entre com o ndice de pobreza : " ; cin >> i n d i c e P o b r e z a ; cin . get () ; // E n t r a d a do i n d i c e P o b r e z a } // Sa da de dados void C A l u n o F u n c i o n a r i o :: Saida () const { CAluno :: Saida () ; // Se chamar T F u n c i o n a r i o :: Saida ( os ) ; vai r e p e t i r os dados na tela cout << " n d i c e P r o d u t i v i d a d e : " << i n d i c e P r o d u t i v i d a d e << " ndice pobreza = : " << i n d i c e P o b r e z a << endl ; }

Veja na listagem 19.10 a implementa ca o do programa que utiliza as classes anteriormente denidas. Observe o uso de instru co es #ifndef, para inclus ao dos arquivos de cabe calho. Note ainda que utilizamos o conceito de polimorsmo. Listing 19.10: Testando a heran ca m ultipla.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 # include < iostream > # include < fstream > # include < string > // I n c l u s ~ a o de todos os a r q u i v o s de c a b e c a l h o *. h # ifndef CPessoa_h # include " CPessoa . h " # endif # ifndef CAluno_h # include " CAluno . h " # endif # ifndef C F u n c i o n a r i o _ h # include " C F u n c i o n a r i o . h " # endif # ifndef C A l u n o F u n c i o n a r i o _ h # include " C A l u n o F u n c i o n a r i o . h " # endif using namespace std ; int main () { string linha = " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\ n " ; int resp = 0; do { cout << linha << " Selecao do tipo de objeto ( -1 para sair ) \ n \ a "

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

19.6. EXEMPLO COMPLETO COM POLIMORFISMO


28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 << " CPessoa . . . . . . . . . . . . . . . . . . . . 0 \ n " << " CAluno . . . . . . . . . . . . . . . . . . . . . 1 \ n " << " C F u n c i o n a r i o . . . . . . . . . . . . . . . 2 \ n " << " C A l u n o F u n c i o n a r i o . . . . . . . . . . 3 : \ n " << linha ; cin >> resp ; cin . get () ; // Cria p o n t e i r o para um objeto , pode ser uma pessoa , // um aluno , ou um f u n c i o n ario // O p o n t e i r o sempre aponta para a classe - base C P e s s o a . CPessoa * pobj = NULL ; switch ( resp ) // E s t r u t u r a de c o n t r o l e { case 0: // Cria objeto C P e s s o a pobj = new CPessoa () ; break ; case 1: // Cria objeto CAluno pobj = new CAluno () ; break ; case 2: // Cria objeto C F u n c i o n a r i o pobj = new C F u n c i o n a r i o () ; break ; case 3: // Cria objeto C A l u n o F u n c i o n a r i o pobj = new C A l u n o F u n c i o n a r i o () ; break ; case -1: default : // Op c~ ao default cout << " \ nSair . " << endl ; return (0) ; break ; } // Este bloco usa pobj sem saber se criou CPessoa , CAluno , C F u n c i o n a r i o if ( pobj != NULL ) { pobj - > Entrada () ; pobj - > Saida ( cout ) ; delete pobj ; pobj = NULL ; } } while ( resp != -1) ; return 0; } -------------------------------------------------------------Selecao do tipo de objeto ( -1 para sair ) CPessoa . . . . . . . . . . . . . . . . . . . . 0 CAluno . . . . . . . . . . . . . . . . . . . . . 1 CFuncionario ...............2 CAlunoFuncionario ..........3: -------------------------------------------------------------0 criou objeto CPessoa construtor default Entre com o nome : Sergio Henrique Almeida Entre com a matricula : 540 Nome : Sergio Henrique Almeida Matricula : 540 destruiu objeto CPessoa -------------------------------------------------------------Selecao do tipo de objeto ( -1 para sair ) CPessoa . . . . . . . . . . . . . . . . . . . . 0

377

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

378

19.7. RESUMO DO CAP ITULO

CAluno . . . . . . . . . . . . . . . . . . . . . 1 CFuncionario ...............2 CAlunoFuncionario ..........3: -------------------------------------------------------------1 criou objeto CPessoa construto r default criou objeto CAluno (1) construtor default Entre com o nome : Viatchsla v a I . Priimenko Entre com a matricula : 68 Entre com o IAA do aluno : 10 Nome : Viatchsla va I . Priimenko Matricula : 68 iaa : 10 destruiu objeto CAluno :1 destruiu objeto CPessoa -------------------------------------------------------------Selecao do tipo de objeto ( -1 para sair ) CPessoa . . . . . . . . . . . . . . . . . . . . 0 CAluno . . . . . . . . . . . . . . . . . . . . . 1 CFuncionario ...............2 CAlunoFuncionario ..........3: -------------------------------------------------------------3 criou objeto CPessoa construto r default criou objeto CAluno (1) construtor default criou objeto C F u n c i o n a r i o construtor default criou objeto C A l u n o F u n c i o n a r i o construtor default Entre com o nome : Cintia Matsumura Entre com a matricula : 546 Entre com o IAA do aluno : 9 Entre com o i n d i c e P r o d u t i v i d a d e do funcionar io : 9 Entre com o indice de pobreza : .8 Nome : Cintia Matsumura Matricula : 546 iaa : 9 indiceProdutividade : 9 indice pobreza = : 0.8 destruiu objeto C A l u n o F u n c i o n a r i o destruiu objeto C F u n c i o n a r i o : destruiu objeto CAluno :1 destruiu objeto CPessoa -------------------------------------------------------------Selecao do tipo de objeto ( -1 para sair ) CPessoa . . . . . . . . . . . . . . . . . . . . 0 CAluno . . . . . . . . . . . . . . . . . . . . . 1 CFuncionario ...............2 CAlunoFuncionario ..........3: --------------------------------------------------------------1 Sair .

19.7

Resumo do cap tulo

Vimos na Se ca o 3.7 que polimorsmo signica muitas formas. Neste cap tulo aprendemos que C++ utiliza m etodos virtuais para implementar o conceito de polimorsmo. Vimos que os m etodos virtuais t em uma tabela VMT que cont em, em tempo de execu ca o, o endere co dos m etodos da classe. Note que para implementar o polimorsmo e necess ario uma hierarquia de classes com m etodos virtuais, e a cria ca o dos objetos deve ser feita de forma din amica, isto e, usando um ponteiro para a classe-base e o operador new. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

19.8. EXERC ICIOS

379

Aprendemos que os m etodos virtuais puros s ao utilizados para implementar o conceito de classes abstratas e classes de interface. Finalmente, vimos um exemplo completo com uso de polimorsmo.

19.8

Exerc cios

1. Por que um m etodo static n ao pode ser const? 2. Modique as listagens da Se ca o 19.6 de forma que na entrada e sa da de dados n ao apare cam repeti co es. 3. Para as listagens da Se ca o 19.6, crie uma classe de interface (com m etodos p ublicos e puros). 4. Observe que a modelagem da Figura 19.2 n ao e perfeita, anal, uma pessoa tem um nome, mas n ao tem uma matr cula. O atributo matr cula foi movido para CPessoa na etapa de projeto. Da mesma forma, o atributo string universidade n ao est a bem colocado. Como exerc cio voc e deve melhorar essa hierarquia e implementar no c odigo as modica co es que considerar pertinentes. 5. Monte o c odigo em C++ para o diagrama de classes a seguir (arquivos .h e .cpp)
Polinomio1G
+a1: double +a2: double +y: double +f(_x:double): double +Entrada(): void

Polinomio2G
+a3: double +f(_x:double): double +Entrada(): void

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

380

19.8. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 20

Friend
Vimos na Se ca o 3.8 uma breve deni ca o do conceito de friend. Neste cap tulo veremos como C++ implementa o conceito de amizade, a utiliza ca o de classes, m etodos e fun co es friend, al em de como utilizar o conceito de friend para obter maior encapsulamento das diversas classes. Iniciaremos com uma introdu ca o ao conceito de friend (Se ca o 20.1), o prot otipo para uso de friend (Se ca o 20.1), e, em seguida, veremos as classes (Se ca o 20.3) e os m etodos friend (Se ca o 20.4), al em das fun co es globais (Se ca o 20.5). Finalizamos o cap tulo com algumas senten cas para friend (Se ca o 20.6).

20.1

Introdu c ao ao conceito de friend

Vimos na Se ca o 3.2 que o conceito de encapsulamento est a relacionado com o ocultamento das informa co es do objeto. Com o encapsulamento nosso c odigo ca melhor, mais seguro. Como voc e e um programador interessado em manter a qualidade de seu c odigo, ir a preocuparse com o encapsulamento. Os atributos e m etodos de uma classe X ser ao, sempre que poss vel, private ou protected. Dessa forma, outros objetos s o poder ao acessar o que for public. Isto e, se voc e tiver um objeto do tipo X com nome obj_x, s o poder a acessar os atributos e m etodos denidos como p ublicos na classe X. Alguns objetos, por em, podem apresentar entre si um relacionamento mais pr oximo, como se fossem amigos. Por exemplo, um desconhecido n ao tem acesso a sua casa, aos seus bens pessoais; um amigo, por sua vez, pode entrar em sua casa e fazer uso de alguns objetos pessoais. Ou seja, com friend podemos implementar associa co es mais ntimas entre as classes. Vamos a um exemplo: se duas classes Y e X t em uma associa ca o do tipo Y acessa X, ent ao os m etodos a serem acessados por Y devem ser p ublicos em X. Neste caso, no entanto, os m etodos p ublicos de X cam p ublicos para qualquer um que queira usar um objeto do tipo X e n ao apenas para Y (quebrando o encapsulamento de X). Podemos manter o encapsulamento de X, informando que a classe Y tem privil egios de acesso ` a classe X, o que e feito com friend. A programa ca o orientada a objeto fornece o conceito de friend para que os objetos que s ao amigos funcionem da mesma forma. Basta informarmos quem s ao os amigos de determinada classe. Com friend podemos preservar o encapsulamento (usando private/protected) e ao mesmo tempo liberar o acesso aos membros da classe para classes/m etodos/fun co es declaradas como amigas. 381

382

20.2. PROTOTIPO PARA FRIEND

20.2

Prot otipo para friend

Veja a seguir o prot otipo para fun co es, m etodos e classes amigas. Observe que e adicionada a palavra-chave friend, utilizada para dar a uma classe, atributo, m etodo ou fun ca o a possibilidade de acesso a membros n ao p ublicos da classe. Prot otipo: // Uma fun ca o global retorno NomeFun ca o(par ametros); // Uma classe class X { retorno NomeM etodo(par ametros); }; // Uma segunda classe class Y { // Declara que a classe X e amiga da classe Y (veja se ca o 20.3) friend class X; // Declara que o m etodo X::NomeM etodo e amigo da classe Y (veja se ca o 20.4) friend retorno X::NomeM etodo(par ametros); // Declara que a fun ca o global NomeFun ca o e amiga da classe Y (veja se ca o 20.5) friend retorno NomeFun ca o(par ametros); }; Veja a seguir um conjunto de dicas para uso de friend. A declara ca o friend s o e v alida para a classe em que foi declarada, ou seja, n ao vale para as classes-derivadas. Observe que se uma classe X e amiga de Y, e a classe Y e amiga de Z, n ao implica que X seja amiga de Z, ou seja, todas as amizades devem ser explicitamente denidas. Por conven ca o o especicador friend e usualmente o primeiro. A declara ca o friend apenas indica que a classe/m etodo/fun ca o declarada como amiga e amiga. N ao pode ser confundida como a declara ca o em si da classe/m etodo/fun ca o. Au nica maneira de especicar o relacionamento friend m utuo entre duas classes e declarar toda a segunda classe como friend da primeira e vice-versa. Um m etodo declarado como friend em uma classe deixa claro que este faz parte de uma estrutura l ogica da classe, provavelmente uma associa c ao. A declara ca o de um m etodo envolve tr es aspectos: 1. O m etodo tem acesso aos membros internos. 2. O m etodo est a no escopo da classe. 3. O m etodo precisa de um objeto da classe (com exce ca o dos m etodos est aticos). Observe que uma fun ca o ou um m etodo friend tem apenas o primeiro aspecto. Para deixar o layout do seu programa mais bem organizado e manter um determinado padr ao, coloque todas as declara co es friend no m da classe. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

20.3. CLASSES FRIEND

383

20.3

Classes friend

Se uma classe X for amiga da classe Y, os m etodos da classe X poder ao acessar todos os atributos e m etodos de um objeto da classe Y. No exemplo da listagem 20.1, o m etodo MX() da classe X pode acessar os atributos do objeto obj_y (recebido como par ametro), porque toda classe X e declarada como amiga da classe Y. Observe neste exemplo que toda classe Y e privada; desta forma os atributos e m etodos de Y s o podem ser acessados pela classe X. Listing 20.1: Usando classes friend.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 # include < iostream > // S o m e n t e d e c l a r a a classe Y class Y ; // D e c l a r a c~ ao e defini c~ a o da classe X class X { int x ; public : // M e todo da classe X que recebe como p a r ^ a m e t r o um objeto Y void MX ( Y & obj_y ) ; }; // D e c l a r a c~ ao e defini c~ a o da classe Y class Y { private : int y ; // A classe X e amiga , o m e todo MX () pode a c e s s a r os a t r i b u t o s de Y friend class X ; }; void X :: MX ( Y & obj_y ) { std :: cout << " Fazendo x = obj_y . y ; " << std :: endl ; // O b s e r v e o acesso ao a t r i b u t o y do objeto obj_y x = obj_y . y ; } int main () { std :: cout << " Criando objetos X obj_x ; Y obj_y ; " << std :: endl ; X obj_x ; Y obj_y ; // O objeto obj_x acessa o m e todo MX p a s s a n d o como p a r ^ a m e t r o o obj_y obj_x . MX ( obj_y ) ; return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ List_18_1 Criando objetos X obj_x ; Y obj_y ; Fazendo x = obj_y . y ;

20.4

M etodos friend

No exemplo da listagem 20.2, um m etodo da classe Y e declarado como amigo da classe Z na linha: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

384 friend void Y::MY(Z& obj_z);

20.5. FUNC OES GLOBAIS FRIEND

Como o m etodo MY() e declarado como amigo da classe Z, pode acessar os atributos de um objeto do tipo Z. Observe que o atributo z, mesmo sendo privado, e acessado pelo m etodo MY(). Listing 20.2: Usando m etodos friend.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 # include < iostream > class Z ; // S o m e n t e d e c l a r a a classe Z class Y // D e c l a r a c~ ao e defini c~ a o da classe Y { private : int y ; public : // M e todo da classe Y que recebe um objeto do tipo Z . void MY ( Z & objZ ) ; }; class Z { private : int z ; // O m e todo MY da classe Y e amigo , pode a c e s s a r os a t r i b u t o s de Z friend void Y :: MY ( Z & objZ ) ; }; void Y :: MY ( Z & objZ ) { std :: cout << " Fazendo y = objZ . z ; " << std :: endl ; y = objZ . z ; } int main () { std :: cout << " Criando objetos Y objY ; Z objZ ; " << std :: endl ; Y objY ; Z objZ ; objY . MY ( objZ ) ; return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ List_18_2 Criando objetos Y obj_y ; Z obj_z ; Fazendo y = obj_z . z ;

20.5

Fun c oes globais friend

Uma fun ca o com escopo global e uma fun ca o que pode ser acessada a qualquer momento. Ela e declarada e denida fora de qualquer bloco, classe, estrutura ou uni ao. Programas estruturados escritos em C costumam ter diversas fun co es globais (veja discuss ao sobre escopo em C na Se ca o B.4). Veja na listagem 20.3 um exemplo de fun ca o global friend. A fun ca o FuncaoGlobalAmiga() recebe como par ametro um ponteiro para um objeto do tipo X. Listing 20.3: Usando fun co es globais friend.
1 # include < iostream >

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

20.6. SENTENCAS PARA FRIEND


2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

385

// D e c l a r a que existe a classe X class X ; // D e c l a r a uma fun c~ a o global void F u n c a o G l o b a l A m i g a ( X * ptr_x ) ; // D e c l a r a a classe X class X { private : static const int x = 321; // D e c l a r a que a fun c~ a o global e amiga da classe X friend void F u n c a o G l o b a l A m i g a ( X * ptr_x ) ; }; // Define a fun c~ a o global void F u n c a o G l o b a l A m i g a ( X * ptr_x ) { std :: cout << ptr_x - > x << std :: endl ; } int main () { X * ptr_x = new X ; F u n c a o G l o b a l A m i g a ( ptr_x ) ; return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ g ++ List -18 -3 - friend - f u n c a o G l o b a l . cpp [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ a . out 321

Dica: evite o uso de fun co es globais em um programa em C++.

20.6

Senten cas para friend

Por padr ao da linguagem, m etodos construtores, m etodos destrutores e m etodos virtuais n ao podem ser friend. Como visto no Cap tulo 4 Modelagem Orientada a Objeto e na Se ca o 6.4.7, uma classe de associa ca o e utilizada para representar conceitos que s o passam a existir com o relacionamento de duas ou mais classes. Para aumentar o encapsulamento do programa, uma classe de associa ca o pode ser toda privada, tendo, em seu interior, declara co es friend das classes que far ao acesso. Na medida do poss vel, classes/m etodos/fun co es friend n ao devem modicar o estado do objeto. Fun co es friend s ao comumente utilizadas para implementar a sobrecarga de operador (veja Se ca o 21.4). Observe que em uma hierarquia os m etodos da classe-base s ao herdados pela classeco es/m etodos declaradas como friend da classe-base n ao s ao herdaderivada, mas as fun das. Fun co es/m etodos friend n ao podem ser virtuais. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

386

20.7. RESUMO DO CAP ITULO

Uma fun ca o friend pode acessar atributos est aticos da classe em que foi declarada como amiga (veja exemplo na listagem 20.3). S o use friend quando realmente necess ario. Em alguns casos o uso de friend viola conceitos de POO, devendo, por isso, ser evitados. 2 Tamb em podemos usar friend com fun co es e classes templates. Veremos templates no Cap tulo 27 Templates (ou Gabaritos). 2 Como a fun ca o friend n ao faz parte da classe, pois s o e amiga, ela n ao recebe um ponteiro impl cito this, ou seja, e preciso passar explicitamente o objeto a ser manipulado pela fun ca o.

20.7

Resumo do cap tulo

Em nossos programas devemos usar, sempre que poss vel, o conceito de encapsulamento; desta forma estaremos diminuindo o acoplamento e as interdepend encias do sistema. O sistema ca mais livre. Como algumas classes e fun co es apresentam naturalmente um relacionamento mais ntimo, como se fossem amigas, C++ apresenta o conceito de friend, que d a a uma determinada classe/m etodo/fun ca o a possibilidade de acessar os membros ocultos (protegidos/privados) da classe declarada como amiga. Aprendemos, por meio dos exemplos apresentados, como implementar o conceito de friend em C++. No pr oximo cap tulo veremos que fun co es friend s ao comumente utilizadas para implementar a sobrecarga de operador (Se ca o 21.4).

20.8

Exerc cios

1. Descreva com suas palavras o conceito de friend. 2. D e exemplos de relacionamentos de amizade na vida real e em termos de programa ca o. 3. Qual a diferen ca pr atica do uso de friend com classes e m etodos? 4. No exemplo da listagem 20.1, tente acessar diretamente o atributo obj_y. 5. Modique as listagens 20.1 e 20.2, adicionando novos atributos, m etodos e relacionamentos de amizades. 6. Encontre o erro da listagem 20.3. 7. Substitua a fun ca o global por um m etodo membro na listagem 20.3.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 21

Sobrecarga de Operador
Neste cap tulo veremos uma introdu ca o ` a sobrecarga de operador (Se ca o 21.1), a lista de operadores que podem ser sobrecarregados (Se ca o 21.2) e os prot otipos para implementar a sobrecarga de operador em C++ (Se ca o 21.3). Em seguida apresenta-se a sobrecarga de operador como fun ca o friend (Se ca o 21.4) e como m etodo membro da classe (Se ca o 21.5). Veremos ainda um exemplo de classe com sobrecarga de operador e seu uso (Se ca o 21.6). No nal do cap tulo apresentam-se alguns prot otipos de sobrecarga de operador (Se ca o 21.7), como sobrecarregar new (Se ca o 21.8), como sobrecarregar new dentro de uma classe (Se ca o 21.8.1), e algumas senten cas (Se ca o 21.9).

21.1

Introdu c ao ` a sobrecarga de operador

Quando denimos uma classe, denimos um tipo do programador, adicionamos um conjunto de atributos e de m etodos que fazem sentido para a classe. Se criarmos uma classe Polinomio, podemos criar uma fun ca o para somar dois polin omios. Veja o exemplo: Exemplo: // Cria objetos do tipo Polinomio Polinomio pol_a, pol_b, pol_c; // Soma os polinomios pol_a e pol_b e armazena o resultado em pol_c Somar ( pol_a, pol_b, &pol_c ); Embora seja funcional, a nota ca o mostrada e t pica de um programa em C e Java. Seria interessante se pud essemos realizar opera co es como soma (+), subtra ca o (-) e multiplica ca o (*) utilizando os operadores usuais. O operador + realizaria a soma de dois polin omios; o operador * realizaria a multiplica ca o dos polin omios e assim por diante. O c odigo caria mais parecido com a linguagem matem atica. Veja o exemplo: Exemplo: pol_c = pol_a + pol_b; Assim, podemos denir sobrecarga de operador como a deni ca o das tarefas que determinado operador realiza sobre um tipo denido pelo programador. Note que com C++ podemos utilizar uma nota ca o muito mais clara e pr oxima da matem atica. Apresenta-se a seguir a lista de operadores de C++ que podem ser sobrecarregados. 387

388

21.2. OPERADORES QUE PODEM SER SOBRECARREGADOS

21.2

Operadores que podem ser sobrecarregados

Antes de apresentarmos a forma utilizada para implementar a sobrecarga dos operadores, e preciso classicar os operadores. Veja na Tabela 21.1 quais os operadores podem ser un arios ou bin arios. S ao un arios quando atuam sobre um u nico objeto e bin arios quando atuam sobre dois objetos. Observe que alguns operadores n ao podem ser sobrecarregados. No exemplo z = x + y;, o operador + e bin ario, opera sobre os objetos x e y. O operador = e bin ario pois armazena o resultado de "x+y" em z. No exemplo r++, o operador ++ e un ario, pois atua somente sobre o objeto r. Tabela 21.1: Operadores que podem ser sobrecarregados. Operadores bin arios + /= < <= , & ++ . ! %= == -> * -.* * = = != [] + :: / < &= <= () ! ?: % > |= >= new[] += << && delete[] & -= >> || new | *= > >= ->* delete

Operadores un arios ou bin arios Operadores un arios N ao podemos sobrecarregar

Nota: n ao podemos alterar a regra de preced encia e associatividade da linguagem (veja Tabela C.1). Isso signica que na seq u encia z = x + y;, primeiro ser a realizada a soma e depois a igualdade, e esta seq u encia n ao poder a ser alterada.

21.3

Prot otipo para sobrecarga de operador

Veja a seguir o prot otipo para sobrecarga de operador como fun ca o friend e m etodo membro da classe. Observe que a declara ca o e a deni ca o s ao iguais ` as de um m etodo/fun ca o, apenas substitu mos o nome do m etodo/fun ca o pela palavra-chave operator. Em (1) temos a sobrecarga de operador un ario como fun ca o friend; observe que a fun ca o recebe apenas um par ametro o objeto obj1. Em (2) temos a sobrecarga de operador bin ario como fun ca o friend; observe que a fun ca o recebe dois par ametros os objetos obj1 e obj2. Como a fun ca o friend n ao faz parte da classe, pois s o e amiga, ela n ao recebe um ponteiro impl cito this, ou seja, e preciso passar explicitamente o objeto a ser manipulado pela fun ca o. Veja detalhes na Se ca o 21.4. Em (3) declaramos a sobrecarga de operador un ario como m etodo membro; observe que o m etodo n ao recebe nenhum par ametro. Lembre-se de que um m etodo de uma classe tem acesso a todos os atributos e aos outros m etodos da classe. Em (4) declaramos a sobrecarga de operador bin ario como m etodo membro; neste caso, o segundo objeto deve ser recebido como par ametro. Veja detalhes na Se ca o 21.5. Prot otipo: class CNomeClasse { Tipo atributo; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

FRIEND 21.4. SOBRECARGA DE OPERADOR COMO FUNC AO // (1) Sobrecarga de operador un ario como fun ca o friend (veja se ca o 21.4) friend CNomeClasse & operatorX (CNomeClasse & obj1); // (2) Sobrecarga de operador bin ario como fun ca o friend (veja se ca o 21.4) friend CNomeClasse & operatorX (CNomeClasse & obj1, CNomeClasse & obj2); // (3) Sobrecarga de operador un ario como m etodo membro (veja se ca o 21.5) CNomeClasse & operatorX(); // (4) Sobrecarga de operador bin ario como m etodo membro (veja se ca o 21.5) CNomeClasse & operatorX(CNomeClasse & obj2); }; // (1) Deni ca o de sobrecarga de operador un ario como fun ca o friend CNomeClasse & operatorX (CNomeClasse & obj1) {... return (CNomeClasse); } // (2) Deni ca o de sobrecarga de operador bin ario como fun ca o friend CNomeClasse & operatorX (CNomeClasse & obj1, CNomeClasse & obj2) {... return (CNomeClasse); } // (3) Deni ca o de sobrecarga de operador un ario como m etodo membro CNomeClasse & CNomeClasse::operatorX() {... return (CNomeClasse); } // (4) Deni ca o de sobrecarga de operador bin ario como m etodo membro CNomeClasse & CNomeClasse::operatorX(CNomeClasse & obj2) {... return (CNomeClasse); } Vamos abordar primeiro a sobrecarga como fun ca o friend.

389

21.4

Sobrecarga de operador como fun c ao friend

Lembre-se que fun co es friend s ao fun co es amigas da classe; n ao fazem parte dela. A declara ca o friend fornece ` a fun ca o a possibilidade de acessar os atributos/m etodos do objeto como se zesse parte da classe ( e uma maneira de fazer com que a fun ca o amiga tenha acesso a todos os atributos e m etodos da classe. Veja Cap tulo 20 Friend). No exemplo a seguir a fun ca o TestaIgualdade() retorna verdadeiro (true) se p1==p2, isto e, se p1.x == p2.x e p1.y == p2.y. Exemplo: // Arquivo CPonto.h class CPonto { public: int x, y; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

390

21.5. SOBRECARGA DE OPERADOR COMO METODO MEMBRO DA CLASSE friend bool TestaIgualdade (const CPonto& p1, const CPonto& p2); }; // Arquivo CPonto.cpp bool TestaIgualdade(const CPonto& p1, const CPonto& p2) { return (p1.x == p2.x) && (p1.y == p2.y); }

Agora vamos montar nossa classe CPonto, substituindo o m etodo TestaIgualdade(), pela sobrecarga do operator== . Note que os operadores denidos com a palavra-chave friend tamb em t em acesso a todos os atributos e m etodos da classe. Exemplo: // Arquivo CPonto.h // Declara c~ ao da sobrecarga de operador bin ario como fun c~ ao friend class CPonto { public: int x, y; friend bool operator== (const CPonto& p1, const CPonto& p2); }; // Arquivo CPonto.cpp // Implementa c~ ao da sobrecarga de operadores bin arios como func~ ao friend bool operator==(const CPonto& p1, const CPonto& p2) { return (p1.x == p2.x) && (p1.y == p2.y); } Observe que a sobrecarga e declarada e denida da mesma forma que uma fun ca o comum. Au nica diferen ca e que, em vez de chamar TestaIgualdade(), usamos o nome operator==. Observe que o operador == verica se os atributos de p1 e p2 s ao iguais. Veja exemplo completo nas listagens 21.1, 21.2 e 21.3.

21.5

Sobrecarga de operador como m etodo membro da classe

Outra forma de implementar a sobrecarga de operador e usar um m etodo membro da classe. Sendo um m etodo da classe, pode acessar diretamente os atributos do objeto. Observe que um operador un ario n ao receber a nenhum par ametro (prot otipo (3)) e um operador bin ario receber a apenas um (prot otipo (4)). Veja no exemplo a seguir que o operador ++ incrementa os valores de x (x++) e de y (y++). O operador + cria um terceiro objeto, com nome p3, no qual armazena a soma de p1 e p2. Observe na linha p3->x = this->x + p2.x; que armazena em p3->x a soma de this->x com p2.x. Exemplo: // CPonto.h class CPonto { public: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

21.6. EXEMPLO PRATICO DE SOBRECARGA DE OPERADOR int x,y; // Sobrecarga de operador un ario como m etodo membro CPonto& operator++(); // Sobrecarga de operador bin ario como m etodo membro CPonto& operator+ (const CPonto& p2); }; // CPonto.cpp CPonto& CPonto::operator++() { x++; y++; return *this; } CPonto& CPonto::operator+(const CPonto& p2) { CPonto *p3 = new CPonto; p3->x = this->x + p2.x; p3->y = this->y + p2.y; return *p3; }

391

21.6

Exemplo pr atico de sobrecarga de operador

Os exemplos apresentados a seguir mostram, na pr atica, como usar a sobrecarga de operador. Veremos nas listagens 21.1, e 21.2 novamente a classe CPonto, agora com v arios operadores sobrecarregados. Observe na listagem 21.1 o uso de sobrecarga de operador. Note que temos um conjunto de m etodos sobrecarregados como m etodo membro e outro como fun ca o friend. A listagem inclui explica co es adicionais. Listing 21.1: A classe CPonto com sobrecarga de operador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # ifndef CPonto_h # define CPonto_h # include < iostream > class CPonto { private : int x ; int y ; static int contador ; public : CPonto () : x (0) , y (0) { contador ++; } CPonto ( const int _x , const int _y ) : x ( _x ) , y ( _y ) { contador ++; } CPonto ( const CPonto & p ) { x = p.x; y = p.y; contador ++; } virtual ~ CPonto () { contador - -; } inline void Set ( const CPonto & p ) {

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

392
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 x = p.x; y = p.y;

21.6. EXEMPLO PRATICO DE SOBRECARGA DE OPERADOR

} inline void Set ( const int &x , const int & y ) { this - > x = x ; // Uso de this this - > y = y ; } int X ( int _x ) { x = _x ; } int X () const { return x ; } int Y ( int _y ) { y = _y ; } int Y () const { return y ; } virtual void Desenha () ; static int Contador () { return contador ; }; // D e c l a r a c~ a o da s o b r e c a r g a de o p e r a d o r e s u n a r i o s como m e todo membro CPonto & operator ++( int ) ; // S o b r e c a r g a para ++ p CPonto & operator - -( int ) ; // S o b r e c a r g a para --p CPonto & operator ++() ; // S o b r e c a r g a para p ++ CPonto & operator - -() ; // S o b r e c a r g a para p - // D e c l a r a c~ a o da s o b r e c a r g a de o p e r a d o r e s b i n a r i o s como m e todo membro CPonto & operator + ( const CPonto & p2 ) const ; CPonto & operator - ( const CPonto & p2 ) const ; CPonto & operator = ( const CPonto & p2 ) ; CPonto & operator += ( const CPonto & p2 ) ; CPonto & operator -= ( const CPonto & p2 ) ; // D e c l a r a c~ a o da s o b r e c a r g a de o p e r a d o r e s b i n a r i o s como fun c~ a o friend friend bool operator == ( const CPonto & p1 , const CPonto & p2 ) ; friend bool operator != ( const CPonto & p1 , const CPonto & p2 ) ; // S o b r e c a r g a do o p e r a d o r de i n s e r c~ a o << , uso cout << ponto ; friend std :: ostream & operator < <( std :: ostream & out , const CPonto & p ) ; // S o b r e c a r g a do o p e r a d o r de e x t r a c~ a o >> , uso cin >> ponto ; friend std :: istream & operator > >( std :: istream & in , CPonto & p ) ; }; # endif

Na listagem 21.2 apresentamos a deni ca o da sobrecarga dos operadores para CPonto. O uso de this e descrito na Se ca o 15.4. Observe que a implementa ca o da sobrecarga dos operadores operator++(int) e operator++() s ao iguais; o mesmo ocorre com operator--(int) e operator--(). Os operadores + e - criam um objeto adicional CPonto* p3;, que e usado para armazenar o resultado da opera ca o. Note no in cio do operador= o uso da linha if( this == &p2) return *this; a qual impede que um objeto seja igualado a si mesmo. Finalmente, observe que os operadores (operator< < e operator> >) ser ao sempre sobrecarregados como m etodos friend. Listing 21.2: Implementa ca o da classe CPonto com sobrecarga de operador.
1 2 3 4 5 6 7 8 9 10 # include < iostream > # include " CPonto . h " int CPonto :: contador = 0; // M e todo v i r t u a l void CPonto :: Desenha () { std :: cout << " \ nCPonto : Coordenada x = " << x << " \ nCPonto : Coordenada y = " << y << std :: endl ; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

21.6. EXEMPLO PRATICO DE SOBRECARGA DE OPERADOR


11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

393

// D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r ++. S i m p l e s m e n t e i n c r e m e n t a x e y CPonto & CPonto :: operator ++( int ) { this - > x ++; this - > y ++; return * this ; } CPonto & CPonto :: operator ++() { this - > x ++; this - > y ++; return * this ; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r - -. S i m p l e s m e n t e d e c r e m e n t a x e y CPonto & CPonto :: operator - -( int ) { this - >x - -; this - >y - -; return * this ; } CPonto & CPonto :: operator - -() { this - >x - -; this - >y - -; return * this ; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r b i n ario + CPonto & CPonto :: operator +( const CPonto & p2 ) const { CPonto * p3 = new CPonto ; p3 - > x = this - > x + p2 . x ; p3 - > y = this - > y + p2 . y ; return * p3 ; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r b i n ario CPonto & CPonto :: operator -( const CPonto & p2 ) const { CPonto * p3 = new CPonto ; p3 - > x = this - > x - p2 . x ; p3 - > y = this - > y - p2 . y ; return * p3 ; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r = CPonto & CPonto :: operator =( const CPonto & p2 ) { if ( this == & p2 ) return * this ; // opcional , evita auto c o pia this - > x = p2 . x ; this - > y = p2 . y ; return * this ; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r += CPonto & CPonto :: operator +=( const CPonto & p2 ) { this - > x += p2 . x ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

394
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 this - > y += p2 . y ; return * this ; }

21.6. EXEMPLO PRATICO DE SOBRECARGA DE OPERADOR

// D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r -= CPonto & CPonto :: operator -=( const CPonto & p2 ) { this - > x -= p2 . x ; this - > y -= p2 . y ; return * this ; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r == , como fun c~ a o friend bool operator ==( const CPonto & p1 , const CPonto & p2 ) { return ( p1 . x == p2 . x ) && ( p1 . y == p2 . y ) ; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r != , como fun c~ a o friend bool operator !=( const CPonto & p1 , const CPonto & p2 ) { return !( p1 == p2 ) ; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r de i n s e r c~ a o <<, como fun c~ a o friend std :: ostream & operator < <( std :: ostream & out , const CPonto & p ) { out << " ( " <<p . x << " , " <<p . y << " ) " ; return out ; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r de e x t r a c~ a o >>, como fun c~ a o friend std :: istream & operator > >( std :: istream & in , CPonto & p ) { in >> p . x ; in >> p . y ; return in ; }

Na listagem 21.3 apresentamos o teste de CPonto com sobrecarga. Para entender melhor o funcionamento do programa, compare cada linha com cout com a sa da gerada. Listing 21.3: Usando a sobrecarga de operador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # include < iostream > # include " CPonto . h " using namespace std ; // E x e m p l o de c r i a c~ a o e uso do objeto CPonto com s o b r e c a r g a int main () { int x ; int y ; // Cria o b j e t o s do tipo CPonto com nomes p1 , p2 , p3 CPonto p1 , p2 , p3 ; // Usando o p e r a d o r >> cout << " Entre com os valores de p1 [ x enter y enter ]: " ; cin >> p1 ; cin . get () ; // Usando o p e r a d o r << cout <<" --- p1 - - > " << p1 << " --- p2 - - > " << p2 << " --- p3 - - > " << p3 << endl ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

21.6. EXEMPLO PRATICO DE SOBRECARGA DE OPERADOR


20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

395

// Usando o p e r a d o r = p2 = p1 ; cout << " Ap o s p2 = p1 " << endl ; cout << " --- p1 - - > " << p1 << " --- p2 - - > " << p2 << " --- p3 - - > " << p3 << endl ; // Usando o p e r a d o r == cout << " Testando p1 == p2 " << endl ; if ( p1 == p2 ) cout << " p1 == p2 " << endl ; else cout << " p1 != p2 " << endl ; // Usando o p e r a d o r ++ p2 ++; cout << " Ap o s p2 ++ " << endl ; cout << " --- p1 - - > " << p1 << " --- p2 - - > " << p2 << " --- p3 - - > " << p3 << endl ; // Usando o p e r a d o r = cout << " Fazendo p3 = p2 ++ " << endl ; p3 = p2 ++; cout << " --- p1 - - > " << p1 << " --- p2 - - > " << p2 << " --- p3 - - > " << p3 << endl ; // Usando o p e r a d o r = cout << " Fazendo p3 = ++ p2 " << endl ; p3 = ++ p2 ; cout << " --- p1 - - > " << p1 << " --- p2 - - > " << p2 << " --- p3 - - > " << p3 << endl ; // Usando o p e r a d o r != cout << " Testando p2 == p3 " << endl ; if ( p2 != p3 ) cout << " p2 != p3 " << endl ; else cout << " p2 == p3 " << endl ; // Usando o p e r a d o r e s + e = p3 = p1 + p2 ; cout << " Ap o s p3 = p1 + p2 " << endl ; cout << " --- p1 - - > " << p1 << " --- p2 - - > " << p2 << " --- p3 - - > " << p3 << endl ; // Usando o p e r a d o r e s p - - e --p p3 - -; -- p2 ; p1 = p2 - p3 ; cout << " Ap os p3 - -; -- p2 ; p1 = p2 - p3 ; " << endl ; cout << " --- p1 - - > " << p1 << " --- p2 - - > " << p2 << " --- p3 - - > " << p3 << endl ; // Usando o p e r a d o r e s p += e p -= p3 += p2 ; p1 -= p2 ; cout << " Ap os p3 += p2 ; p1 -= p2 ; " << endl ; cout << " --- p1 - - > " << p1 << " --- p2 - - > " << p2 << " --- p3 - - > " << p3 << endl ; return 0; } Entre com os valores de p1 [ x enter y enter ]:1 2 --- p1 - - >(1 , 2) --- p2 - - >(0 , 0) --- p3 - - >(0 , 0) Ap o s p2 = p1 --- p1 - - >(1 , 2) --- p2 - - >(1 , 2) --- p3 - - >(0 , 0) Testando p1 == p2 p1 == p2 Ap o s p2 ++ --- p1 - - >(1 , 2) --- p2 - - >(2 , 3) --- p3 - - >(0 , 0)

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

396

21.7. COMO SOBRECARREGAR ++ E --

Fazendo p3 = p2 ++ --- p1 - - >(1 , 2) --- p2 - - >(3 , 4) --- p3 - - >(3 , 4) Fazendo p3 = ++ p2 --- p1 - - >(1 , 2) --- p2 - - >(4 , 5) --- p3 - - >(4 , 5) Testando p2 == p3 p2 == p3 Ap o s p3 = p1 + p2 --- p1 - - >(1 , 2) --- p2 - - >(4 , 5) --- p3 - - >(5 , 7) Ap os p3 - -; -- p2 ; p1 = p2 - p3 ; --- p1 - - >( -1 , -2) --- p2 - - >(3 , 4) --- p3 - - >(4 , 6) Ap os p3 += p2 ; p1 -= p2 ; --- p1 - - >( -4 , -6) --- p2 - - >(3 , 4) --- p3 - - >(7 , 10)

21.7

Como sobrecarregar ++ e --

Veja a seguir o prot otipo para sobrecarga dos operadores ++ e --. Observe que, para sobrecarga do operator++ (pr e-xado, como em ++obj), n ao passamos nenhum par ametro, mas, para sobrecarrega do operator++ (p os-xado, como em obj++), passamos como par ametro um int. Note que o par ametro int n ao e utilizado; ele e necess ario apenas para diferenciar obj++ de ++obj. Prot otipo: Tipo operator++(); Operador para Tipo operator- -(); Operador para Tipo operator++(int); Operador para Tipo operator- -(int); Operador para ++obj; Incremento Pr e-xado. - -obj; Decremento Pr e-xado. obj++; Incremento P os-xado. obj- -; Decremento P os-xado.

21.8

Como sobrecarregar new2

O operador new pode ser sobrecarregado de tr es formas diferentes. Veja a seguir os prot otipos para sobrecarga de new. Observe que este est a no escopo global. Prot otipo: void* ::operator new(std::size t size) throw (std::bad alloc); // (1) void* ::operator new(std::size t size, const std::nothrow t &) throw(); // (2) void* ::operator new(std::size t size, void* ptr) throw (); // (3) delete ptr->T(); A sobrecarga-padr ao de new e dada em (1). Para usar new padr ao fa ca: new T; Outra sobrecarga para new e new(nothrow) , uma vers ao de new que n ao lan ca exce co es (item (2)). Para usar new(nothrow) fa ca: new (std::nothrow) T; . O item (3) ilustra o uso de new in place. Com ele, o novo objeto vai ser armazenado em um endere co de mem oria existente, ou seja, new in place n ao pede mem oria para o sistema operacional, pois usa a mem oria do objeto previamente alocado (existente). Note que o sizeof() do novo objeto deve ser menor ou igual ao anterior. Para usar new in place fa ca: new (ptr) T; . Note que, quando usamos new in place, devemos chamar o destrutor do objeto criado explicitamente. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

21.8. COMO SOBRECARREGAR NEW2

397

Dica: evite usar new(nothrow), pois ele elimina o lan camento de exce co es, e, como o uso de exce co es e um padr ao da linguagem, os usu arios da sua biblioteca/programa esperam seu uso. A dica e: se for realmente necess ario usar new(nothrow), seu uso deve ser muito bem documentado.

21.8.1

Como sobrecarregar new dentro de uma classe2

O exemplo da listagem 21.4 mostra a declara ca o e o uso de sobrecarga de new para uma classe do usu ario. Observe que sobrecarregamos todas as tr es formas de new. Em cada sobrecarga enviamos uma mensagem para tela e, em seguida, chamamos o operador global equivalente de new. Note que na chamada a new o primeiro par ametro std::size_t n e passado implicitamente. Listing 21.4: Sobrecarregando new em uma classe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 # include < iostream > using namespace std ; class CNome { char ch ; public : // S o b r e c a r g a para new Padr~ ao static void * operator new ( std :: size_t n ) throw () { cout << " Usando new padr~ a o da classe " << endl ; return :: operator new ( n ) ; } // S o b r e c a r g a para new n o t h r o w static void * operator new ( std :: size_t n , const std :: nothrow_t & r ) throw () { cout << " Usando new nothrow da classe " << endl ; return :: operator new (n , r ) ; } // S o b r e c a r g a para new in place static void * operator new ( std :: size_t n , void * ptr ) throw () { cout << " Usando new in place da classe " << endl ; return :: operator new ( n , ptr ) ; } CNome () { cout << " Construiu o objeto CNome . " << endl ; ~ CNome () { cout << " Destruiu o objeto CNome . " << endl ; }; class CAux { public : int x ; CAux () { cout << " Construtor classe auxiliar \ n " ; } ~ CAux () { cout << " Destrutor classe auxiliar \ n " ; } }; int main () { // Usando new padr~ ao CNome * prt_padrao = new CNome ; delete prt_padrao ;

} }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

398
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

21.9. SENTENCAS PARA SOBRECARGA DE OPERADOR

// Usando new n o t h r o w CNome * prt_nothro w = new ( std :: nothrow ) CNome ; delete prt_nothro w ; // Usando new in place // Cria objeto que tem m e m o r i a s u f i c i e n t e para caber CNome CAux * ptr_inpla c e = new CAux ; // Cria objeto CNome usando new in place e a r m a z e n a em p t r _ i n p l a c e new ( static_cast < void * >( ptr_inpla ce ) ) CNome ; // Chama e x p l i c i t a m e n t e o d e s t r u t o r do objeto criado , p r e c i s a do cast ( reinterpret_ ca s t < CNome * >( ptr_inplac e ) ) - >~ CNome () ; // Chama o d e s t r u t o r do objeto o r i g i n a l delete ptr_inplac e ; return 0; } Usando new padr~ a o da classe Construiu o objeto CNome . Destruiu o objeto CNome . Usando new nothrow da classe Construiu o objeto CNome . Destruiu o objeto CNome . Construto r classe auxiliar Usando new in place da classe Construiu o objeto CNome . Destruiu o objeto CNome . Destrutor classe auxiliar

Dica importante: se sobrecarregar new em uma classe, implemente todas as tr es formas de sobrecarga para que o usu ario da sua biblioteca/programa n ao tenha surpresas desagrad aveis. Isto e necess ario, pois se voc e sobrecarregar apenas new, e desconsiderar new(nothrow), um usu ario pode usar as diferentes formas de new no mesmo programa, e n ao ir a compreender o porqu e do funcionamento diferente. Novamente, a boa documenta ca o do sistema e importante.

21.9

Senten cas para sobrecarga de operador

Voc e j a deve ter percebido que muitos operadores da linguagem C++ s ao sobrecarregados para os tipos internos. Por exemplo, o operador * e utilizado para multiplica ca o, declara ca o de ponteiros ou para obter o conte udo de ponteiros. Tente utilizar sempre sobrecarga como m etodo membro. A sobrecarga como fun ca o friend cria uma fun ca o global, que e desaconselh avel em um programa orientado a objeto. Criar uma sobrecarga para += n ao signica que voc e sobrecarregou + e =. Por padr ao, somente sobrecarregue new e delete como m etodos est aticos. Operadores de atribui ca o (=, +=,-=, ..) devem retornar uma refer encia ao objeto, pois podemos ter algo como obj1 = obj2 = obj3;. Exemplo: T& operator=(const T& obj) Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

21.9. SENTENCAS PARA SOBRECARGA DE OPERADOR { ... return *this; }

399

Por padr ao, quando criar uma classe, sempre implemente o construtor de c opia e o operador de atribui ca o (operator=()). Lembre-se de que o operator=() deve evitar a autoc opia. Exemplo: T& T::operator=(const T& src) { if(this == &src) // Evita autoc opia return *this; ...copiar atributos... return *this; // Retorna refer^ encia } A utiliza ca o do operador de atribui ca o (a = b) e do construtor de c opia por inicializa ca o (int a = b;) s ao duas opera co es diferentes. Para evitar surpresas, crie voc e mesmo os operadores de c opia e de atribui ca o sempre que existirem atributos din amicos. Exemplo: class A { A(); // Construtor A(const A& ); // Construtor de c opia por inicializa c~ ao A& operator=(const A& );// Operador de atribui c~ ao }; Os operadores de atribui ca o =, apontador para membro ->, subscrito [] e par enteses () s o podem ser sobrecarregados como m etodos membro da classe (n ao podem ser friend). Quando for implementar a sobrecarga de operador esteja atento a efeitos como: Exemplo: obj1 = obj2 = obj3; // Encadeamentos string1 = string2 = "texto"; // Tipos diferentes complex_c = complex_a + double_x; // Sobrecarga m ultipla complex_d = double_y + complex_a; Observe que os operadores < < e > >, quando aplicados a streams, sempre ser ao sobrecarregados como fun ca o friend. Para reduzir o n umero de sobrecargas, utilize m etodos de convers ao (veremos as convers oes no Cap tulo 25 Convers oes). Veja a seguir outros prot otipos de sobrecarga. Prot otipo: Tipo* operator & (); Operador endere co de. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

400 Tipo operator & (Tipo); Operador & bin ario. Tipo* operator->(); Operador de acesso. Tipo operator-(); Operador - , un ario. Tipo operator-(Tipo); Operador -, bin ario. Tipo & operator[](const Tipo &); Operador subscrito. Tipo & operator()(Tipo &); Operador chamada de fun ca o.

21.10. RESUMO DO CAP ITULO

2 Quando sobrecarregar < <, n ao envie a sa da diretamente para cout; envie-a para a stream, pois se pode ter algo como: Exemplo: cout < < "teste " < < objeto < < " "; 2 Segundo Stroustrup [Bjarne, 1999] devido a um acidente hist orico, os operadores = (atribui ca o), & (endere co) e seq uenciamento () t em signicados predenidos quando aplicados a objetos de classes. Voc e pode impedir o acesso a estes (e qualquer outro operador), declarando-os como private. 2 Operadores n ao podem ser denidos para receber exclusivamente ponteiros, exceto (=, &). 2 O primeiro argumento de um operador sobrecarregado deve ser um lvalue. 2 A sobrecarga como m etodo membro n ao e poss vel com m etodos est aticos (static), porque estes n ao recebem implicitamente o ponteiro this. 2 Uma sobrecarga e uma chamada de fun ca o; assim, os par ametros podem denir o namespace a ser utilizado. 2 Para que uma sobrecarga se torne mais r apida, declare-a como inline.

21.10

Resumo do cap tulo

C++ e uma linguagem de programa ca o sensacional! Com ela, voc e pode sobrecarregar os operadores (+, -, *, /, = etc.) de forma que o exemplo do polin omio possa ser utilizado, ou seja, com C++ podemos utilizar uma nota ca o muito mais clara e pr oxima da matem atica. Anal de contas, o c odigo pol_c = pol_a + pol_b; e muito mais claro que Somar ( pol_a, pol_b, &pol_c ); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

21.11. EXERC ICIOS

401

Observe que C++ e a programa ca o orientada a objeto aproximam muito os conceitos computacionais dos conceitos f sicos e matem aticos, o que facilita o entendimento e o desenvolvimento de programas para as areas de exatas e engenharia. Vimos que temos operadores un arios e bin arios, e que nem todos os operadores podem ser sobrecarregados. Aprendemos que podemos implementar a sobrecarga de operador utilizando m etodos membro da classe ou fun co es friend. Apresentamos um exemplo a classe . No nal do cap tulo vimos as diferentes formas de sobrecarga para new.

21.11

Exerc cios

1. Diga com suas palavras as vantagens do uso de sobrecarga de operador. Destaque aspectos relacionados ` as areas cient cas como matem atica, estat stica e m etodos num ericos. 2. Implemente exemplo com sobrecarga para operador + como operador un ario e bin ario. 3. Documente a classe CPonto das listagens 21.1 e 21.2. 4. Implemente uma classe CPolinomio com sobrecarga para os operadores +, -, =, ==. Use fun co es friend. 5. Implemente uma classe CMatriz com sobrecarga para os operadores +, -, *, / e []. Use m etodos membro. 6. Explique o c odigo que segue (consulte a Se ca o G.3 Enumera co es). Em seguida, implemente o c odigo para o operator- -. Os estados de um processo s ao discutidos na Se ca o ?? e apresentados na Figura ??. Exemplo: enum EEstado {idle, ready, standby, running, blocked, suspended, zoombied, stopped}; EEstado& operator++(EEstado& e) { if ( e != stopped) e++; else e = idle; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

402

21.11. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 22

Entrada e Sa da
Veremos neste cap tulo a hierarquia de classes fornecidas pelo C++ para entrada e sa da de dados, bem como denir a localidade a ser utilizada e formatar a sa da e a entrada de dados. Iniciamos com uma introdu ca o ` a entrada e sa da de dados (Se ca o 22.1). Em seguida, apresentamos a biblioteca-padr ao para entrada e sa da de dados (Se ca o 22.2): a classe ios_base (Se ca o 22.3), a classe <iomanip> (Se ca o 22.4), a classe <ostream> (Se ca o 22.5), a classe <ios> (Se ca o 22.6), a classe <istream> (Se ca o 22.7) e a classe <sstream> (Se ca o 22.8). Veremos ainda conceitos avan cados (Se ca o 22.9) como a classe locale (Se ca o 22.9.2) e o uso de facets (Se ca o 22.9.3). Por m, veremos algumas senten cas para stream (Se ca o 22.10). Nota: um guia de refer encia ` as classes e aos m etodos de entrada e sa da est a dispon vel em http://www.cplusplus.com/reference/.

22.1

Introdu c ao ` a entrada e sa da de dados com C++

Nos cap tulos anteriores e nos exemplos apresentados, aprendemos a utilizar os objetos cin e cout para entrada e sa da de dados. Exemplo: using namespace std; int x; // Cria objeto do tipo int com nome x // Enviar para tela o conjunto de caracteres cout < < "Entre com o valor de x:"; cin > > x; // Pega o n umero digitado e armazena em x cin.get(); // Pega o enter // Enviar para tela o valor de x cout < < "Valor de x= " < < x < < endl; Neste exemplo, usamos os objetos cout e cin, que s ao stream s. Uma stream encapsula o conceito de uxo de caracteres. De maneira geral, um objeto A do tipo stream insere (< <) ou extrai (> >) uma seq u encia de caracteres em um objeto B. Normalmente as streams est ao associadas a dispositivos f sicos. O objeto cout, por exemplo, j a vem previamente conectado com o dispositivo monitor, e o objeto cin j a vem previamente conectado com o dispositivo teclado. Diversos dispositivos do seu computador funcionam utilizando streams. Veja os exemplos: 403

404

22.2. BIBLIOTECA DE ENTRADA E SA IDA

O teclado de seu computador tem um buer onde s ao armazenados os caracteres digitados. Esses caracteres s ao extra dos do buer do teclado pelo objeto cin. As sa das auxiliares (com1, com2, com3, com4) utilizam e funcionam com streams de caracteres. O modem, as impressoras seriais, entre outros dispositivos, tamb em utilizam e funcionam com streams de caracteres. Programas podem comunicar-se utilizando stream s. No Cap tulo ?? Introdu ca o ao Processamento Paralelo com M ultiplos Processos, utilizaremos streams para trocar dados entre processos, isto e, entre dois ou mais programas. Pois bem, este cap tulo apresenta uma hierarquia de classes oferecidas pela biblioteca-padr ao de C++ para manipula ca o de stream s (entrada e sa da de dados).

22.1.1

Streams buferizadas

Vimos que uma stream tem um buer de mem oria utilizado para armazenar caracteres (Figura 8.2). Quando o buer enche, os caracteres s ao enviados para o dispositivo de destino. A linha cout < < "Entre com o valor de x: "; insere os caracteres "Entre com o valor de x: " no buer de cout (os caracteres seguem o uxo denido pelas setas < <). Observe que os caracteres ainda n ao foram enviados para a tela. Quando voc e usa cin > > x;, o objeto cin envia para o objeto cout um comando flush(), o qual descarrega o buer de cout, enviando todos os caracteres para o dispositivo de sa da, no caso o monitor. Em resumo, o buer de cout armazena temporariamente os caracteres enviados para a tela com cout< <. Quando o objeto cout recebe um comando flush(), ou quando o buer enche, todo conte udo do buer e enviado para a tela, e o buer e esvaziado. Note que a vantagem do uso de um buer e que as opera co es de sa da s ao executadas mais rapidamente.

22.2

Biblioteca de entrada e sa da

A Figura 22.1 ilustra a hierarquia de classes para entrada e sa da de dados com C++. De modo geral, um objeto dessa hierarquia pode armazenar, receber e fornecer caracteres. Um objeto da hierarquia de entrada e sa da e uma stream, a qual cont em um buer onde cam armazenados os caracteres e um conjunto de atributos utilizados na formata ca o desses caracteres. Note que a grande vantagem desta biblioteca e sua facilidade de uso. Por exemplo: o envio de dados para tela e para dispositivos externos (como disco, sa da auxiliar, outros programas) funciona exatamente da mesma forma. Outra grande vantagem e sua portabilidade, isto e, o programa vai funcionar em praticamente todas as plataformas de interesse. Outro exemplo e o uso da classe <locale>, utilizada para denir a localidade (pais de interesse). Com locale podemos denir que o programa funciona usando portugu es do Brasil ou o tradicional padr ao de C. A classe ios_base cont em um conjunto de m etodos b asicos que s ao herdados pelas demais etodo setf() e um conjunto de atributos (status, classes da hierarquia. Essa classe tem o m ags e informa co es de formata ca o) que podem ser utilizados para deni ca o do formato de Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

22.3. A CLASSE IOS_BASE

405

entrada/sa da de dados. Observe que a classe ios_base e independe do tipo de caractere (n ao e uma classe template). A classe <ios> e herdeira de ios_base. Os m etodos good(), bad(), fail() fornecem o estado da stream. Observe que <ios> depende do tipo de locale selecionado. A classe <istream> e utilizada para entrada de dados. C++ fornece o objeto cin do tipo <istream> para leitura de dados do teclado. A classe <ostream> e utilizada para sa da de dados. C++ fornece o objeto cout do tipo <ostream>, o qual e utilizado para enviar caracteres para a tela. A classe <iostream> pode ser utilizada para entrada e sa da de dados. A classe <iomanip> cont em um conjunto de manipuladores que podem ser utilizados para formata ca o da sa da de dados. Como j a visto as classes derivadas de <ios> t em objetivos predenidos. A classe <streambuf> e utilizada nos casos em que a formata ca o n ao precisa ser previamente denida. A classe <sstream> e uma mistura da classe <iostream> com a classe <string>, funcionando ora como uma <string>, ora como uma <iostream>. Em alguns casos, desejamos enviar e receber dados para um dispositivo externo, como um arquivo de disco; nestes casos, utilizamos a classe <fstream> e as classes <ofstream> e <ifstream>. A classe <string> e apresentada no Cap tulo 24 Classe <string>. A hierarquia de classes ilustrada na Figura 22.1 foi desenvolvida utilizando o conceito de templates (gabaritos). Isto signica que esta foi implementada para tipos gen ericos de caracteres. Na pr atica, as classes s ao constru das para dois tipos de caracteres: o char, j a utilizado no C, e o wchar_t. O char suporta 256 caracteres e o wchar_t, cerca de 16.000 caracteres. O wchar_t foi desenvolvido para dar suporte a diversas linguagens (ingl es, portugu es etc.). Veremos os templates no Cap tulo 27 Templates (ou Gabaritos). Vamos iniciar a descri ca o da biblioteca de entrada e sa da de dados, descrevendo a classe ios_base. Nota: veremos o acesso a arquivos de disco no Cap tulo 23 Entrada e Sa da com Arquivos de Disco.

22.3

A classe ios_base

A classe ios_base cont em atributos com informa co es de formata ca o da stream. Observe no diagrama de classes da Figura 22.1 que ios_base n ao considera informa co es do locale. Veremos a seguir os m etodos de ios_base. Na descri ca o de cada m etodo colocamos, em negrito, na primeira linha, a declara ca o do m etodo e abaixo, uma breve descri ca o. M etodos de ios base fmtags setf(fmtags fmt); O m etodo setf() e um dos principais m etodos da classe ios_base, sendo utilizado com o objetivo de denir a formata ca o de sa da. Veja na Tabela 22.1 os ags que podem ser utilizados para alterar os atributos da stream por meio do m etodo setf(). Lembre-se de que diferentes ags podem ser combinados com o operador |, como em setf(ios::scientific | ios::right). O m etodo setf() retorna os ags anteriores. void unsetf(fmtags mask); Desativa formata ca o de sa da. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

406

22.3. A CLASSE IOS_BASE

Figura 22.1: Diagrama UML da biblioteca de manipula ca o de entrada e sa da.


ios_base
+flags() +setf() +unsetf() +rdstate() +width() +precision() +imbue() +getloc()

<ios>
+bad() +clear() +eof() +fail() +good() +rdstate() +setstate() +fill() +rdbuf()

locale
+locale() +name() +global() +classic()

<iomanip>
+boolalpha() +noboolalpha() +showbase() +noshowbase() +showpoint() +noshowpoint() +showpos() +noshowpos() +skipws() +noskipws() +uppercase() +nouppercase() +left() +right() +dec() +hex() +oct() +fixed() +scientific() +endl() +ends() +flush() +ws() +setbase() +setfill() +setprecision() +setw() +unitbuf() +nounitbuf() +setiosflags() +resetiosflags()

<string>
+getline()

<sstream> <istream>
+gcount() +get() +getline() +ignore() +read() +tellg() +seekg() +putback() +unget() +peek() +sync() +operator>>()

<ostream>
+tellp() +seekp() +put() +write() +operator<<() +flush()

+str()

<streambuf>

<iostream>

<ofstream>
+is_open() +open() +close()

<ifstream>
+is_open() +open() +close()

<stringstream> <istringstream>

<ostringstream> <fstream>

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

22.3. A CLASSE IOS_BASE int rdstate(); Retorna o estado atual da stream.

407

streamsize width(streamsize n); O m etodo width() dene a largura m nima do campo; isto signica que, se a largura e6 e o n umero enviado para a tela tem 9 d gitos de precis ao, ser ao mostrados os 9 d gitos. Isto e v alido apenas para a pr oxima sa da. streamsize width(); Retorna a largura do campo. streamsize precision(streamsize n); Dene a precis ao da sa da; o valor default e 6 caracteres. Retorna o valor da precis ao anterior. locale imbue(const locale& loc); Seta nova localidade, retorna localidade anterior (veja listagem 22.7). locale getloc(); Retorna a localidade. fmtags ags(); Retorna os ags atuais. fmtags ags(fmtags ags); Seta os ags, retorna ags anteriores.

Tabela 22.1: Flags para o m etodo setf(). Flags de ios base ios::skipws ios::left ios::right ios::internal ios::shombase ios::showpoint ios::uppercase ios::showpos ios::scientific ios::fixed ios::unitbuf ios::stdio ios::dec ios::oct ios::hex ios::boolalpha Signicado Ignora espa cos em branco (somente entrada). Alinhamento ` a esquerda. Alinhamento ` a direita. Caractere de preenchimento entre o sinal +/- e o n umero (nointernal). Mostra indicador de base, 0x para hexadecimal (s o sa da). Mostra ponto decimal (utuante) zeros n ao signicativos no nal. Mai uscula para sa da de valores hexadecimais (nouppercase). Mostra sinal positivo (+) se maior que 0 (noshowpos). Usa nota ca o cient ca. Usa nota ca o xa. Descarrega stream ap os inser ca o. Descarrega stdout e stderr ap os inser ca o. Base 10, decimal. Base 8, octal. Base 16, hexadecimal. Exibe true/false no lugar de 1 e 0.

Veja a seguir um exemplo de uso da classe ios::base. Lembre-se de que cout e um objeto do tipo ostream, herdeiro da classe ios_base, logo cout pode acessar o m etodo setf() diretamente. Observe a forma como os ags da Tabela 22.1 s ao passados para o m etodo setf(). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

408 Exemplo: #include<iostream> using namespace std; int main() { float x = 5.1234567890; // Armazena flags atuais ios::fmtflags flags = cout.flags();

22.3. A CLASSE IOS_BASE

// Muda flags, usa formato cient fico e alinhamento ` a esquerda cout.setf(ios::scientific); // Ativa nota c~ ao cient fica cout.setf(ios::left); // Ativa alinhamento ` a esquerda // cout.setf(ios::scientific | ios::left); // Alternativa cout < < "Valor de x = " < < x < < endl; cout.flags(flags); // Retorna para flags anteriores cout < < "Valor de x = " < < x < < endl; return 0; } Veja no exemplo da listagem 22.1 o uso de sa da formatada. As opera co es de sa da para tela podem ser realizadas com o objeto cout e o operador de inser ca o (< <). O exemplo mostra sa da com e sem showpoint e, em seguida, dene a largura do campo em 5 caracteres e imprime o valor de i. Veja na sa da que o n umero 1 e impresso a partir da coluna 4. Posteriormente, entra em um la co for onde dene a precis ao de sa da e imprime o contador i num campo com largura 2, e, ent ao, o valor de d. Observe que d e truncado e n ao arredondado. No nal, dene o caractere de preenchimento como sendo * e imprime i. Nota: note que dentro de main() criamos um inteiro i e dentro do for um novo inteiro i e que mudan cas no i do for n ao alteraram o valor de i de main(), isto ocorre porque os mesmos est ao em escopos diferentes. Veja Se ca o B.4. Listing 22.1: Formata ca o b asica da sa da de dados.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # include < iostream > # include < string > using namespace std ; int main () { int i = 5; double d = 1.23456789 ; string nome = " Clube Palestra It a lia - Palmeiras " ; char letra = c ; char cstring [] = " STRING_DE _C " ; cout << << << << << " \n - - - - - - - - - - - - - - - - - Formato padr~ ao - - - - - - - - - - - - - - - - " " \ nint_i double_d string_nom e char_c char * _cstring " " \n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\ n " i << " " << d << " " << nome << << letra << " " cstring << endl ;

cout << " Alinhamen t o a esquerda " << endl ; cout . setf ( ios :: left ) ; cout . width (10) ; cout << i << " " ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

22.3. A CLASSE IOS_BASE


23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

409

cout << " \ n A l i n h a m e n t o a direita " << endl ; cout . setf ( ios :: right ) ; cout . width (10) ; cout << i << endl ; cout << " Formato cient fico " << endl ; cout . setf ( ios :: scientific ) ; cout << d << endl ; cout << " Mostra sinal positivo " << endl ; cout . setf ( ios :: showpos ) ; cout << d << endl ; cout << " Seta precis~ a o num e rica em 12 " << endl ; cout . precision (12) ; cout << d << endl ; cout << " Seta espa c o do campo em 20 caracteres " << endl ; cout . width (20) ; cout << i << endl ; cout << " Seta o caractere de p r e e n c h i m e n t o # " << endl ; cout . width (20) ; cout . fill ( # ) ; cout << i << endl ; cout << " Escreve na tela 5 caracteres da cstring " << endl ; cout . write ( cstring , 5) ; cout << endl ; cout << " Imprime a letra G na tela " << endl ; cout . put ( G ) ; cout << endl ; cout << " Imprime a letra " << ends << letra << endl ; cout << " Imprime c o digo ascii da letra \ n " << static_cast < int >( letra ) << endl ; cout << " Imprime o n u mero 12 em hexadecim al \ n " << hex << 12 << endl ; cout << " Parenteses evita ambig u idade , imprime \"9\"\ n " << (5 + 4) << endl ; cout << " Imprime string de C \ n " << cstring << endl ; cout . flush () ; // U t i l i z a d o para d e s c a r r e g a r o buffer

cout << " Usando boolalpha : 1 = " << boolalpha << ( bool ) 1 << " \ nUsando noboolalp h a : 1 = " << noboolalph a << ( bool ) 1 << endl ; return 0; } - - - - - - - - - - - - - - - - - Formato padr~ ao - - - - - - - - - - - - - - - int_i double_d string_nom e char_c char * _cstring ----------------------------------------------5 1.23457 Clube Palestra It a lia - Palmeiras c STRING_DE _ C Alinhamen to a esquerda 5 Alinhamen to a direita

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

410
5 Formato cient fico 1.234568 e +00 Mostra sinal positivo +1.234568 e +00 Seta precis~ a o num e rica em 12 + 1 . 2 3 4 5 6 7 8 9 0 0 0 0 e +00 Seta espa c o do campo em 20 caracteres +5 Seta o caractere de p r e e n c h i m e n t o # ##################+5 Escreve na tela 5 caractere s da cstring STRIN Imprime a letra G na tela G Imprime a letrac Imprime c o digo ascii da letra +99 Imprime o n u mero 12 em hexadecim al c Parentese s evita ambig u idade , imprime "9" 9 Imprime string de C STRING_D E_ C Usando boolalpha : 1 = true Usando noboolalp ha : 1 = 1

22.3. A CLASSE IOS_BASE

Veja exemplo na listagem 22.2. Observe que o valor na sa da de cout e arredondado e n ao truncado e que utilizamos endl para incluir uma linha nova e descarregar o buer (cout < < endl;). O manipulador flush descarrega o buer (cout.flush();). Listing 22.2: Formata ca o da sa da de dados usando o m etodo setf().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # include < iostream > using namespace std ; int main () { int i = 16; double d = 1 . 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ; char c = c ; cout << " --> Mostrando n u meros em ponto flutuante " << endl ; cout . unsetf ( ios :: showpoint ) ; cout << " Sem shownpoin t 3.33000= " << 3.33000 << endl ; cout . setf ( ios :: showpoint ) ; cout << " Com shownpoin t 3.33000= " << 3.33000 << endl ; cout << " --> Definindo a largura do campo " << endl ; cout . width (5) ; cout << i << endl ; cout << " --> Definindo a precis~ a o da sa da " << endl ; for ( int i = 1; i <= 5; i ++) { cout << " Precis~ ao = "; cout . width (2) ; cout << i ; cout . precision ( i ) ; cout << " d = " << d << endl ; } cout << " --> Definindo o caractere de p r e e n c h i m e n t o " << endl ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

22.4. A CLASSE <IOMANIP>


31 32 33 34 35 cout . fill ( * ) ; cout . width (10) ; cout << i << endl ; return 0; }

411

--> Mostrando n u meros em ponto flutuante Sem shownpoint 3 . 3 3 0 0 0 = 3 . 3 3 Com shownpoint 3 . 3 3 0 0 0 = 3 . 3 3 0 0 0 --> Definindo a largura do campo 16 --> Definindo a precis~ a o da sa da Precis~ a o = 1 d =1. Precis~ a o = 2 d =1.1 Precis~ a o = 3 d =1.12 Precis~ a o = 4 d =1.123 Precis~ a o = 5 d =1.1235 --> Definindo o caractere de p r e e n c h i m e n t o ********16

22.4

A classe <iomanip>

A <iomanip> e uma classe de manipuladores que permite a deni ca o de um conjunto de par ametros relacionados ` a formata ca o da sa da de dados. A Tabela 22.2 mostra alguns manipuladores de <iomanip>, se o mesmo e usado para entrada (E) e sa da (S) e seu signicado. Muitos dos manipuladores de <iomanip> s ao equivalentes a alguns ags do m etodo setf(). Observe que, na coluna de signicado, colocamos, dentro de [], o manipulador inverso. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

412

22.4. A CLASSE <IOMANIP>

Tabela 22.2: Manipuladores da classe <iomanip>. Manipulador showpos showpoint skipws upercase left/right fixed/scientific endl ends flush resetiosflags(long fl) setbase(int i) setfill(char) setiosflags(lonf fl) setprecision(int n) setw(int w) ws dec oct hex showbase boolalpha unitbuf E/S S S S S S S S S S E/S S E/S E/S E/S E/S S E/S E/S E/S S E/S S Signicado Mostra sinal positivo (+) [noshowpos]. Adiciona zeros [noshowpoint]. Ignora espa cos em branco [noskipws]. Letras mai usculas [nouppercase]. Alinhamento ` a esquerda/direita. Formato xo/cient co. Insere nova linha \n e libera stream [flush]. Envia caractere nulo \0. Esvazia o buer da stream. Dene os bits de ios indicados em long fl. Formata n umeros na base i. Dene o caractere de preenchimento. Dene os bits de ios indicados em long fl. Dene a precis ao float para n casas. Dene o tamanho de campos para w espa cos. Ignora caracteres em branco. Formata n umeros na base decimal (10). Formata n umeros na base octal (8). Formata n umeros na base hexadecimal (16). Se ativo mostra base. Se ativo, usar true/false no lugar de 1/0 [noboolalpha]. Esvazia o buer ap os cada opera ca o [nounitbuf].

No exemplo a seguir testamos o uso de showpoint, boolalpha e uppercase. Exemplo: #include<iostream> int main() { int x = 11; std::cout < < x < < std::endl; < < "Sa da em hexadecimal\n" < < hex < < x < < "\nSa da com showpoint\n" < < showpoint < < x < < "\nSa da com boolalpha e uppercase\n" < < boolalpha < < uppercase < < (bool)0 < < endl; return 0; } Veja no exemplo da listagem 22.3 o uso de sa da formatada usando os manipuladores da classe <iomanip>. Compare esse exemplo com a listagem 22.1. O exemplo inicia-se denindo a largura do campo com setw(). Em seguida, usa setprecision() para denir a precis ao de sa da e setfil() para denir o caractere de preenchimento. Listing 22.3: Formata ca o da sa da de dados usando a classe <iomanip>.
1 # include < iostream >

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

22.4. A CLASSE <IOMANIP>


2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # include < iomanip > using namespace std ; int main () { int i = 16; double d = 1 . 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ; char c = c ; cout << " --> Definindo a largura do campo \ n " << setw (5) << i << endl ; cout << " --> Definindo a precis~ a o da sa da " << endl ; for ( int cont = 1; cont <= 10; cont ++) cout << " Precis~ a o = " << setw (2) << cont << s e t p r e c i s i o n ( cont ) << " d = " << d << endl ; cout << " --> Definindo o caractere de p r e e n c h i m e n t o \ n " << setw (10) << setfill ( * ) << i << endl ; cout << " --> Definindo formato do n u mero " << " ( hexadecimal , octal e decimal ) " << " \ nhex 15 = " << hex << 15 << " \ noct 15 = " << oct << 15 << " \ ndec 15 = " << dec << 15 << " \ nbase 10= " << setbase (10) << 15 << endl ; return 0; }

413

--> Definindo 16 --> Definindo Precis~ ao = 1 Precis~ ao = 2 Precis~ ao = 3 Precis~ ao = 4 Precis~ ao = 5 Precis~ ao = 6 Precis~ ao = 7 Precis~ ao = 8 Precis~ ao = 9 Precis~ a o =10 --> Definindo ********16 --> Definindo hex 15 = f oct 15 =17 dec 15 =15 base 10=15

a largura do campo a precis~ a o da sa da d =1 d =1.2 d =1.23 d =1.235 d =1.2346 d =1.23457 d =1.234568 d =1.234567 9 d =1.2345678 9 d =1.2345678 9 o caractere de p r e e n c h i m e n t o formato do n u mero ( hexadecimal , octal e decimal )

Um bool tem como sa da os valores 0 ou 1. Para ter na sa da "false" ou "true", basta ativar este tipo de sa da utilizando o manipulador boolalpha:

Exemplo: cout < < boolalpha < < 0; // Sa da: true cout < < boolalpha < < 1; // Sa da: false Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

414

22.5. A CLASSE <OSTREAM>

22.5

A classe <ostream>

A classe <ostream> e utilizada para enviar caracteres para um dispositivo (sa da de dados). C++ cria automaticamente o objeto cout que pode ser utilizado para sa da na tela do computador. Observe que cout e uma abrevia ca o de C out. A formata ca o da sa da para a tela e realizada em dois passos. Primeiro, denem-se os atributos do objeto ostream (alinhamento, espa camento, formatos), e, em seguida, envia-se a stream para a sa da desejada. Veja as listagens 22.1, 22.2 e 22.3. Veja a seguir os m etodos da classe <ostream>. M etodos de <ostream> ostream& ush(); Descarrega o buer. Como dito anteriormente, uma stream tem um buer onde os caracteres cam armazenados. Quando o buer enche, os caracteres s ao descarregados, isto e, enviados para o seu destino. O m etodo flush() solicita o descarregamento imediato do buer. A classe <iomanip> fornece o manipulador flush. ostream& put(char ch); Insere o caractere ch na stream. long tellp(); Retorna a posi ca o do ponteiro de escrita put. Veja Se ca o 23.5.1. ostream & operator< <(ostream & ); Operador de inser ca o. ostream & write(const signed char* s, streamsize n); Envia para ostream a string s com at e n caracteres. N ao interpreta o conte udo de s. Veja na Tabela 22.3 os caracteres de escape, os quais, quando inseridos em uma stream, realizam uma determinada tarefa. Exemplo: cout < < "\a\a";

Caracter \a \b \f \n \r \t \v \0 \\ \ \"

Tabela 22.3: Caracteres de escape. Efeito. Toca o alarme (beep ). Retrocede uma coluna (retrocesso). Pr oxima linha, ou p agina (). Pr oxima linha, nova linha. Retorno de carro. Tabula ca o horizontal. Tabula ca o vertical. Caractere nulo, usado no m da string. Imprime \. Imprime . Imprime .

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

22.6. A CLASSE <IOS>

415

22.5.1

Senten cas para <ostream>

Veja no exemplo a seguir como e a sobrecarga de uma ostream. Exemplo: ostream& operator< < (ostream& out, const Tipo obj) { out < < obj.atributo; return out; } Observe que a sobrecarga de > > e < < e realizada com fun co es friend, n ao admitindo a utiliza ca o do polimorsmo (n ao s ao m etodos virtuais da classe). Voc e pode, por em, criar um m etodo virtual para entrada e sa da de dados. Exemplo: virtual void Entrada(istream &in); virtual void Saida(ostream &out);

22.6

A classe <ios>

A classe <ios> cont em informa co es de formata ca o da stream considerando as informa co es do locale, isto e, a classe <ios> leva em conta o locale selecionado (a classe locale e descrita na Se ca o 22.9.2). A seguir s ao descritos os m etodos de <ios> utilizados para vericar o estado da stream. M etodos de <ios> bool good(); Retorna um (== 1) se n ao tem erro, isto e, se est a tudo ok. N ao e eof(), n ao e fail(), n ao e bad(). Associado ao bit de estado goodbit. bool bad(); Verica se ocorreu um erro nas opera co es de entrada/sa da de dados. Se estiver bad(), os caracteres da stream est ao perdidos e voc e deve resetar a stream utilizando clear(). Retorna um valor diferente de 0 se ocorreu um erro (badbit == 1). Associado ao bit de estado badbit. bool fail(); Retorna um (== 1) se o estado da stream estiver incorreto. Se estiver fail(), indica que a pr oxima opera ca o ir a falhar. Uma falha pode ocorrer quando voc e realizou a leitura de caracteres incompat veis, ou quando o arquivo a ser aberto e inexistente. Associado ao bit de estado failbit. void clear( int b = 0 ); O m etodo clear() e utilizado para reestabelecer o estado da stream para o estado ok. O par ametro opcional b e usado para setar os bits. Desliga os bits de estado eofbit, failbit e badbit e liga o bit de estado goodbit. bool eof(); Retorna um valor diferente de zero se estamos no nal do arquivo. Observe que eof = end of le. Associado ao bit de estado eofbit. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

416 operator void!(); Diferente de zero (!= 0) se o estado do uxo falhou.

22.6. A CLASSE <IOS>

char ll(char ch); Dene o caractere de preenchimento (o default e o caractere de espa co, ). Se um campo tem largura denida para 10 caracteres, e a sa da s o ocupa 6, os 4 caracteres restantes s ao preenchidos com o caractere de preenchimento. char ll(); Retorna o caractere de preenchimento. void setstate(iostate b); Usado para setar o estado do bit b. No exemplo a seguir, seta o bit eofbit para verdadeiro, tamb em ativa o bit goodbit. Os demais ags de estado, failbit e goodbit, n ao s ao alterados. Veja exemplo na listagem 26.7. Exemplo: cin.setstate(ios::eofbit); operator!(); Retorna o estado da stream (o mesmo que fail()). ostream* tie(); const Retorna ponteiro para stream de sa da. ostream* tie(ostream* obj); Conecta a stream com uma stream de sa da (ex: cin.tie(cout);). iostate rdstate(); Retorna o estado da stream. iostate exceptions(iostate b); Liga o bit de estado que faz com que clear() dispare uma exce ca o. No exemplo a seguir a chamada a clear() ir a disparar uma exce ca o se o failbit estiver true. Veremos exce co es no Cap tulo 26 Exce co es. Exemplo: cin.exceptions(ios::failbit); streambuf* rdbuf(); Acesso ao buer da stream.

22.6.1

Senten cas para <ios>

Veja a seguir como usar m etodos de <ios> para saber o estado de cin. Para saber se est a no nal do arquivo. cin.eof(); Os caracteres foram lidos, mas o formato e incorreto. cin.fail(); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

22.7. A CLASSE <ISTREAM> Para saber se houve perda de dados. cin.badbit(); Para saber se tudo ocorreu corretamente. cin.good(); Para reinicializar os ags para o estado ok. cin.clear();

417

A classe <ios> inclui convers oes para bool. Assim, pode-se usar while(cin > > x) para ler os valores de x. Sempre que a entrada de x for correta, cin > > x retorna verdadeiro e continua o la co while. Quando o usu ario digitar um ctrl+d , invalidando a entrada de x, o la co while ser a encerrado.

22.7

A classe <istream>

A classe <istream> e uma classe para entrada de dados (istream = input stream ). Nos diversos exemplos apresentados, voc e aprendeu a utilizar o objeto cin do tipo <istream> para ler dados do teclado. Veremos a seguir alguns m etodos fornecidos pela classe <istream>. Na descri ca o do m etodo nos referimos ao objeto cin, mas o m etodo e v alido para qualquer <istream>. M etodos de <istream> int gcount(); Retorna o n umero de caracteres extra dos na u ltima opera ca o de leitura (v alido para get(), getline() e read()). istream& get(char* cstring, streamsize n, char end=*); e a digita ca o do asterisco=* (o * representa Obt em do teclado at e n caracteres, ou at aqui o caractere terminador; pode ser qualquer caractere), ou at e a digita ca o do retorno de carro(\n), o que ocorrer primeiro. O conjunto de caracteres lidos e armazenado em cstring. A fun ca o get() l e a stream at e o terminador, n ao o incluindo; para pegar o terminador, use um cin.get() adicional. No exemplo a seguir usamos o m etodo get() para ler do teclado at e 20 caracteres ou at e encontrar o ponto . e armazenar os dados lidos em nome. Exemplo: char nome[21]; cin.get(nome, 20, .); cin.get(); istream& get(char ch); Obt em um caractere do teclado e armazena em ch. Observe que se o usu ario digitou a letra A e em seguida pressionou Enter , a letra A e armazenada em ch, o enter digitado pelo usu ario continua no buer do teclado. Isto signica que voc e precisa de um cin.get() adicional para capturar o enter. Observe nos exemplos apresentados que, ap os uma leitura do teclado, utilizamos um cin.get() para capturar o enter. Veja que get() retorna uma refer encia para uma istream. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

418

22.7. A CLASSE <ISTREAM> Exemplo: char ch, novaLinha; cin.get(ch); // Captura um caractere e armazena em ch cin.get(novaLinha); // Captura o enter e armazena em novaLinha

int get(); Obt em um u nico caractere do teclado. Retira um caractere do teclado. Exemplo: cin.get(); istream& getline(signed char* cstring, int n, char=\n); O m etodo getline() e usado para armazenar uma linha inteira digitada no teclado em uma cstring (string de C). O m etodo getline() pega tamb em o retorno de carro. Observe que ele l e at e n-1 caracteres, visto que o u ltimo caractere e utilizado para armazenar o caractere terminador (\0). Exemplo: char nome[255]; cin.getline(nome); // string de C

istream& getline(istream cin, string nome, char end=\n); Armazena uma linha inteira digitada no teclado em uma string de C++ . Observe que voc e inclui a stream cin como par ametro (denida no arquivo de cabe calho <string>). Exemplo: string nome; getline(cin, nome); istream& ignore(streamsize n=1, int delim=EOF); Utilizada para ignorar at e n caracteres do uxo de entrada, ou seja, ela joga fora os pr oximos n caracteres. Por default ignora um caractere. Exemplo: cin.ignore(); // Ignora 1 caractere cin.ignore(2); // Ignora 2 caracteres istream& read(char *cstring, streamsize n); Utilizada para ler n caracteres sem interpretar o conte udo desses caracteres e armazenar em cstring. Desconsidera terminadores e n ao inclui o caractere de termina ca o. int readsome(char* cstring, stramsize n); Assemelha-se ao read(), mas retorna o n umero de caracteres lidos. long tellg(); Retorna a posi ca o atual do uxo (posi ca o do ponteiro get). Veja Se ca o 23.5.1. istream& putback(char ch); Devolve o caractere ch ao uxo de entrada. A pr oxima letra a ser lida ser a ch. Exemplo: char ch = k; cin.putback(ch); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

22.7. A CLASSE <ISTREAM> istream& unget(); Devolve para stream o u ltimo caractere lido. int peek(); Retorna o pr oximo caractere do uxo sem extra -lo da la. Equivale a get(ch); putback(ch);.

419

istream& operator > >(); Usada para armazenar uma entrada do teclado em uma vari avel. O operador > > l e at e o retorno de carro ou at e o primeiro espa co em branco (nova linha, tabulador, avan co de formul ario, retorno de carro). Exemplo: cin > > vari avel; cin > > x > > y > > z; cin > > oct > > numeroOctal; cin > > hex > > numeroHexadecimal; ostream* tie(ostream* os); Existe uma rela ca o entre cin e cout. Observe nas listagens apresentadas que cout n ao est a enviando um caractere de nova linha (\n), mas, ao executar o programa, a nova simples! O objeto cin envia para linha e inclu da. A pergunta e: como isto funciona? E cout uma nova linha. Voc e pode utilizar o m etodo tie() da classe <iostream> para criar uma associa ca o entre uma <istream> e uma <ostream> (da mesma forma como ocorre com cin e cout). Exemplo: istream is; ostream os; is.tie(os); Dica: veja exemplos de uso dos m etodos de <istream> nas listagens 9.4 e 9.8. No exemplo da listagem 22.4, mostramos como obter o n umero de linhas, palavras e caracteres digitados pelo usu ario. Listing 22.4: Contando n umero de linhas, palavras e caracteres.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // C o n t a n d o n u mero de linhas , p a l a v r a s e c a r a c t e r e s # include < cctype > # include < iomanip > # include < iostream > # include < string > using namespace std ; int main () { unsigned long nLinhas = 0; unsigned long nPalavras = 0 ; unsigned long nCaracter es = 0; string linhaAtual ; while ( getline ( cin , linhaAtual ) ) { ++ nLinhas ; nCaracter es += linhaAtual . size () + 1;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

420
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

22.7. A CLASSE <ISTREAM>

bool naPalavra = false ; for ( size_t i = 0; char c = linhaAtual [ i ]; ++ i ) if ( isspace ( static_cast < unsigned char >( c ) ) ) { if ( naPalavra ) ++ nPalavras ; naPalavra = false ; } else if (! naPalavra ) naPalavra = true ; if ( naPalavra ) ++ nPalavras ; } cout << \ n << left << nLinhas << \ n << left << nPalavras << \ n << left << nCaracteres < < return 0; } C ++ e mesmo uma linguagem de programa c a ~ o sensaciona l . O uso de streans e simples e i n c r i v e l m e n t e pr a tico . nLinhas : nPalavras : nCaracte re s : 3 17 107 setw (15) << " nLinhas : " setw (15) << " nPalavras : " << right << setw (15) << << right << setw (15) <<

setw (15) << " nCaracter es : " << right << setw (15) << endl ;

No exemplo da listagem 22.5, mostramos como controlar a entrada de dados. Listing 22.5: Controle de entrada.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 // E x e m p l o com c o n t r o l e de e n t r a d a . # include < iostream > # include < fstream > # include < string > # include < sstream > using namespace std ; int main () { int numero , soma = 0; cout << " Digite valores inteiros ( ctrl + d para encerrar entrada ) : " ; while ( true ) { cin >> numero ; // Se a e n t r a d a foi ok if ( cin . good () ) soma += numero ; // Se chegou o fim do a r q u i v o ( ctrl + d no GNU / Linux , ctrl + z no w i n d o w s) else if ( cin . eof () ) break ; // Se o c o r r e u um erro na e n t r a d a do n u mero else { cin . clear () ; string entrada ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

22.7. A CLASSE <ISTREAM>


29 30 31 32 33 34 35 cin >> entrada ; cerr << " Entrada errada , voc^ e digitou : " << entrada << endl ; } cout << " Soma = " << soma << endl ; } return 0; } Digite valores inteiros ( ctrl + d para encerrar entrada ) :1 2 3 4 Soma = 1 Soma = 3 Soma = 6 Soma = 10 [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ a . out Digite valores inteiros ( ctrl + d para encerrar entrada ) :1 2 ee 3 4 r 5 Soma = 1 Soma = 3 Entrada errada , voc^ e digitou : ee Soma = 3 Soma = 6 Soma = 10 Entrada errada , voc^ e digitou : r Soma = 10 Soma = 15

421

22.7.1

Senten cas para <istream>

A classe <istream> e uma especializa ca o do gabarito <basic_istream> para caracteres do tipo char. Para caracteres do tipo wchar_t, utilize a <wistream>. O caractere utilizado para encerrar uma entrada de dados e diferente nas plataformas DOS/Windows e Unix, GNU/Linux, MacOS X. Exemplo: // No DOS, um ctrl+z encerra o la co a seguir // No Unix, Mac OS X, GNU/Linux, um ctrl+d encerra o la co a seguir int var; do { cout < < "Entre com um n umero:"; } while( cin > > var ); Exemplo: // L^ e os caracteres do teclado usando cin // e joga para tela at e que ctrl+d // (no GNU/Linux) ou ctrl +z (no Windows) seja digitado. char ch; while(cin.get(ch)) cout.put(ch); O operador > >, ao ler uma stream (do teclado, do disco ou de outros dispositivos de entrada) desconsidera espa cos em branco , nova linha \n, avan co de formul ario \f e retorno de carro (enter). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

422

22.8. A CLASSE <SSTREAM>

A fun ca o isspace() denida em <cctype> informa se o caractere e um espa co. A leitura para uma string do C [char*] automaticamente inclui o caractere de termina ca o (\0). Veja no exemplo a seguir como sobrecarregar uma istream. Exemplo: istream& operator> > (istream& in, Tipo obj) { in > > obj.atributo; return in; }

22.8

A classe <sstream>

O arquivo de cabe calho <sstream> inclui as classes ostringstream, istringstream, stringstream e stringbuf. Estas representam um misto de uma classe string e uma classe stream, funcionando ora como uma string, ora como uma stream. Veja a seguir os m etodos de <sstream>. M etodos de <sstream> string str(); Retorna a string corrente. void str(string); Seta a string. stringbuf type* rdbuf() const; Oculta deni ca o da classe-base, isto e, oculta ios::rdbuf(). Retorna buer corrente. operator< <(); Operador de inser ca o (< <). operator> >(); Operador de extra ca o (> >). As classes ostringstream (output string stream ) e istringstream (input string stream ) podem ser utilizadas para substituir com vantagens as fun co es printf() e scanf() de C. A classe stringstream pode ser usada para leitura e escrita. O exemplo da listagem 22.6 mostra como formatar uma string utilizando os m etodos de ostringstream e istringstream. Preste aten ca o neste exemplo: primeiro criamos um objeto os, utilizado para armazenar os caracteres das strings s1, s2 e os n umeros d e i, funcionando como uma stream (como cout). Em seguida, o objeto os e utilizado para mostrar a string na tela com os.str(), ou seja, os.str() retorna uma string. Voc e pode usar um objeto os para formatar uma sa da de dados em uma string. Observe que a fun ca o setf(), os manipuladores de <iomanip> e os ponteiros de posicionamento de leitura e escrita (veja Se ca o 23.5.1) podem ser utilizados. No nal do exemplo, criamos um objeto in, do tipo istringstream, que recebe como entrada a string formatada em os (os.str()), ou seja, o objeto in atua como uma string. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

22.9. ENTRADA E SA IDA USO AVANCADO

423

A seguir, in e utilizado para enviar os caracteres para as strings s3, s4 e os n umeros d2 e i2, atuando como uma stream (como cin). Observe que, com um objeto do tipo ostringstream, pode-se substituir com vantagens a antiga fun ca o sprintf() de C, e, com um objeto istringstream, a antiga scanf(). Listing 22.6: Usando sstream (ostringstream e istringstream).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 # include < iostream > # include < string > # include < sstream > using namespace std ; // s t r e a m s // string de C ++ // stream e string junto

int main () { string s1 ( " oi_tudo " ) , s2 ( " bem " ) ; double d = 1.2345; int i = 5;

// Cria o b j e t o s

// Objeto do tipo o s t r i n g s t r eam , f u n c i o n a ora como stream ora como string o s t r i n g s t r e a m os ; // Abaixo , o objeto " os " f u n c i o n a como uma stream , como cout os << s1 << " " << s2 << " " << d << " " << i ; // A seguir o objeto os f u n c i o n a como uma string , str () r e t o r n a a string cout << " os . str () = " << os . str () << endl ; // Cria objeto do tipo i s t r i n g s t r e a m com nome in , // aqui in f u n c i o n a como uma string i s t r i n g s t r e a m in ( os . str () ) ; // Cria s t r i n g s s3 e s4 e dados n u m e r i c o s d2 e i2 string s3 , s4 ; double d2 ; int i2 ; // Extrai os dados da stream in e a r m a z e n a em s3 , s4 , d2 , i2 // aqui in f u n c i o n a como uma stream , como cin in >> s3 >> s4 >> d2 >> i2 ; cout << " s3 = " << s3 << " \ n " << " s4 = " << s4 << " \ n " << " d2 = " << d2 << " \ n " << " i2 = " << i2 << endl ; return 0; } os . str () = oi_tudo s3 = oi_tudo s4 = bem d2 = 1.2345 i2 = 5 bem 1.2345 5

Nota: veremos outra forma de converter int em string na Se ca o ??.

22.9

Entrada e sa da uso avan cado

Veremos nesta se ca o alguns temas avan cados do uso de entrada e sa da.

22.9.1

Como criar e usar um manipulador

Voc e pode criar seus pr oprios manipuladores. Veja o prot otipo a seguir. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

424

22.9. ENTRADA E SA IDA USO AVANCADO

Prot otipo: istream & NomeManipulador(istream & is) { is > > vari avel; return is;} ostream & NomeManipulador(ostream & os) {return os < < Op co esDeFormata ca o....;} No exemplo a seguir criamos um manipulador que emite um beep. Exemplo: ostream& beep(ostream& os) { return os < < \a; } Utilizando o manipulador beep denido pelo usu ario: Exemplo: cout < < beep; Veja a seguir o exemplo de manipulador usado para ignorar uma linha inteira: Exemplo: inline istream& ignoreline(istream& in) { in.ignore( numeric.limits<long int>::max(), \n ); return in; }

22.9.2

A classe locale2

Com a classe locale voc e pode denir caracter sticas de formata ca o relacionadas a uma determinada localidade (pa s, regi ao). Como, por exemplo, a formata ca o de n umeros (ex.: 1.0 ou 1,0), o c odigo postal, datas, telefones etc. Veremos a seguir a classe locale: class std::locale { public: locale(const char*); locale(const locale&);

// Construtor // Construtor de c opia // Cria locale a partir de x e y locale(const locale& x, const locale& y); string name(); // Retorna o nome do locale // Recebe novo locale global e retorna antigo static locale global(const locale& ); const locale classic(); // Retorna locale cl assico }; Observe que um locale pode ser constru do a partir de uma cstring (const char *), de um outro locale ou de uma combina ca o de locales. Voc e pode obter o locale-padr ao chamando o construtor da classe locale sem par ametros, locale(), tamb em pode construir o locale do usu ario chamando locale("");. O m etodo global() e utilizado para denir uma nova localidade-padr ao e retornar a localidade antiga. O m etodo classic() retorna o locale cl assico (o mesmo que locale("C")). O m etodo name() retorna uma string com uma s erie de informa co es da localidade. eja Tabela 22.4. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

22.9. ENTRADA E SA IDA USO AVANCADO

425

Tabela 22.4: Informa co es fornecidas pelo m etodo locale.name(). Vari avel Descri ca o LC CTYPE Classica ca o e convers ao de caracteres. LC COLLATE Ordem como as strings devem ser copiadas. LC MESSAGES Como traduzir mensagens como yes/no. LC NUMERIC Como representar n umeros. LC MONETARY Como representar dados monet arios. LC TIME Congura ca o de data e tempo. Dica: no GNU/Linux Red Hat e Fedora, as informa co es do locale s ao armazenadas no arquivo /etc/syscong/i18n e iniciam-se com as letras LC . Observe na Figura 22.1 que cada stream ao ser criada tem um locale associado o localepadr ao. Voc e pode alterar o locale de uma stream chamando o m etodo imbue(). No exemplo da listagem 22.7, vamos criar uma classe TestandoLocale() com tr es m etodos. O m etodo Mostra() mostra as informa co es dos locales inicial, padr ao, POSIX e C. O m etodo Define() solicita e dene o locale a ser utilizado. O m etodo Testa() testa o locale selecionado. Observe na sa da do exemplo os valores da localidade do usu ario (lc_usuario). A seguir, denimos o novo locale como pt_BR;. Observe que digitamos uma v rgula para denir o separador decimal do novo valor de x (exemplo: 1235,678). O locale-padr ao de C exige que o separador decimal de valores num ericos seja digitado com ponto (exemplo: 1235.678). Ap os denido o novo locale, setamos as stream s cin e cout usando o m etodo imbue(). Nota: o locale do usu ario e denido pelo usu ario quando se instala o sistema operacional. O uso de exce co es, bloco try{} throw e catch ser a visto no Cap tulo 26 Exce co es. Listing 22.7: Usando a classe locale.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # include < iostream > # include < string > # include < iomanip > using namespace std ; // s t r e a m s // string de C ++ // F o r m a t a c~ a o de s t r e a m s

// / Cria classe para visualiza c~ a o , ajuste e teste do locale class C T e s t a n d o L o c a l e { public : void Mostra () ; void Define () ; void Testa () ; private : locale lc_usuario ; // O locale s e l e c i o n a d o pelo u s u ario public : // Construtor , seta a t r i b u t o s i n t e r n o s // define locale do u s u a r i o p a s s a n d o uma string vazia "". // O locale do u s u ario e d e f i n i d o em seu s i s t e m a o p e r a c i o n a l . C T e s t a n d o L o c a l e () { lc_usuario = locale ( " " ) ; } };

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

426
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

22.9. ENTRADA E SA IDA USO AVANCADO

// / Mostra a l g u m a s l o c a l i d a d e s p a d r ~ o e s como C , POSIX , a l o c a l i d a d e inicial , // / e a l o c a l i d a d e do u s u a r i o l c _ u s u a r i o . name () . void C T e s t a n d o L o c a l e :: Mostra () { cout << " \ n l o c a l i d a d e _ i n i c i a l = " << locale () . name () << " \ n l o c a l i d a d e _ p a d r a o _ C = " << locale ( " C " ) . name () << " \ n l o c a l i d a d e _ p a d r a o _ P O S I X = " << locale ( " POSIX " ) . name () << " \ n l o c a l i d a d e _ u s u a r i o = " << lc_usuario . name () << endl ; } void C T e s t a n d o L o c a l e :: Define () { string nomeLocale ; // S o l i c i t a nome da l o c a l i d a d e a ser u t i l i z a d a cout << " Entre com o novo locale ( ex : pt_BR , en_US , pt , fr , C ) : " ; getline ( cin , nomeLocale ) ; // Tenta d e f i n i r novo locale a partir da e n t r a d a do u s u ario try { // Define a l o c a l i d a d e do u s u ario lc_usuario = locale ( nomeLocale . c_str () ) ; // Define a l o c a l i d a d e global como sendo a do u s u ario locale :: global ( lc_usuario ) ; // Define a l o c a l i d a d e de cin e cout cout . imbue ( lc_usuario ); cin . imbue ( lc_usuario ); } catch ( ... ) { cerr << " \ n \ a \ aErro ao tentar definir novo locale , o locale - > " << nomeLocale << " deve ser inv a lido .\ n " ; } } void C T e s t a n d o L o c a l e :: Testa () { double x = 1.234; cout << " Entre com x ( ex : " << x << " ) : " ; cin >> x ; cin . get () ; cout << " x = " << s e t p r e c i s i o n (10) << x << endl ; } int main () { C T e s t a n d o L o c a l e localidad e ; localidade . Mostra () ;

// Cria objeto // Mostra alguns l o c a l e s

int continuar = 1 ; while ( continuar == 1) { localidade . Define () ; // S o l i c i t a e altera o locale localidade . Testa () ; // Testa o locale s e l e c i o n a d o cout << " \ n \ aTestar novo locale (1) ou sair (0) ?: " ; cin >> continuar ; cin . get () ; } return 0; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

22.9. ENTRADA E SA IDA USO AVANCADO


localidade_inicial = C localidade_padrao_C = C localidade_padrao_POSIX = C l o c a l i d a d e _ u s u a r i o = pt_BR Entre com o novo locale ( ex : pt_BR , en_US , pt , fr , C ) : C Entre com x ( ex :1.234) :1.2345 x =1.2345 Testar novo locale (1) ou sair (0) ?:1 Entre com o novo locale ( ex : pt_BR , en_US , pt , fr , C ) : pt_BR Entre com x ( ex :1 ,234) :1 ,23456 x =1 ,23456 Testar novo locale (1) ou sair (0) ?:0

427

22.9.3

Usando facets 2

Um locale pode ser adaptado a uma determinada localidade denindo-se facets (classes que especicam algumas propriedades das stream s). Para detalhes do funcionamento de um locale, consulte o livro de [Bjarne, 1999] (3a . edi ca o revisada em ingl es). Infelizmente, a edi ca o traduzida para o portugu es, a terceira, n ao contempla o ap endice sobre locale. Entretanto, o autor disponibilizou no seu site, o Appendix D: Locales, no endere cohttp://www.research. att.com/~bs/3rd_loc0.html. No exemplo da listagem 22.8, vamos mostrar o uso de facets. Tamb em mostraremos o uso de wstring e wcout. Listing 22.8: Usando facets.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // E x e m p l o de uso de facet # include < iostream > # include < fstream > # include < string > # include < sstream > # include < locale > using namespace std ; int main () { // Usando facets // A c h a n d o o s m b o l o usado com dolar locale us ( " en_US " ) ; wstring dolar = use_facet < moneypunct < wchar_t > > ( us ) . curr_symbo l () ; wcout << " S mbolo para dolar = " << dolar << endl ; // A c h a n d o o s m b o l o usado com real locale br ( " pt_BR " ) ; wstring real = use_facet < moneypunct < wchar_t > > ( br ) . curr_symb o l () ; wcout << " S mbolo para real = " << real << endl ; return 0; }

S mbolo para dolar = $ S mbolo para real = R$

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

428

22.10. SENTENCAS PARA STREAM

22.10

Senten cas para stream

Lembre-se de que, no uso de cin > > mensagem;, caracteres como espa co s ao desconsiderados. A inclus ao de #include <iostream> fornece, al em dos objetos cin e cout, os objetos cerr (mensagens de erro) e clog (mensagens de log) que tamb em s ao conectados ` a sa dapadr ao do sistema (o monitor). cout e clog s ao buferizadas; isto signica que os caracteres n ao s ao imediatamente enviados para a tela. Para enviar imediatamente ` a tela, inclua uma chamada ao m etodo flush(). Exemplo: cout.flush(); // ou cout < < flush; O objeto cerr n ao e buferizado; isto signica que ele envia os caracteres imediatamente para a tela. Assim como cin, cerr e conectada com o monitor e deve ser utilizada para enviar mensagens de erro para a tela. Nas suas classes inclua sobrecarga para os operadores de extra ca o > > e de inser ca o < <. Note que o usu ario de sua classe espera que os operadores < < e > > estejam sobrecarregados. Para ter certeza da sa da do operador de inser ca o (< <), utilize par enteses. Exemplo: cout < < (a+b); Ap os uma leitura com cin, utilize cin.get() para retirar o caractere de retorno (o enter ). Lembre-se de que o manipulador width() se aplica ` a sa da seguinte. Como dito, ios e v alido para char, e wios para wchar_t. As equival encias s ao: ios>wios, istream->wistream, ostream->wostream, iostream->wiostream, ofstream->wofstream, ifstream->wifstream, fstream->wfstream, streambuf->wstreambuf, e, nalmente, filebuf>wfilebuf. A classe <ios> dene um operador void*() que retorna NULL se o bit failbit e true, isto e, se ocorreu um erro na leitura [Lischner, 2003].

22.11

Resumo do cap tulo

Vimos neste cap tulo a hierarquia de classes fornecidas pelo C++ para entrada e sa da de dados. Aprendemos que a biblioteca-padr ao e bastante extensa e inclui diversas classes para entrada e sa da de dados, classes com e sem buer. Aprendemos que o uso de buer e importante pois os mesmos deixam o programa mais r apido. Vimos que podemos denir a formata ca o de entrada e sa da de dados usando o m etodo setf() ou usando manipuladores. Aprendemos a criar nossos pr oprios manipuladores. Vimos que a entrada de dados e feita com as classes <ios> e <istream>. Substitu mos o uso da obsoleta printf() e scanf() (de C) pelas classes ostringstream e istringstream. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

22.12. EXERC ICIOS

429

Finalmente, aprendemos a denir a localidade a ser utilizada, a usar a classe locale e os facets. A seguir, no Cap tulo 23 Entrada e Sa da com Arquivos de Disco, aprenderemos a acessar dispositivos de disco e veremos alguns conceitos como redirecionamento de entrada e sa da.

22.12

Exerc cios

1. Inclu mos a seguir dois exemplos de fun co es utilit arias que realizam a convers ao de n umeros double para string e vice-versa. Como exerc cio, monte fun co es equivalentes para int, float, long double. Em seguida, monte uma fun ca o template para realizar a mesma coisa para tipos gen ericos. // Fun c~ ao global utilit aria, convers~ ao double->string string doubleToString(double d) { ostringstream os; os < < d ; return os.str(); } // Fun c~ ao global utilit aria, convers~ ao string->double double stringToDouble(string s) { istringstream in( s ); double d; in > > d; if( in.fail() || !in.eof()) return 0.0; return d; } 2. Quais objetos est ao associados ` a sa da e entrada padr ao, ` a sa da de erro e de logs? Quais s ao buferizados? (falar o nome e para que serve). 3. Qual a diferen ca entre \n e ends? 4. Monte um exemplo que utilize putback() e unget(). 5. Pesquise na internet o uso de facets e, em seguida, modique a listagem 22.7, incluindo o uso de facets. 6. Monte um exemplo que inclua a deni ca o e o uso do manipulador beep. 7. Crie um par de manipuladores que fa cam a convers ao de d olar para real e de real para d olar. 8. Monte um exemplo em que o n umero de caracteres lidos seja mostrado na tela a cada opera ca o de leitura. 9. Na listagem 22.6, verique como ca a istringstream depois de usada. 10. Comente o funcionamento l ogico da listagem 22.4.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

430

22.12. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 23

Entrada e Sa da com Arquivos de Disco


No Cap tulo 22 - Entrada e Sa da com C++, aprendemos a utilizar as classes streams de C++. Neste cap tulo veremos uma introdu ca o ao acesso a arquivos de disco (se ca o 23.1). Como criar e usar objetos da classe <fstream> para acessar arquivos de disco (se ca o 23.2). Como armazenar e ler objetos inteiros em disco (se ca o 23.3). O uso de redirecionamento de entrada e sa da (se ca o 23.4). Na se ca o entrada e sa da com arquivos de disco - uso avan cado (se ca o 23.5), veremos: Como posicionar ponteiros de arquivos com seekg(), seekp(), tellg(), tellp() (se ca o 23.5.1), o acesso a dispositivos externos como a impressora e a sa da auxiliar (se ca o 23.5.2). A cria ca o e uso de arquivos de disco bin arios (se ca o 23.5.3) e como executar e enviar comandos para outros programas usando as classes de <pstream.h> (se ca o 23.5.4). Nota: neste cap tulo vamos descrever o uso das classes <ofstream>, <ifstream>, <fstream>, nos referindo ao acesso a arquivos de disco. Mas estas classes podem ser utilizadas para ler/escrever em outros dispositivos.

23.1

Introdu c ao ao acesso a disco

Reveja na Figura 22.1, a hierarquia de classes de entrada e sa da. Herdeira da classe <ostream>, a classe <ofstream> e utilizada para enviar caracteres para um dispositivo externo, como um arquivo de disco (ofstream = output le stream ). Herdeira da classe <istream>, a classe <ifstream> e utilizada para ler caracteres de um dispositivo, como um arquivo de disco (ifstream = input le stream ). Herdeira da classe <iostream>, a classe <fstream> e utilizada para leitura e escrita em arquivos de disco. Para usar o acesso a arquivos de disco, inclua o arquivo de cabe calho <fstream>: Exemplo: #include <fstream>

23.2

A classe <fstream>

Veremos a seguir alguns m etodos da classe <fstream>. 431

432 M etodos de <fstream>

23.2. A CLASSE <FSTREAM>

fstream(); Construtor default da classe, cria objeto sem associ a-lo a um arquivo de disco. fstream(const char* arq, int = modoDeAbertura, int = modoDeProte c ao); Construtor sobrecarregado, cria objeto e associa-o a um dispositivo, normalmente um arquivo de disco. Se voc e deseja abrir o arquivo sem eliminar o existente, inclua um ios::app para adicionar caracteres no m do arquivo. modoDeAbertura Especica como abrir o arquivo (veja Tabela 23.1). modoDeProte ca o Especica o formato de prote ca o do arquivo (veja Tabela 23.2). fstream(int); Construtor sobrecarregado, cria objeto e associa-o a arquivo identicando-o com um n umero int (n ao e coberto pelo padr ao Ansi C++, mas e disponibilizado em alguns sistemas). void open (const char *arq, int = modoDeAbertura, int = modoDeProte c ao); O m etodo open() e usado para abrir arquivos de disco. Por default, abre o arquivo eliminando o arquivo existente. Se voc e deseja abrir o arquivo sem eliminar o existente, inclua um ios::app para adicionar caracteres no m do arquivo. Exemplo: ofstream fout; fout.open("nomeDoArquivo.dat");

Tabela 23.1: Modos de abertura do m etodo open(). ios::app Acrescenta ao m do arquivo (modo append ) ios::ate Abre arquivo e vai para o m dele ios::in Abre o arquivo para entrada (leitura) ios::out Abre o arquivo para sa da (escrita) ios::nocreat N ao cria se o arquivo n ao existe (uma falha) ios::noreplace Se o arquivo j a existir, ocorre uma falha ios::binary Abre o arquivo em modo bin ario ios::trunc Elimina o arquivo se j a existir e recria (default )

Tabela 23.2: Modos de prote ca o do m etodo open() (atributos de arquivo). 0 Arquivo 1 Apenas leitura 2 Escondido 4 Sistema 8 Ativar o bit do arquivo (backup) Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

23.2. A CLASSE <FSTREAM>

433

istream & seekg(streamo deslocamento, seekdir manipulador); Quando uma istream abre um arquivo de disco, o ponteiro de leitura aponta para o in cio do arquivo. A medida que a istream e utilizada, o ponteiro de leitura e deslocado para o pr oximo dado a ser lido. O m etodo seekg() e utilizado para movimentar o ponteiro de leitura. Podemos mudar a posi ca o do ponteiro de leitura sem ter que realizar uma leitura (veja se ca o 23.5.1). ostream & seekp(streamo deslocamento, seekdir manipulador); Movimenta ponteiro de escrita (veja se ca o 23.5.1). Veja na Tabela 23.3 os manipuladores que podem ser passados para esses m etodos. Exemplo: // Movimenta ponteiro get fin.seekg(deslocamento,manipulador); // Movimenta ponteiro put fout.seekp(deslocamento,manipulador); // Obt em posi c~ ao do ponteiro get ios::pos_type pg = fin.tellg(); // Obt em posi c~ ao do ponteiro put ios::pos_type pp = fout.tellp(); bool is open(); Retorna verdadeiro se o arquivo esta aberto. void close(); Descarrega o buer e fecha o arquivo aberto; se j a fechado, ignora-o.

Tabela 23.3: Manipuladores seekdir para os m etodos seekp() e seekg(). ios::beg Vai para o in cio do arquivo ios::end Vai para o m do arquivo ios::cur Posi ca o corrente ios::fail Opera ca o E/S falhou (possivelmente o arquivo est a com problemas) ios::bad E/S inv alida (possivelmente o arquivo est a com problemas) Na listagem 23.1 apresentamos, al em da sa da, os arquivos gerados pelo programa (o comando cat do GNU/Linux mostra o conte udo de um arquivo). O programa inicia criando o objeto fout. A seguir abre o arquivo de disco "data.dat" e envia para o arquivo a mensagem "Isto vai para o arquivo de disco". Num segundo bloco, abrimos o arquivo de disco "data2.dat", usando o construtor de ofstream que recebe o nome do arquivo a ser aberto. No terceiro bloco, o arquivo "data.dat" e aberto, agora para leitura. O conte udo da primeira linha do arquivo e copiada para a string s. Dentro do for, utilizamos um objeto ostringistream para criar arquivos de disco com nomes: nomeDoArquivo-1.dat, nomeDoArquivo-2.dat, nomeDoArquivo-3.dat. Arquivos seq uenciais s ao muito u teis em programas de simula ca o cient ca. Como dito anteriormente, os.str(), retorna uma string de C++, j a c_str(), converte uma string de C++ em uma string de C (char *). Observe que o funcionamento dos objetos do tipo ofstream e ifstream, e muito semelhante ao uso de cout e cin. Em ambos os casos, o acesso a disco e nalizado quando fechamos a conex ao com o dispositivo de disco com close(). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

434

23.2. A CLASSE <FSTREAM> Listing 23.1: Uso de stream de disco (ifstream e ofstream).

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

# include < iostream > # include < fstream > # include < string > # include < sstream > using namespace std ; int main () { { // Cria o objeto do tipo o f s t r e a m ofstream fout ;

com nome fout

// A s s o c i a o objeto fout ao a r q u i v o de disco data . dat fout . open ( " data . dat " ) ; // Se a a b e r t u r a do a r q u i v o falhou , e n c e r r a o p r o g r a m a if ( fout . fail () ) { cout << " N~ a o abriu o arquivo de disco . " << endl ; return 1; } // Se o a r q u i v o abriu corretamente , insere c a r a c t e r e s no a r q u i v o . fout << " Isto vai para o arquivo data . dat \ n " ; // D e s c a r r e g a o buffer e fecha o a r q u i v o. fout . close () ; } { // P o d e m o s criar o objeto fout e associ a - lo a um a r q u i v o de disco ofstream fout ( " data2 . dat " ) ; fout << " Isto vai para o arquivo data2 . dat \ n " ; fout . close () ; // D e s c a r r e g a o buffer e fecha o a r q u i v o . } { // Um i f s t r e a m e um f s t r e a m com ios :: in , // a s s o c i a objeto de l e i t u r a fin ao a r q u i v o de disco data . dat ifstream fin ( " data . dat " ) ; string s ; getline ( fin , s ) ; // L^ e a string s do a r q u i v o de disco data . dat cout << " Conte u do do arquivo : " << s << endl ; fin . close () ; // Fecha o a r q u i v o } { for ( int i = 0; i < 3; i ++) { // Cria objeto do tipo o s t r i n g s t r e a m o s t r i n g s t r e a m os ; // os f u n c i o n a como uma ostream , e e u t i l i z a d a para criar // o nome do a r q u i v o de disco que ser a aberto a seguir os << " nomeDoArquivo - " << i << " . dat " ; // Abre a r q u i v o n o m e D o A r q u ivo -0. dat ,... ofstream fout ( os . str () . c_str () ) ; // A r m a z e n a dados no a r q u i v o aberto fout << " no arquivo de disco : " << os . str () << endl ; cout << " Escrevendo no arquivo de disco : " << os . str () << endl ; fout . close () ; // Fecha o a r q u i v o }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

23.2. A CLASSE <FSTREAM>


62 63 64 } return 0; } bash -3.00 $ ./ a . out Conte u do do arquivo : Isto Escrevendo no arquivo de Escrevendo no arquivo de Escrevendo no arquivo de

435

vai para o arquivo data . dat disco : nomeDoArquivo -0. dat disco : nomeDoArquivo -1. dat disco : nomeDoArquivo -2. dat

bash -3.00 $ cat data . dat Isto vai para o arquivo data . dat bash -3.00 $ cat data2 . dat Isto vai para o arquivo data2 . dat bash -3.00 $ no arquivo bash -3.00 $ no arquivo bash -3.00 $ no arquivo cat nomeDoArquivo -0. dat de disco : nomeDoArquivo -0. dat cat nomeDoArquivo -1. dat de disco : nomeDoArquivo -1. dat cat nomeDoArquivo -2. dat de disco : nomeDoArquivo -2. dat

O exemplo da listagem 23.2 mostra como ler um arquivo de disco com formata ca o simples. O programa abre o arquivo de disco "data3.dat" e armazena no arquivo 3 linhas. Na primeira linha um n umero inteiro seguido de coment ario. A seguir, repete o procedimento para um float e uma string. Depois o arquivo e fechado com close(). Na segunda etapa o programa, abre o arquivo de disco e cria as vari aveis que ser ao lidas do arquivo de disco. Na linha fin > > x; o objeto fin percorre o arquivo de disco desconsiderando espa cos em branco e retornos de carro. Quando encontra o primeiro caracter v alido, verica se o mesmo e um n umero inteiro e copia o mesmo para x. No caso copia o n umero 1452 para x. A linha fin.ignore(255,\n); e usada para ignorar o restante da linha. O mesmo procedimento e usado para ler y e s. Para ler a1, a2 e a3, usamos fin.ignore(255,#); ou seja, ignorar tudo at e encontrar o caracter separador, no caso #. Observe na sa da que os valores de x, y, s, a1, a2 e a3 est ao corretos. Listing 23.2: Lendo um arquivo com dados e coment arios.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # include < iostream > # include < fstream > # include < string > # include < sstream > using namespace std ; int main () { { // Cria a r q u i v o de disco e a r m a z e n a dados com c o m e n t arios ofstream fout ; fout . open ( " data3 . dat " ) ; // valor # c o m e n t arios fout << 1452 << " # representa bla .. bla .. bla ..1 " << endl ; fout << 0.123 << " # representa bla .. bla .. bla ..2 " << endl ; fout << " msg " << " # representa bla .. bla .. bla ..3 " << endl ; // valor # valor # valor # fout << 12 << " # " << 13 << " # " << 14 << " # " << endl ; fout . close () ; } { // L^ e os dados do a r q u i v o de disco ifstream fin ( " data3 . dat " ) ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

436
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 int x ; float y ; string s ; int a1 , a2 , a3 ; fin >> x ; fin . ignore (255 , \ n ) ; fin >> y ; fin . ignore (255 , \ n ) ;

23.3. ARMAZENANDO E LENDO OBJETOS

fin >> s ; fin . ignore (255 , \ n ) ; cout << " x = " << x << " y = " << y << " s = " << s << endl ; fin >> a1 ; fin . ignore (255 , # ) ; fin >> a2 ; fin . ignore (255 , # ) ; fin >> a3 ; fin . ignore (255 , # ) ; cout << " a1 = " << a1 << " a2 = " << a2 << " a3 = " << a3 << endl ; fin . close () ; } return 0; } x = 1452 y = 0.123 s = msg a1 = 12 a2 = 13 a3 = 14

23.3

Armazenando e lendo objetos

Com os m etodos read() e write(), podemos armazenar um objeto em disco e posteriormente l e-lo do disco, o que e muito u til para manipula ca o de dados (banco de dados). Reveja a seguir o prot otipo dos m etodos read() e write(). Prot otipo: istream & read(char *charbufer, streamsize n); ostream & write (const signed char *charbuer, int n); A listagem 23.3 mostra um exemplo. O programa inicia-se denindo uma classe CData. Observe a sobrecarga dos operadores de inser ca o e extra ca o. Dentro de main(), solicita o nome do arquivo de disco e o associa ` a stream fout. Ap os vericar se o arquivo de disco foi corretamente aberto, cria um vetor para armazenar objetos do tipo CData. A seguir, entra em um looping while, onde o usu ario entra com os dados de cada objeto (x e y). Envia o objeto para o arquivo de disco com fout < < obj; e mostra o objeto na tela, cout < < "Objeto=" < < obj;. No nal do do while(), adiciona o objeto no vetor com push_back(obj);. Fora do while(), fecha o arquivo de disco, fout.close(), e mostra todos os objetos do tipo CData que est ao armazenados no vetor d. Na segunda parte do programa, abre um objeto de leitura de arquivo de disco, ifstream fin, e verica se o arquivo foi corretamente aberto, if (!fin). Para mostrar que os dados que foram armazenados em disco ser ao corretamente lidos, cria-se um segundo vetor, com nome d2. Entra num novo while, onde l e todos os objetos armazenados em disco, mostra-os na tela e armazena no vetor d2. Finalmente mostra o vetor d2. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

23.3. ARMAZENANDO E LENDO OBJETOS Listing 23.3: Leitura e grava ca o de objetos simples usando read() e write().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 # include < string > # include < fstream > # include < vector > # include < iostream > using namespace std ; class CData { int x ; int y ; public : CData () : x (0) , friend istream friend ostream friend ifstream friend ofstream }; // D e c l a r a classe CData

437

y & & & &

(0) { }; operator operator operator operator

>> << >> <<

( istream & , CData &) ; ( ostream & , CData &) ; ( ifstream & , CData * &) ; ( ofstream & , CData * &) ;

// de in para CData , e x e m p l o: cin >> d ; istream & operator >> ( istream & in , CData & d ) { cout << " \ nx : " ; in >> d . x ; cout << " \ ny : " ; in >> d . y ; return in ; } // de CData para out , e x e m p l o : cout << d ; ostream & operator << ( ostream & out , CData & d ) { out << " ( x = " << d . x << " , y = " << d . y << " ) " << endl ; return out ; } // de in para CData , e x e m p l o: fin >> d ; ifstream & operator >> ( ifstream & in , CData * & d ) { in . read ( r e i n t e r p r e t _ c a s t < char * >( d ) , sizeof ( CData ) ) ; return in ; } // de CData para out , e x e m p l o : fout << d ; ofstream & operator << ( ofstream & out , CData * & d ) { out . write ( r e i n t e r p r e t _ c a s t < const char * >( d ) , sizeof ( CData ) ) ; return out ; } int main () { cout << " Nome do Arquivo : " ; // S o l i c i t a nome do a r q u i v o string nomeArqui vo ; getline ( cin , nomeArqui vo ) ; // Abre a r q u i v o de disco ofstream fout ( nomeArqui v o . c_str () ) ; if (! fout ) // V e r i f i c a se o a r q u i v o foi aberto { // ou use if ( fout . i s _ o p e n () ) cout << " \ n \ nErro na abertura de arquivo " ; exit (1) ; } vector < CData > d ; // Cria vetor para o b j e t o s do tipo CData

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

438
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 CData obj ; CData * pobj ; pobj = & obj ;

23.3. ARMAZENANDO E LENDO OBJETOS


// Cria objeto do tipo CData com nome obj // Cria p o n t e i r o para CData // A r m a z e n a e n d e r e c o do objeto no p o n t e i r o

cout << " Entre com os valores de x e y de cada objeto . " << " Para encerrar ctrl + d " << endl ; while ( cin >> obj ) // E n q u a n t o l e i t u r a for c o r r e t a { cin . get () ; fout << pobj ; // A r m a z e n a dados do objeto no a r q u i v o de disco cout << " Objeto = " << obj ; // Mostra dados do objeto lido na tela d . push_back ( obj ) ; // A r m a z e n a objeto no vetor }; cin . clear () ; // Reseta a stream , pronta para p r oxima leitura fout . close () ; // Fecha o a r q u i v o de disco cout << " \ nMostrand o objetos do vetor d \ a " << endl ; for ( int i = 0; i < d . size () ; i ++ ) cout << d [ i ] << endl ; // Mostra todos os o b j e t o s lidos cout << " Vai ler os objetos do disco " << endl ; ifstream fin ( nomeArquiv o . c_str () ) ; if (! fin ) { cout << " \ n \ nErro na Abertura de arquivo " ; exit (1) ; } vector < CData > d2 ; while ( fin >> pobj ) { d2 . push_back ( obj ) ; }; fin . close () ;

// d2 . p u s h _ b a c k (* pobj ) ; // Fecha a r q u i v o de disco

cout << " \ nMostrand o objetos do vetor d2 \ a " << endl ; for ( int i = 0; i < d2 . size () ; i ++) cout << d2 [ i ] << endl ; return 0; } Nome do Arquivo : Teste . txt Entre com os valores de x e y de cada objeto . Para encerrar ctrl + d x : 1 y : 2 Objeto =( x = 1 , y = 2) x : 3 y : 4 Objeto =( x = 3 , y = 4) x : 5 y : 6 Objeto =( x = 5 , y = 6) x : y : Mostrando objetos do vetor d ( x = 1 , y = 2) ( x = 3 , y = 4) ( x = 5 , y = 6) Vai ler os objetos do disco Mostrando objetos do vetor d2 ( x = 1 , y = 2) ( x = 3 , y = 4)

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

23.4. REDIRECIONAMENTO DE ENTRADA E SA IDA


(x = 5 , y = 6)

439

Observe que este mecanismo de armazenamento e leitura de arquivos em disco funciona corretamente. Mas se o objeto usar aloca ca o din amica para atributos internos, o conte udo do ponteiro e que ser a armazenado em disco. Voc e ter a de usar um outro mecanismo para gerenciar o armazenamento e a leitura de objetos com atributos din amicos.

23.4

Redirecionamento de entrada e sa da

Tanto na linha de comando do GNU/Linux como do Mac OS X e do Windows, voc e pode utilizar os mecanismos de redirecionamento de entrada e sa da de dados. Voc e j a usou o comando ls (ou dir ) para listar o conte udo de um diret orio. Exemplo (GNU/Linux): ls Exemplo (Windows): dir Entretanto, se a sa da do comando ls (ou dir ) for muito grande e n ao couber na tela, os primeiros diret orios e arquivos ir ao desaparecer. Neste caso, voc e pode usar um comando de redirecionamento como pipe (|), para enviar a sa da do comando ls (ou dir ) para um paginador como o less. No Windows, o equivalente de ls e dir e o equivalente do less e o more (ou type). O programa less e um paginador, pois permite que voc e navegue em um arquivo. Para sair do less digite a letra q. Veja no exemplo a seguir que pegamos a sa da do programa ls e a enviamos para o programa less. Exemplo (GNU/Linux): ls | less Exemplo (Windows): dir | more Quando voc e executa um programa a sa da-padr ao e a tela. Voc e pode redirecionar a sa da do programa para um arquivo de disco utilizando redirecionamento >. Veja o exemplo. Exemplo (GNU/Linux): ls > arquivo.dat cat arquivo.dat Exemplo (Windows): dir > arquivo.dat type arquivo.dat | more No exemplo anterior, voc e pegou a sa da do programa ls e a enviou para o arquivo arquivo.dat. O programa cat apenas mostrou o conte udo do arquivo arquivo.dat. Se o arquivo arquivo.dat for muito grande, utilize novamente o paginador less. Exemplo (GNU/Linux): cat arquivo.dat | less Exemplo (Windows): type arquivo.dat | more Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

440

23.4. REDIRECIONAMENTO DE ENTRADA E SA IDA

Voc e pode adicionar a sa da de um programa no nal de um arquivo utilizando o operador de concatena ca o (> >), ou seja, escrever a sa da de um programa em um arquivo de disco j a existente. Exemplo (GNU/Linux): ./Simulacao > resultado.dat ./Simulacao > > resultado.dat Exemplo (Windows): Simula c~ ao.exe > resultado.dat Simula c~ ao.exe > > resultado.dat Neste caso, primeiro, voc e cria o arquivo resultado.dat que armazenar a o resultado da primeira simula ca o realizada. Depois, executa novamente o programa ./Simulacao , adicionando os novos resultados no nal do arquivo resultado.dat. Outra possibilidade bastante interessante e criar um arquivo de disco com as entradas que ser ao solicitadas por determinado programa. Assim, em vez de esperar o usu ario digitar cada entrada, o programa l e as entradas diretamente do arquivo de disco. Veja exemplo a seguir. Exemplo (GNU/Linux): ./Simulacao < entrada.dat Exemplo (Windows): Simulacao.exe < entrada.dat Vamos utilizar o exemplo da listagem 23.4 para mostrar o uso dos mecanismos de redirecionamento. Observe que a listagem 23.4 solicita a entrada de 3 valores. O nome do arquivo, o n umero de repeti co es e a precis ao do solver. Depois, mostra os valores lidos. O programa pode ser compilado e executado normalmente. Para rodar este exemplo, voc e precisa de um arquivo de disco com o nome "teste.dat" com o seguinte conte udo: teste.dat 3 0.0001 Para rodar, basta digitar ./nomeDoPrograma < < arquivoComDados. Observe na sa da que executamos o programa sem redirecionamento e a seguir com redirecionamento. Listing 23.4: Usando redirecionamento de arquivo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include < iostream > # include < fstream > # include < string > using namespace std ; int main () { string n o m e A r q u i v o D i s c o ; cout << " Entre com o nome do arquivo de disco : " ; getline ( cin , n o m e A r q u i v o D i s c o ) ; cout << " Entre com o n u mero de repeti co ~ es : " ; int repeticoes = 0; cin >> repeticoes ; cin . get () ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

23.5. ENTRADA E SA IDA COM ARQUIVOS DE DISCO - USO AVANCADO


17 18 19 20 21 22 23 24 25 26 27 28 cout << " Entre com a precis~ a o do solver : " ; double precisao = 0.0001; cin >> precisao ; cin . get () ; cout << " VALORES I N T R O D U Z I D O S / LIDOS " << " \ nnome do arquivo de disco = " << n o m e A r q u i v o D i s c o << " \ nn u mero de repeti co ~ es = " << repeticoe s << " \ nprecisao = " << precisao << endl ; // Aqui e n t r a r i a a s i m u l a c~ a o em si .... return 0; } Executando o programa sem r e d i r e c i o n a m e n t o -----------------------------------------bash -3.00 $ ./ a . out Entre com o nome do arquivo de disco : teste . dat Entre com o n u mero de repeti co ~ es : 4 Entre com a precis~ a o do solver : 0.0005 VALORES I N T R O D U Z I D O S / LIDOS nome do arquivo de disco = teste . dat n u mero de repeti co ~ es = 4 precisao = 0.0005 Executando o programa com r e d i r e c i o n a m e n t o -----------------------------------------bash -3.00 $ ./ a . out < teste . dat Entre com o nome do arquivo de disco : Entre com o n u mero de repeti co ~ es : Entre com a precis~ a o do solver : VALORES I N T R O D U Z I D O S / LIDOS nome do arquivo de disco = teste . dat n u mero de repeti co ~ es = 3 precisao = 0.001

441

23.5

Entrada e Sa da com Arquivos de Disco - Uso Avancado

Veremos nesta se ca o conceitos avan cados de entrada e sa da em C++. O acesso a impressora e a sa da auxiliar. O uso de arquivos de disco bin arios e como executar programas externos e enviar comandos para eles.

23.5.1

Posicionando ponteiros de arquivos2

Quando estamos lendo informa co es de um arquivo do disco, estamos com o nosso objeto de leitura apontando para uma determinada posi ca o do arquivo. Os m etodos seekg() e seekp() s ao utilizados para posicionar o ponteiro de leitura (get ) e o de escrita (put ) em um determinado arquivo. Os m etodos tellg() e tellp() s ao utilizadas para obter a posi ca o dos ponteiros de leitura get() e escrita put(). Veja o uso de seekg(), read(), write() e arquivos bin arios na listagem 23.5. O programa inicia-se denindo uma classe CA, que tem os atributos x e y e um m etodo de entrada Input(). O m etodo ArmazenaObjeto() cria um objeto do tipo CA e abre um arquivo de disco. A seguir, entra num la co while() onde os dados de cada objeto s ao lidos e armazenados em disco. No nal do m etodo ArmazenaObjeto(), o arquivo de disco estar a com todos os objetos que foram lidos. O m etodo LeObjetos() solicita ao usu ario qual objeto deve ser lido. A seguir, abre o arquivo de disco e usa o m etodo seekg() para movimentar o ponteiro get e o posicionar no in cio do objeto a ser lido. A fun ca o read() l e o objeto do arquivo de disco. Finalmente o objeto Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

442

23.5. ENTRADA E SA IDA COM ARQUIVOS DE DISCO - USO AVANCADO

lido e mostrado na tela. Enm, neste exemplo, criamos uma base de dados, armazenando-a em disco com write() e usamos os m etodos seekg() e read() para ler o objeto selecionado. Observe que os objetos s ao armazenados e lidos no formato bin ario (ios::binary). Listing 23.5: Usando read(), write() e seekg().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 # include < iostream > # include < fstream > using namespace std ; class CA { public : int x ; int y ; CA () : x (0) , y (0) { }; bool Input () { cout << " Entre com x e y ( x espa co y ):" ; cin >> x ; cin . get () ; cin >> y ; cin . get () ; if ( cin . fail () ) { cin . clear () ; return 0; } return 1; } }; // A r m a z e n a o b j e t o s em disco void A r m a z e n a O b j e t o s () { cout << " sizeof ( CA ) = " << sizeof ( CA ) << endl ; CA obja ; ofstream fout ( " readwrite . dat " , ios :: binary ) ; if (! fout ) { cout << " N~ a o consegue abrir arquivo de disco " ; return ; } while ( obja . Input () ) { cout << " obja . x = " << obja . x << " obja . y = " << obja . y << endl ; fout . write ( r e i n t e r p r e t _ c a s t < char * >(& obja ) , sizeof ( CA ) ) ; } fout . close () ; } void LeObjetos () { CA obja ; cout << " \ nQual objeto quer ler ? " ; int i ; cin >> i ; cin . get () ; // Cria objeto fin , que aponta para a r q u i v o r e a d w r i t e . dat ifstream fin ( " readwrite . dat " , ios :: binary ) ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

23.5. ENTRADA E SA IDA COM ARQUIVOS DE DISCO - USO AVANCADO


58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 if (! fin ) { cout << " N~ a o consegue abrir arquivo de disco " ; return ; } // Vai at e a posi c~ a o i n i c i a l do objeto i no disco fin . seekg ( i * sizeof ( CA ) , ios :: beg ) ; // L^ e o objeto i , usando m e todo read () fin . read ( r e i n t e r p r e t _ c a s t < char * >(& obja ) , sizeof ( CA ) ) ; fin . close () ; // Mostra a t r i b u t o s do objeto lido cout << " obja . x = " << obja . x << " obja . y = " << obja . y << endl ; } int main () { A r m a z e n a O b j e t o s () ; LeObjetos () ; return 0; } sizeof ( A ) =8 Entre com x e y ( x espa co obja . x = 1 obja . y = 2 Entre com x e y ( x espa co obja . x = 3 obja . y = 4 Entre com x e y ( x espa co obja . x = 5 obja . y = 6 Entre com x e y ( x espa co Qual objeto quer ler ?1 obja . x = 3 obja . y = 4

443

y ) :1 2 y ) :3 4 y ) :5 6 y):

23.5.2

Acessando a impressora e a sa da auxiliar2

Como dito anteriormente, alguns sistemas aceitam o uso de um construtor de fstream que recebe um inteiro. Um exemplo e o DOS. Para ligar um arquivo diretamente ` a impressora no DOS, utilize: Prot otipo: fstream cprn(4); caux(3); // cprn e conectado a impressorafstream // caux e conectado a sa da auxiliar.

No exemplo a seguir enviamos para impressora o texto Estou escrevendo na impressora. Exemplo: // Testado no DOS fstream cprn(4); cprn < < Estou escrevendo na impressora ; cprn.close(); fstream caux(3); caux < < Estou enviando texto para sa da auxiliar ; caux.close(); No GNU/Linux o dispositivo impressora est a localizado em /dev/lp0, /dev/lp1,.., etc. Assim, posso criar uma stream e a seguir conect a-la ao dispositivo /dev/lp0. Veja o exemplo. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

444

23.5. ENTRADA E SA IDA COM ARQUIVOS DE DISCO - USO AVANCADO Exemplo: ofstream fout ("/dev/lp0");

Observe como o uso de objetos streams e surpreendente. O procedimento para enviar uma string para a tela e exatamente o mesmo utilizado para enviar uma string para a impressora, sa da auxiliar, modem ou outro programa.

23.5.3

Arquivos de disco bin arios2

Os m etodos get() e put() operam byte a byte, sem interpret a-los. Veja a seguir o prot otipo. Prot otipo: istream & get(char & c); ostream & put(char & c); No exemplo a seguir a string "oi tudo bem e percorrida com s.at[i]. Enquando o acesso n ao falhar, isto e, se o caracter existe, ent ao o mesmo e enviado para o disco com put(). Exemplo: #include <fstream> main() { ofstream fout("data.dat", ios::binary); string s = oi tudo bem ; while(s.at[i]) // Enquanto houver algo fout.put(s[i++]); // Escreve no disco em modo binario fout < < end; fout.close(); return 0; }

23.5.4

Executando e enviando comandos para outro programa2

Um exemplo muito interessante e u til do uso das streams de C++ e a execu ca o e o envio de comandos para um outro programa. Isto e, o seu programa pode executar um programa B e enviar comandos a ele. Nosso objetivo e desenvolver um programa que ir a gerar um conjunto de dados, armazenar estes dados em disco e a seguir executar o programa gnuplot para fazer o gr aco dos dados gerados. O exemplo da listagem 23.6 foi testado na plataforma GNU/Linux/Fedora e utiliza o arquivo de cabe calho "pstream.h" que n ao e padr ao e esta disponibilizado em http://pstreams. sourceforge.net/. Veremos no Cap tulo ?? - Introdu ca o ao Processamento Paralelo com M ultiplos Processos, m etodos alternativos ao uso de "pstream.h". A classe opstream localizada no namespace redi, e utilizada para conectar o seu programa com um programa externo. O nome do programa externo deve ser passado para o construtor de opstream dentro de aspas (). O programa da listagem 23.6 inicia abrindo o arquivo de disco "data.dat", e armazenando neste arquivo um conjunto de dados (x, y = sin(x), z = cos(x)). A seguir o programa executa o programa externo gnuplot na linha redi::opstream gnuplot("gnuplot");. Neste ponto, criamos um objeto do tipo opstream com nome gnuplot, e executamos o programa gnuplot, de forma que poderemos enviar caracteres (comandos) diretamente para o gnuplot. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

23.5. ENTRADA E SA IDA COM ARQUIVOS DE DISCO - USO AVANCADO

445

Depois o programa envia para o gnuplot um conjunto de instru co es para gerar o gr aco desejado. O programa gnuplot e aberto e o gr aco e apresentado (veja Figura 23.1). O gnuplot e um programa utilizado para fazer gr acos. O mesmo est a dispon vel no site: http://www.gnuplot.info/. Se voc e usa GNU/Linux, provavelmente j a tem o gnuplot instalado. Depois de instalar o gnuplot abra um terminal, digite gnuplot e a seguir plot sin(x),cos(x) seguido de enter. Pronto, voc e acaba de gerar um gr aco usando o gnuplot. Quer gerar um gr aco em 3D? digite splot sin(x)*cos(x) . Voc e encontra no site https://www.lenep.uenf.br/~bueno/SoftwareLivre, material da disciplina de Software Livre, o que inclui aula sobre o uso do gnuplot (veja Lista das Aulas, e procure por gnuplot ). As instru co es a seguir s ao utilizadas para plotar, em duas dimens oes, os dados do arquivo data.dat. Com estas instru co es vamos gerar duas curvas, a primeira usando a coluna 1 (x) contra a coluna 2 (y) . A segunda curva vai mostrar os dados da coluna 1 (x) contra os dados da coluna 3 (z). "plot data.dat using 1:2,data.dat using 1:3 O comando pode ser aperfei coado, acrescentando-se t tulos para os dados (title dados de y), e o tipo de linha (with linespoint). "plot data.dat using 1:2 title dados de y with linespoint, data.dat using 1:3 title dados de z with linespoint"

Figura 23.1: Sa da gerada pelo programa gnuplot.


1 dados de y dados de x 0.8 0.6 0.4 0.2 0 -0.2 -0.4 -0.6 -0.8 -1 -10

-5

10

Listing 23.6: Executando e enviando comandos para um outro programa (com <opstream>).
1 # include < iostream >

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

446
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

23.6. SENTENCAS

# include < cstdio > # include < cmath > # include < fstream > # include " pstream . h " // D i s p o n v e l em http :// p s t r e a m s . s o u r c e f o r g e . net / using namespace std ; int main () { // Cria a r q u i v o de disco , onde ir a a r m a z e n a r os dados de x ,y , z ofstream fout ( " data . dat " ) ; float x , y , z ; // A r m a z e n a um c o n j u n t o de dados em disco for ( x = -10; x <= 10; x += 0.1) { y = sin ( x ) ; z = cos ( x ) ; fout << x << " " << y << " " << z << endl ; } fout . close () ; // Cria objeto g n u p l o t do tipo o p s t r e a m e o c o n e c t a com o p r o g r a m a g n u p l o t redi :: opstream gnuplot ( " gnuplot " ) ; // Envia c o m a n d o para o g n u p l o t gnuplot << " plot data . dat using 1:2 title dados de y with linespoint " << " , data . dat using 1:3 title dados de z with linespoint " << endl ; cout << " \ nPression e enter " << endl ; cin . get () ; // E n c e r r a e x e c u c~ a o do g n u p l o t gnuplot . close () ; return 0; }

23.6

Senten cas

A equival encia entre os modos de abertura no C e C++ e dada por: "r" equivale a ios::in; "w" a ios::out e ios::out | ios::trunc; "a" a ios::out | ios::app; "rf" a ios::in | ios::out; "w+" a ios::in | ios::out | ios::trunc. Ap os ler um arquivo de disco at e EOF - End Off File, use clear() para zerar o estado da stream, antes de usar a stream com outro arquivo.

23.7

Resumo do cap tulo

No Cap tulo 22 - Entrada e Sa da com C++, aprendemos a utilizar as classes streams de C++. Neste cap tulo vimos uma introdu ca o ao acesso a disco, onde aprendemos que um objeto ofstream e utilizado para escrever dados em um arquivo de disco e um arquivo ifstream e utilizado para leitura de dados de um arquivo de disco. Aprendemos que podemos criar um objeto ofstream/ifstream j a o associando a dispositivos de disco, ou deixar para fazer esta associa ca o depois com o m etodo open(). Vimos que podemos armazenar e ler objetos inteiros em disco, e que podemos posicionar os ponteiros de arquivos com os m etodos seekg(), seekp(), tellg(), tellp(). Aprendemos a Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

23.8. EXERC ICIOS

447

usar redirecionamentos, e vimos que os mesmos funcionam usando > > e < < (da mesma forma que os operadores de inser ca o< < e extra ca o> >). Aprendemos a acessar a impressora e a sa da aux liar, a criar arquivos de disco bin arios, e a executar e enviar comandos para outros programas usando as classes de <pstream.h> (se ca o 23.5.4). No pr oximo cap tulo, Cap tulo 24 - A Classe string, veremos em detalhes o uso de strings de C++.

23.8

Exerc cios

1. Planilhas eletr onicas como excel, calc, gnumeric, podem importar arquivos de texto com dados em ASCII. Monte um programa que gera um conjunto de dados (x,y,z) e a seguir importe os dados usando uma destas planilhas. A seguir monte gr acos x versus y, e x versus z. 2. Criar uma classe CEstat stica, que e utilizada para calcular a m edia e o desvio padr ao de um conjunto de dados passados pelo usu ario usando cin, ou armazenados em um arquivo de disco. 3. Tenho um arquivo de disco com um nome qualquer, que tem o formato abaixo. Criar uma classe CData1D, em que os valores de uma coluna, como a coluna x, possam ser armazenados. CData1D deve armazenar o nome da coluna, a m edia, o desvio padr ao, a vari ancia, o valor m nimo, e o valor m aximo. Observe que para o arquivo a seguir, iremos precisar de 3 objetos do tipo CData1D. 3 # o n umero 3 indica o n umero de colunas x y z # nome das vari aveis, utilizado como t tulos dos gr aficos 123 432 254 321 765 987 .... 890 543 780 4. Criar um programa que usa CData1D e o programa externo gnuplot para plotar os dados. 5. Modique a listagem 23.1, acrescente a possibilidade de se criar um arquivo de disco em que o nome muda de acordo com dois ndices, i e j. 6. Modique a listagem 23.2, de forma que a mesma possa ler um arquivo de texto exportado por uma planilha usando como separador um caracter qualquer denido pelo usu ario (precisa solicitar o nome do separador (ex: ;,-). 7. Modique a listagem 23.3 , acrescentando o uso de seekg() e seekp(). 8. Modique a listagem 23.3, adaptando as mesmas para um caso que seja de seu interesse. 9. Modique a listagem 23.5, substitua ArmazenaObjeto pelo operador < < e LeObjeto pelo operador > >. 10. Modique a listagem 22.4 de forma a obter o n umero de linhas, palavras e caracteres de um arquivo do disco. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

448

23.8. EXERC ICIOS

11. Montar exemplo que envia para impressora um arquivo postscript (nome.ps). Usar ofstream fout ("/dev/lp0");. 12. Na se ca o 23.5.3, o exemplo usa s.at[i], para acessar a posi ca o i e depois s[i++], esta l ogica esta correta? justique. 13. Modique a listagem 23.6, acrescente uma classe polinomio de grau n. O programa deve solicitar ao usu ario os coecientes do polin onio e a seguir gerar o gr aco no intervalo especicado.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 24

A Classe <string>
A classe <string> foi brevemente apresentada na se ca o 9.4.1 e utilizada em nossos exemplos. Neste cap tulo, vamos nos aprofundar nos conceitos da classe <string>. Veremos uma introdu ca o ` as strings de C++ (se ca o 24.1), discutiremos os diferentes m etodos de <string> (se ca o 24.2), seus construtores (se ca o 24.2.1), iteradores (se ca o 24.2.2), a manipula ca o do tamanho da <string> (se ca o 24.2.3), os operadores de acesso (se ca o 24.2.4), a atribui ca o e concatena ca o (se ca o 24.2.5), a inser ca o, remo ca o e substitui ca o (se ca o 24.2.6). A compara ca o de strings (se ca o 24.2.7), e o uso de substrings (se ca o 24.2.8). Como fazer pesquisas em uma <string> com find e rfind (se ca o 24.2.9). Um exemplo (se ca o 24.3). Finalizamos o cap tulo apresentando algumas senten cas para strings de C++ (se ca o 24.4).

24.1

Introdu c ao ` as strings

A classe basic_string e uma classe template que pode manipular um conjunto de caracteres gen ericos. Normalmente precisamos de caracteres ASCII de 8 bits, ou caracteres de 16 bits. Para satisfazer a estas necessidades, foram denidos os seguintes apelidos: typedef basic_string< char, string_char_traits<char> > typedef basic_string< wchar_t > wstring; string;

Assim, <string> e um apelido para basic_string<char, string_char_traits<char> >, e utilizada para manipular caracteres do tipo char. J a a classe <wstring> e utilizada para manipular caracteres do tipo wchar_t. Nos exemplos que ser ao apresentados nos referimos a <string>, mas os conceitos s ao v alidos para <wstring>. Para utilizar a classe <string>, inclua o arquivo de cabe calho <string>. Exemplo: #include <string>

Nota: nos prot otipos que ser ao apresentados usamos <string> para representar basic_string<char> e char para representar um caracter qualquer. Usamos rst (ou begin()) para indicar um iterador (ou ponteiro) para o in cio da string e last (ou end()) para indicar o m do intervalo (posi ca o n). Num vetor de dimens ao n, podemos acessar da casa 0, at e a casa n-1. Lembre-se this refere-se ao objeto que chama o m etodo. 449

450

24.2. METODOS DE <STRING>

24.2

M etodos de <string>

Veja a seguir os diferentes construtores fornecidos pela classe <string>.

24.2.1

Construtores e destrutor

Um objeto <string> pode ser constru do vazio, a partir de uma outra <string> (de C ou C++), a partir de um caracter ou mesmo de uma sub-string. Observe que alguns construtores recebem o tipo de alocador a ser utilizado. inline string(); Constr oi uma string vazia. explicit string (const Alloc a); Constr oi uma string vazia, recebe o tipo de alocador a ser utilizado. string (const string &src); Construtor de c opia. string (const string& src, size type pos, size type n = npos); Constr oi uma c opia de src a partir da posi ca o pos at e a posi ca o npos. string (const string & src, size type pos, size type n, const Alloc & a); Constr oi string a partir da posi ca o pos da string src, considerando n caracteres. string (size type n, char c, const Alloc& a = Alloc()); Constr oi string de tamanho n, com n c opias do caracter c. string (InputIterator beg, InputIterator end, const Alloc & a = Alloc ()); Constr oi string considerando iteradores beg() e end(). Os iteradores ser ao descritos na se ca o 31.3. Veja a seguir um exemplo. Exemplo: // Cria string com nome s1 string s1; // Cria string com nome s2 e armazena "a classe string" string s2 ("a classe string"); // Cria string com nome s3 e inicializa com " e legal" // utiliza construtor de c opia string s3 = " e legal"; // Cria string com nome s4 uma c opia de s3 // utiliza construtor de c opia string s4 (s3); // Cria string s5, com espa co para 10 caracteres, preenche com b string s5 (10, b); // Cria string s6, uma c opia de s4. // s4.begin() aponta para o in cio de s4 // s4.end() aponta para o fim de s4 string s6 (s4.begin(), s4.end()); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

24.2. METODOS DE <STRING>

451

24.2.2

Iteradores

Como dito, a classe <string>, tem semelhan cas com as classes containers da STL. Nesta se ca o descrevemos os m etodos de <string> utilizados para obten ca o de iteradores, ponteiros inteligentes, para partes da <string>. Os iteradores ser ao descritos na se ca o 31.3. iterator begin (); Retorna um iterador para in cio da string. Utilizado para varrer a string do in cio para o m. iterator end (); Retorna um iterador para m da string. Utilizado para informar que chegamos ao m da string. Exemplo: string s = "oi tudo bem!"; for(string::iterator i = s.begin(); i != s.end(); i++) cout < < s[i] ; reverse iterator rbegin (); Retorna um iterador reverso para m da string. Utilizado para varrer a string do m para o in cio. reverse iterator rend (); Retorna um iterador reverso para in cio da string.

24.2.3

Manipula c ao do tamanho da string

A classe <string> tem um conjunto de m etodos para manipula ca o do tamanho da string. Veremos os m etodos size(), length(), capacity(), max_size(), resize(), reserve(), clear(), empty(). size type size () const; Retorna dimens ao utilizada. size type length () const; Retorna dimens ao utilizada (uso obsoleto). size type capacity () const; Retorna capacidade alocada. Exemplo: string msg(100); // Tem capacidade para armazenar 100 caracteres msg = "123456789"; // Mas o size() e de 9 caracteres size type max size () const; Retorna maior dimens ao poss vel para a string, limitada pela quantidade de mem oria dispon vel em seu computador. void resize (size type n); Redimensiona a string para o tamanho n. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

452

24.2. METODOS DE <STRING>

void resize (size type n, char c); Redimensiona a string para o tamanho n. Se forem criados novos caracteres os mesmos ser ao preenchidos com o caracter c. void reserve (size type res arg = 0); Reserva espa co de mem oria adicional, muda a capacidade da string. void clear (); Zera a string. O size() da string passa a ser zero. bool empty () const; Returna true se a string estiver vazia Veja a seguir um exemplo. Exemplo: // Cria string com nome s6 e a seguir redimensiona string s6 ("eu terei espa co para 100 caracteres"); s6.resize(100); if(s6.empty()) // Verifica se a string esta vazia cout < < "A string s6 esta vazia.";

24.2.4

Operadores de acesso

O operador [] foi sobrecarregado para acessar cada casa da string. Assim, podemos usar s[i] para acessar o elemento i da string s (da mesma forma que usamos <vector>). O m etodo s.at[i] faz o mesmo que s[i], a diferen ca e que se a casa i n ao existe, s.at[i] lan ca uma exce ca o e s[i] causa um estouro de pilha. reference operator[] (size type pos); Acesso a posi ca o i, usando []. Retorna uma refer encia para i. reference at (size type n); Retorna uma refer encia para posi ca o i. Se a casa i n ao existe, lan ca uma exce ca o. const reference operator[] (size type pos) const; Acesso a posi ca o i, usando []. Retorna uma refer encia constante para i. const reference at (size type n) const; Retorna uma refer encia constante para posi ca o i. Se a casa i n ao existe, lan ca uma exce ca o.

24.2.5

Atribui c ao e concatena c ao

O m etodo assign() e usado para atribuir uma string assign(string); uma parte de uma string, assign(string,inicio,n); uma string de C, assign(cstring); ou um caracter, assign(ch) a uma string de C++. string & assign (const string & str); Atribui a string str, para string this. string & assign (const string & str, size type pos, size type n); Atribui a string str, a partir da posi ca o pos, considerando n caracteres. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

24.2. METODOS DE <STRING>

453

24.2.6

Inser c ao, remo c ao, substitui c ao, c opia

Voc e pode remover, remove(), ou substituir, replace(), partes da string. Pode inserir novos caracteres, insert(), ou substrings em uma string existente. void insert (iterator p, size type n, char c); Insere a partir da posi ca o p, n caracteres do tipo c. void insert (iterator p, InputIterator beg, InputIterator end); Insere a partir da posi ca o p, a sub-string acessada por beg e end. string & erase (size type pos = 0, size type n = npos); Apaga bloco de dados a partir da posi ca o pos considerando n caracteres. iterator erase (iterator pos); Apaga caracter na posi ca o dada por pos. iterator erase (iterator begin(), iterator end()); Apaga caracteres no intervalo dado pelos iteradores begin() e end(). string & replace (size type pos, size type n, const string & str); A partir da posi ca o pos, considerando n caracteres, coloca a string str. size type copy (char * s, size type n, size type pos = 0) const; Copia n caracteres de s para posi ca o pos. void swap (string & s); Troca o conte udo das strings. Veja a seguir um exemplo. Exemplo: string s1 = "0123456789"; string s2 = "abcdefghijklmnopqrst"; cout < < s1 < < "\t" < < s2 < < endl; s1.erase(s1.begin()+3); s2.swap(s1); cout < < s1 < < \t < < s2 < < endl;

24.2.7

Compara c ao

Voc e pode comparar strings utilizando os operadores: ==, !=, >, <, >=, <=, ou o m etodo compare(). Se compare() retorna 0 as strings s ao iguais. Se o retorno e menor que zero s1 e maior que s2, se o retorno e maior que zero, s1 e menor que s2. int compare (const string & str) const; Compara string this com str. int compare (size type pos, size type n, const string & str) const; Compara string this com str, a partir da posi ca o pos, considerando n caracteres. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

454

24.2. METODOS DE <STRING>

24.2.8

Substrings

Pode-se criar e manipular sub-strings a partir de uma string. string substr (size type pos = 0, size type n = npos) const; Cria uma sub-string a partir da posi ca o pos, considerando n casas. const char* c str(); Retona uma string no estilo de C (uma cstring). Exemplo: string s = "Palmeiras campe~ ao mundial 1951"; string sub = s.substr(0,10);

24.2.9

Pesquisa

A classe <string> fornece fun co es de pesquisa como find() e pesquisa invertida com rfind(). O m etodo find("seq") localiza a primeira ocorr encia de "seq" na string. Pode-se especicar com um inteiro a posi ca o inicial da busca. O m etodo rfind() busca da posi ca o nal para a inicial, ou seja, faz pesquisa reversa. Outros m etodos de pesquisa find_first_of(), find_last_of(), find_first_not_of() e find_last_not_of() tratam a string argumento como um conjunto de caracteres. A posi ca o do primeiro caractere encontrado e retornada e, se n ao encontrar, retorna uma exce ca o do tipo out_of_range. O prot otipo destes m etodos e apresentado a seguir, veja exemplo na listagem ??. size type nd (const string & str, size type pos = 0) const; Procura a primeira ocorr encia da string str, a pesquisa inicia em pos. size type nd (const char * str, size type pos, size type n) const; Procura a primeira ocorr encia da cstring str, a pesquisa inicia em pos e considera at en caracteres. size type rnd (const string & str, size type pos = npos) const; Procura a primeira ocorr encia da string str, a pesquisa inicia em pos e e feita do m de this para o in cio (pesquisa reversa). size type nd rst of (const string & str, size type pos =0) const; Procura a primeira ocorr encia da string str, a pesquisa inicia em pos. size type nd last of (const string & str, size type pos = npos) const; Procura a u ltima ocorr encia da string str, a pesquisa inicia em pos. size type nd rst not of (const string & str, size type pos=0) const; Procura a primeira n ao ocorr encia da string str, a pesquisa inicia em pos. size type nd last not of (const string & str, size type pos = npos) const; Procura a u ltima n ao ocorr encia da string str, a pesquisa inicia em pos e e invertida. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

24.3. EXEMPLOS DE USO DE <STRING>

455

24.3

Exemplos de uso de <string>

Na listagem 24.1, alguns m etodos da classe <string> s ao testados. O c odigo esta documentado. Listing 24.1: Usando a classe <string> de C++.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 # include < iostream > # include < string > # include < cstring > using namespace std ; int main () { // Cria string com nome s1 string s1 ; s1 = " Oi , tudo bem " ; // Cria string com nome s2 e a r m a z e n a " C ++ e legal " string s2 ( " C ++ e legal " ) ; // Cria string com nome s3 e i n i c i a l i z a com " demais " string s3 = " demais " ; // Cria string com nome s4 uma c o pia de s3 ( usa c o n s t r u t o r de c o pia ) string s4 ( s3 ) ; // Cria string com nome s5 e define t a m a n h o como sendo 100 c a r a c t e r e s string s5 = " eu tenho espa c o para 100 caracteres " ; // R e d i m e n s i o n a a string s5 s5 . resize (100) ; cout << " Conte u do das strings :\ ns1 = " << s1 << " \ ns2 = " << s2 << " \ ns3 = " << s3 << " \ ns4 = " << s4 << " \ ns5 = " << s5 << endl ; // Tamanho , c a p a c i d a d e e cout << " s5 . size () = " << " s5 . capacity () = " << " s5 . max_size () = " t a m a n h o m a ximo da string s5 << s5 . size () << s5 . capacity () << s5 . max_size () << endl ;

// Cria a string s7 e p r e e n c h e com o c a r a c t e r e a string s7 (10 , a ) ; cout << " s7 . size () = " << s7 . size () << " s7 = " << s7 << endl ; // R e d i m e n s i o n a s7 . resize (15 , t ) ; cout << " Depois de s7 . resize (15 , t ) ; s7 . size () = " << s7 . size () << " s7 . length () = " << s7 . length () << " s7 = " << s7 << endl ; // R e t o r n a true se a string s7 e s t i v e r vazia if ( s7 . empty () ) cout << " A string s7 est a vazia " << endl ; // C o pia de s t r i n g s s1 = s2 ; cout << " Ap o s s1 = s2 , s1 = " << s1 << " , s2 = " << s2 << endl ; // A t r i b u i c~ a o de uma string de C s4 = " - p r o f i s s i o n a l " ; // A t r i b u i c~ a o de um u nico c a r a c t e r e s5 = - ; cout << " s4 = " << s4 << " \ t s5 = " << s5 << endl ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

456
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118

24.3. EXEMPLOS DE USO DE <STRING>

// A d i c i o n a r a string e x i s t e n t e ( c o n c a t e n a r ) s5 += " Inclui a STL - e e "; cout << " s4 = " << s4 << " \ t s5 = " << s5 << endl ; // A d i c i o n a ao final de s5 , 6 c a r a c t e r e s de s3 , a partir da p o s i c~ a o 1 de s3 . s5 . append ( s3 , 1 , 6) ; cout << " Ap o s s5 . append ( s3 , 1 , 6) ; s5 = " << s5 << endl ; // Cria uma c o pia de s2 , a d i c i o n a s4 , s5 , e mostra na tela cout << " ( s2 + s4 + s5 ) = " << ( s2 + s4 + s5 ) << endl ; // Troca o c o n t e u d o das s t r i n g s s1 e s5 s5 . swap ( s1 ) ; cout << " Ap o s s5 . swap ( s1 ) ; " << endl << " s1 = " << s1 << " \ ns5 = " << s5 << " \ nDo caracter s1 [11] at e s1 [14]= " ; // Acessa a p o s i c~ a o i da string ( como em v e t o r e s) for ( int i = 11; i < 14; i ++) cout << s1 [ i ]; cout << endl ; // Coloca a letra P na p o s i c~ ao 2 s4 [2] = P ; cout << " Ap o s s4 [2]= P , s4 [2]= " << s4 [2] << " s4 = " << s4 << endl ; // O mesmo que s4 [2] , acessa p o s i c~ a o 2 ( com at (2) v e r i f i c a acesso ) cout << " s4 . at (2) = " << s4 . at (2) << endl ; // Cria uma string no padr~ a o C , uma c s t r i n g char cstring [256]; // Copia a string s4 para cstring , usa fun c~ a o strcpy do a r q u i v o de // c a b e c a l h o < cstring > strcpy ( cstring , s4 . c_str () ) ; cout << " cstring = " << cstring << endl ; // Uso de r e p l a c e e insert s5 . replace (9 , 1 , " t " ) ; s4 = " para as outras linguagens " ; s3 . insert ( s3 . end () , s4 . begin () , s4 . end () ) ; cout << s5 << s3 << endl ; s5 = " tem " ; // S u b s t i t u i c a r a c t e r e s de s1 [17] at e s1 [22] por s5 s1 . replace ( s1 . begin () +17 , s1 . begin () +22 , s5 . begin () , s5 . end () ) ; cout << s1 + " - e m u l t i p l a t a f o r m a " << endl ; // A d i c i o n a " p r o g r a m a c~ ao gen erica e " s1 . insert (10 , " programa ca ~ o gen e rica e " ) ; cout << s1 << endl ; // Cria uma s u b s t r i n g de s1 , a partir da p o s i c~ a o 10 at e o final de s1 cout << " s1 . substr (10) = " << s1 . substr (10) << endl ; // Cria uma s u b s t r i n g de s4 cout << " s1 . substr (10 , 12) = " << s1 . substr (10 , 12) << endl ; // C o n c a t e n a n d o s t r i n g s com append // append aceita uma v a r i e d a d e de c o m b i n a c~ oes string s10 ( " Oi " ) ; cout << s10 << endl ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

24.3. EXEMPLOS DE USO DE <STRING>


119 120 121 122 123 124 125 126 127 128 129 130 131 132 s10 . append ( " , tudo Bem ! " ) ; cout << s10 << endl ; // O m e todo copy pode ser u t i l i z a d o para copiar parte da string // para uma c s t r i n g. copy ( char * , int size , int p o s I n i c i a l =0) ; char teste [255]; s10 . copy ( teste , s10 . size () , 0) ; cout << " teste = " << teste << endl ; // O m e todo c o m p a r e e u t i l i z a d o para c o m p a r a r s t r i n g s ou partes de s t r i n g s cout << s10 . compare ( teste ) << endl ; return 0; } Conte u do das strings : s1 = Oi , tudo bem s2 = C ++ e legal s3 = demais s4 = demais s5 = eu tenho espa c o para 100 caracteres s5 . size () =100 s5 . capacity () =100 s5 . max_size () = 4 6 1 1 6 8 6 0 1 8 4 2 7 3 8 7 8 9 7 s7 . size () =10 s7 = aaaaaaaaa a Depois de s7 . resize (15 , t ) ; s7 . size () =15 s7 . length () =15 s7 = a a a a a a a a a a t t t t t Ap o s s1 = s2 , s1 = C ++ e legal , s2 = C ++ e legal s4 = - p r o f i s s i o n a l s5 = s4 = - p r o f i s s i o n a l s5 = - Inclui a STL - e e Ap o s s5 . append ( s3 , 1 , 6) ; s5 = - Inclui a STL - e e demais ( s2 + s4 + s5 ) = C ++ e legal - p r o f i s s i o n a l - Inclui a STL - e e demais Ap o s s5 . swap ( s1 ) ; s1 = - Inclui a STL - e e demais s5 = C ++ e legal Do caracter s1 [11] at e s1 [14]= STL Ap o s s4 [2]= P , s4 [2]= P s4 = - P r o f i s s i o n a l s4 . at (2) = P cstring = - P r o f i s s i o n a l C ++ e letal demais para as outras linguagens - Inclui a STL - e tem mais - e multiplataforma - Inclui a programa ca ~ o gen e rica e STL - e tem mais s1 . substr (10) = programa ca ~ o gen e rica e STL - e tem mais s1 . substr (10 , 12) = programa ca ~o Oi Oi , tudo Bem ! teste = Oi , tudo Bem !* -1

457

Na listagem 24.2, os m etodos find(), rfind(), find_first_of(), find_first_not_of(), replace() da classe <string> s ao testados. Observe que mostramos como trocar espa cos por , o que e util para renomear arquivos. Tamb em mostramos como trocar a extens ao de um arquivo. Listing 24.2: Usando os m etodos de pesquisa da classe string de C++.
1 2 3 4 5 6 7 # include < iostream > # include < string > # include < cstring > using namespace std ; int main () {

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

458
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 // Usando find () e rfind () string s1 = " cascavel / parana " ; cout << " s1 = " << s1 << " \ ns1 . find (\" ca \") = " << " \ ts1 . find (\" ca \" , 1) = " << " \ ns1 . rfind (\" ca \") = " << " \ ts1 . rfind (\" ca \" , 2) = "

24.3. EXEMPLOS DE USO DE <STRING>

// s1 [0]= c , s1 [1]= a ,.. << << << << s1 . find ( " ca " ) s1 . find ( " ca " , 1) s1 . rfind ( " ca " ) s1 . rfind ( " ca " , 2) << endl ;

// P r o c u r a a p r i m e i r a o c o r r ^ e n c i a de aeiou int i = s1 . f i n d _ f i r s t _ o f ( " aeiou " ) ; cout << " f i n d _ f i r s t _ o f aeiou = " << i ; // P r o x i m a n~ a o vogal int j = s1 . f i n d _ f i r s t _ n o t _ o f ( " aeiou " , i ) ; cout << " \ n f i n d _ f i r s t _ n o t _ o f aeiou = " << j

<< endl ;

// Para trocar c a r a c t e r e s em uma string string n o m e A r q u i v o C o m E s p a c o s ( " Nome de Arquivo Com Espacos . txt " ) ; cout << n o m e A r q u i v o C o m E s p a c o s << endl ; // Troca os e s p a c o s " " por " _ " int pos = 0; while (( pos = n o m e A r q u i v o C o m E s p a c o s . find ( " " , pos ) ) > 0) n o m e A r q u i v o C o m E s p a c o s . replace ( pos ,1 , " _ " ) ; // Para s u b s t i t u i r a e x t e n s ~ a o de um a r q u i v o pos = n o m e A r q u i v o C o m E s p a c o s . rfind ( " . " ) ; n o m e A r q u i v o C o m E s p a c o s . replace ( pos , 4 , " . dat " ) ; cout << n o m e A r q u i v o C o m E s p a c o s << endl ; return 0; } s1 = cascavel / parana s1 . find (" ca ") = 0 s1 . find (" ca " , 1) = 3 s1 . rfind (" ca ") = 3 s1 . rfind (" ca " , 2) = 0 f i n d _ f i r s t _ o f aeiou = 1 f i n d _ f i r s t _ n o t _ o f aeiou = 2 Nome de Arquivo Com Espacos . txt N o m e _ d e _ A r q u i v o _ C o m _ E s p a c o s . dat

Veja na listagem 24.3 a utiliza ca o das classes <string>, sstream e ifstream para executar um programa do shell. O programa cria um arquivo de disco com o nome lixo, onde s ao armazenados os nomes dos arquivos que t em extens ao *.jpg. A seguir, monta a linha de comando a ser executada. Finalmente, realiza a convers ao de imagens no formato *.jpg para o formato *.ps executando o programa convert (um programa do GNU/Linux usado para converter imagens de um formato para outro). Observe que o programa usa a fun ca o system() para executar comandos do shell. Neste exemplo, o comando os.str() retorna um objeto da classe <string>. Para obter uma string no estilo de C, chama-se adicionalmente o m etodo c_str(). Nota: este exemplo e meramente did atico, visto que existem maneiras mais inteligentes de converter arquivos. Listing 24.3: Usando as classes <string> e sstream para executar comandos do shell.
1 2 3 # include < iostream > # include < fstream > # include < string >

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

24.4. SENTENCAS PARA STRINGS DE C++


4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # include < sstream > int main ( int argc , char * argv ) { // Lista dos a r q u i v o s com e x t e n s ~ a o jpg // Nota : voc^ e pode s u b s t i t u i r ls pelo c o m a n d o find () . system ( " ls *. jpg > lixo " ) ; std :: string arq ; std :: ifstream fin ( " lixo " ) ; if ( fin . good () ) // E n q u a n t o tiver algo no a r q u i v o de disco , ler o nome do a r q u i v o while ( fin >> arq ) { int posicao = arq . rfind ( " jpg " ) ; // D e t e r m i n a p o s i c~ a o do jpg std :: o s t r i n g s t r e a m os ; os << " convert " << arq ; // In cio do c o m a n d o " c o n v e r t arq . jpg " arq . replace ( posicao , 3 , " ps " ) ; // S u b s t i t u i e x t e n s ~ a o jpg por ps os << " > " << arq ; // Fim do c o m a n d o " > arq . ps " std :: cout << os . str () << " \ n \ n " ; system ( os . str () . c_str () ) ; // E x e c u t a o c o m a n d o } // E l i m i n a o a r q u i v o lixo system ( " rm -f lixo " ) ; return 0; }

459

24.4

Senten cas para strings de C++

As fun co es insert() e remove() s ao similares as de vetores. A fun ca o replace() e uma combina ca o de remove() e insert(), substituindo o intervalo especicado por novo valor. A fun ca o compare() raramente e acessada diretamente; normalmente utilizamos os operadores de compara ca o (<, <=, ==, !=, >= e >). Pode-se comparar duas strings de C++ ou uma string de C++ com uma string de c (uma cstring). Em C++ o operador == verica se duas strings s ao iguais (se o conte udo e igual). Em Java este operador verica se as duas strings s ao a mesma (ocupam o mesmo espa co de mem oria). O operador endere co (&) aplicado a s[0] n ao e um ponteiro para o primeiro elemento da string. Isto e, a string n ao tem um ponteiro para o primeiro elemento. Para manipula ca o avan cada de strings, utilize iteradores (veja Parte III - Introdu ca o ` a STL). Se a string for redimensionalizada, possivelmente os iteradores existentes ir ao apontar para um monte de lixo (iteradores s ao descritos no Cap tulo 31). Observe que se uma string for muito grande, voc e pode quebr a-la no c odigo usando \. Exemplo: string s = "Releia o cap tulo com aten c~ ao, cada linha e verifique \ como esta pode ser utilizada em seus programas"; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

460

24.5. RESUMO DO CAP ITULO

24.5

Resumo do cap tulo

Vimos uma breve descri ca o da classe <string> na se ca o 9.4.1, neste cap tulo aprendemos novos m etodos da classe <string>. Discutimos os diferentes tipos de construtores, o uso de iteradores, operadores de acesso e operadores de compara ca o de strings. A classe <string> tem um conjunto de m etodos para manipula ca o do tamanho da string. Pode-se obter o tamanho utilizado com size() e a capacidade real da string com capacity(). Pode-se redimensionalizar a string com resize(). O m etodo max_size() retorna o tamanho da maior string que pode ser constru da. O m etodo length() e denido para manter compatibilidade com vers oes antigas da classe <string>. Vimos o uso de substrings. No nal do cap tulo aprendemos a fazer pesquisas em uma <string> com find(), rfind(). E ainda vimos o arquivo <string> da biblioteca padr ao. Nota: Os livros de C++ procuram explicar apenas parte das fun co es/m etodos da biblioteca padr ao. Isto se deve ` a necessidade de se limitar o n umero de p aginas dos livros. Se f ossemos incluir todos os m etodos os livros passariam de 2000 p aginas. A dica e: para conhecer em detalhes determinada classe da biblioteca padr ao, abra e leia o arquivo correspondente.

24.6

Exerc cios

1. Monte um exemplo em que a lista de arquivos de um diret orio e armazenada em um arquivo de disco. A seguir pergunte para o usu ario qual arquivo quer localizar. Depois abra o arquivo e use os m etodos de <string> para localizar e mostrar partes do arquivo que foi aberto. 2. Adicione ao programa anterior a possibilidade de renomear arquivos. 3. Adicione ao programa anterior a possibilidade de mudar a extens ao dos arquivos. 4. Crie um programa que calcula o tamanho m nimo, m aximo e m edio dos arquivos em um determinado diret orio. 5. Criar um programa que recebe um arquivo de disco e calcula: o n umero de letras, palavras e frases. A freq u encia de ocorr encia de cada letra (visualizar o histograma utilizando o programa gnuplot ). c por c, a por a. 6. Monte um programa que troque: por , 7. Corrigir o exemplo da listagem 24.3, de forma que os arquivos que tenham espa co no nome possam ser convertidos corretamente. 8. Criar exemplo que use as diferentes vers oes de: find(), rfind(), find_first_of() e find_first_not_of(). 9. Leia agora o arquivo /usr/include/c++/4.1.1/bits/basic string.h, da biblioteca padr ao.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 25

Convers oes
Neste cap tulo mostraremos o prot otipo para convers oes entre objetos (se ca o 25.1) e sua necessidade (se ca o 25.2). A seguir veremos o construtor de convers ao (se ca o 25.3), o operador de convers ao (se ca o 25.4) e o uso de explicit em construtores (se ca o 25.5). Discutiremos ainda a utiliza ca o de static_cast<> (se ca o 25.6), dynamic_cast<> (se ca o 25.7), const_cast<> (se ca o 25.8) e reinterpret_cast (se ca o 25.9). Finalmente veremos algumas senten cas para convers oes (se ca o 25.10).

25.1

Prot otipo para convers oes

Na vida real estamos o tempo todo adaptando os objetos para uso diferente do inicialmente projetado. Poder amos citar milhares de casos, mas vamos mostrar apenas alguns poucos, bem comuns: Voc e precisa de um abridor de latas, mas s o tem uma faca, o que voc e faz? A resposta e simples e direta, usa a faca como abridor de lata. Voc e precisa de uma chave de fenda, mas s o tem uma faca, o que voc e faz? A resposta e simples e direta, usa a faca como chave de fenda. Quando temos um programa real nos deparamos com diversas situa co es onde precisamos utilizar um objeto para uma fun ca o alternativa. De um modo geral, o objeto pode ser utilizado para uma fun ca o n ao previamente planejada, desde que tenha funcionalidades semelhantes ao objeto a ser substitu do. Um caso usual de convers oes e a convers ao entre n umeros, de inteiro (int) para utuante (float) e vice-versa. Outro exemplo e a convers ao de classes-derivadas em classes-base. Veja a seguir o prot otipo para deni ca o e uso dos construtores de convers ao e dos operadores de convers ao. Ao longo deste cap tulo os mesmos ser ao detalhados. Prot otipo: class Base { // Declara ca o de construtor com explicit (veja se ca o 25.5) explicit Base (par ametros); }; 461

462

25.2. NECESSIDADE DE CONVERSAO class Derivada : public Base { // Construtor de convers ao (veja se ca o 25.3) // Cria objeto da classe-derivada a partir de objeto da classe-base Derivada(const Base & obj){}; // Declara ca o de operador de convers ao para classe-base (veja se ca o 25.4) operator Base(); // Declara ca o de operador de convers ao, converte para outro tipo (veja se ca o 25.4) operator Tipo(); }; // Deni ca o do m etodo de convers ao Tipo Derivada::operator Tipo() { // Descri ca o de como se processa a convers ao return(Tipo); }; ... // Utiliza ca o de static cast<> (veja se ca o 25.6) Derivada der; Base base = static cast<Base> (der); // Utiliza ca o de dynamic cast<> (veja se ca o 25.7) Base* ptrBase = new Derivada; Derivada* ptrDerivada = dynamic cast <Derivada*> (ptrBase); // Utiliza ca o de refer encias e dynamic cast<> (veja se ca o 25.7.1) Tipo & ref = dynamyc cast<Tipo & >(r); ca o 25.8) // Utiliza ca o de const cast<> (veja se Tipo* ptr = const cast<Tipo*> (const ptr);

25.2

Necessidade de convers ao

Voc e j a sabe que existe uma hierarquia de classes para os tipos num ericos e um sistema de convers ao entre os diferentes tipos num ericos. Assim, um int pode ser convertido em double (sem perda de dados) e um double pode ser convertido em int (com poss vel perda de dados). Da mesma forma, os tipos denidos pelo programador tamb em podem ser convertidos, devendo o programador denir a forma como esta convers ao deve ser realizada. Observe o seguinte exemplo: digamos que exista uma classe B e uma classe-derivada D, e que foi criado o objeto b1 do tipo B e o objeto d1 do tipo D. Criamos tamb em os objetos b2, fazendo B b2 = d1; e um objeto b3, fazendo B b3 = b1;. Como a classe D e derivada da classe B, um objeto do tipo D pode ser convertido para B. Entretanto, n ao e poss vel criar um objeto do tipo D a partir de um objeto do tipo B, (fazendo D d2 = b1;), porque B e menor que D. A listagem 25.1 esclarece melhor esta situa ca o. Listing 25.1: Mostrando a necessidade de convers oes.
1 2 3 4 5 6 7 8 // Define tipo B class B { public : int x ; }; // Define tipo D class D : public B

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

25.3. CONSTRUTOR DE CONVERSAO


9 10 11 12 13 14 15 16 17 18 19 20 21 { public : int y ; }; int main () { B b1 ; D d1 ; B b2 = d1 ; B b3 = b1 ; D d2 = b1 ; return 0; }

463

// // // // //

Cria objeto do tipo B com nome b1 Cria objeto do tipo D com nome d1 Ok Ok Erro , b1 n~ a o p r e e n c h e d2 ( b1 n~ a o tem y ) .

n e c e s s i d a d e C o n v e r s a o . cpp : In function int main () : n e c e s s i d a d e C o n v e r s a o . cpp :19: error : conversion from B to non - scalar type D requested

Na linha B b2 = d1; o c odigo funciona porque d1 tem os atributos x e y e o compilador faz b2.x = d1.x;. Na linha D d2 = b1; b1 s o tem o atributo x, e d2 precisa de um x e um y. Como b1 n ao tem y, o compilador acusa o erro. A solu ca o para este tipo de problema e a utiliza ca o de construtores de convers ao, descritos a seguir.

25.3

Construtor de convers ao

Um construtor de convers ao e utilizado para construir um objeto do tipo D a partir de um objeto do tipo B. Isto e, recebe um objeto do tipo base e constr oi um objeto do tipo derivado. Veja no exemplo a seguir que o construtor do objeto D, faz y = 0;. Exemplo: class D: public B { int y; // Construtor de convers~ ao, recebe um B e constr oi um D D(const& B obj) { this->x = obj.x; this->y = 0; } }; Com o construtor de convers ao do exemplo acima, resolvemos o problema da linha D d2 = b1; preenchendo o valor de y com zero (this->y = 0;). Entretanto, se tivermos Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

464 B b; D d; d = b;

- CAST 25.4. OPERADOR DE CONVERSAO

o objeto b e o objeto d j a foram criados. Neste caso e necess ario um m etodo que converta o objeto b em d. Para solucionar este problema, utiliza-se um operador de convers ao descrito na se ca o 25.4.

25.4

Operador de convers ao - cast

Um operador de convers ao e utilizado para converter um objeto de um tipo em outro. Observe que o m etodo n ao precisa ser da mesma hierarquia. O prot otipo e dado a seguir. Veja que o m etodo operator Tipo(); deve converter de CNome para Tipo. Observe o uso da palavra-chave operator, seguida do nome do tipo a ser criado a partir de CNome. Prot otipo: class CNome {... // Declara ca o de m etodo de convers ao operator Tipo(); }; No exemplo a seguir o operator B() e utilizado para converter um objeto do tipo B num objeto do tipo D. Note que para utilizar o m etodo de convers ao, podemos ter uma convers ao impl cita ou explicita. Exemplo: class D { public: int y; operator B() { B* b = new B(); b->x = this->x; return *b; } }; int main() { B b; D d; b = d; // b = (B) d; // // tico de C++ b = static_cast< return 0; }

// Converte da classe D para classe B // Cria objeto do tipo B // Preenche atributos do objeto b // Retorna objeto

Impl cita, converte de d para b Expl cita, com a utiliza c~ ao de cast de d Expl cita, com a utiliza c~ ao do cast est aB > (d);

Veremos o uso de static_cast< >(); na se ca o 25.6. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

EXPLICITA NOS CONSTRUTORES COM EXPLICIT 25.5. CONVERSAO

465

25.5

Convers ao explicita nos construtores com explicit

Em algumas hierarquias as convers oes ocorrem automaticamente. Se voc e n ao quiser que isso ocorra, ou seja, quiser ter controle das convers oes, utilize a palavra-chave explicit na declara ca o do construtor. Veja na listagem 25.2 exemplo de uso de construtor com explicit. Observe que na linha Saida(10); deveria ocorrer um erro, pois Saida() recebe como par ametro um CData, e estamos passando um int. Mas como existe um construtor de CData que recebe um int, o compilador vai criar automaticamente um objeto CData e a seguir chamar Saida(). Observe na sa da que ao trocar o construtor CData por explicit CData o compilador n ao realiza a convers ao autom atica e emite o erro de inicializa ca o incorreta. Veja na sa da que quando o construtor n ao usa explicit, a linha Saida(10); funciona, pois o compilador troca automaticamente a linha Saida(10); por Saida(CData(10)); ou seja, cria um CData a partir do n umero 10 e a seguir executa o m etodo Saida(). Listing 25.2: Usando construtor com explicit.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # include < iostream > using namespace std ; class CData { public : int x ; // C o n s t r u t o r sem uso de e x p l i c i t CData ( int _x = 10) : x ( _x ) { }; // C o n s t r u t o r com uso de e x p l i c i t // e x p l i c i t CData ( int _x = 10) : x ( _x ) { } }; // Fun c~ a o global , recebe um objeto do tipo CData void Saida ( const CData & dat ) { cout << dat . x << endl ; } int main () { int i = 5; CData data ( i ) ; cout << " Saida ( data ) ; " ; Saida ( data ) ; cout << " Saida ( 10 ) ; " ; Saida ( 10 ) ; return 0; } Sa da sem uso de explicit : ------------------------bash -3.00 $ ./ a . out Saida ( data ) ; 5 Saida ( 10 ) ; 10

// Cria CData // I m p r i m e data

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

466

ESTATICA 25.6. CONVERSAO COM STATIC_CAST<>

Sa da com uso de explicit : ------------------------bash -3.00 $ g ++ Usando - explicit . cpp Usando - explicit . cpp : In function int main () : Usando - explicit . cpp :37: error : invalid i n i t i a l i z a t i o n of reference of type const CData & from expression of type int Usando - explicit . cpp :19: error : in passing argument 1 of void Saida ( const CData &)

25.6

Convers ao est atica com static_cast<>

Na linguagem C uma vari avel int pode ser convertida para double usando-se cast. Exemplo: int x = 3; float y = (float) x; Neste exemplo o cast e o trecho de c odigo (float), que for ca a convers ao de x do tipo int para float. como se Note que o uso de cast subverte o controle de tipos realizados pelo compilador. E o programador dissece para o compilador ca tranquilo, eu sei o que estou fazendo. Ou seja, a responsabilidade pelo uso do cast e toda do programador. Para implementar o conceito de cast em C++, usamos a palavra-chave static_cast<>. Veja prot otipo a seguir. Note que static_cast<> e utilizado para convers oes de tipos em tempo de compila ca o. Se a convers ao for ilegal, o compilador acusa o erro, o que n ao e feito no cast de C. Prot otipo: TipoA obja; TipoB objb = static cast<TipoB> (obja); No exemplo a seguir, static_cast<> converte de float para double. Exemplo: float fpi = 3.141516; double dpi = static_cast<double>(fpi);

25.7

Convers ao din amica com dynamic_cast<>

Quando temos uma hierarquia de classes, podemos criar um ponteiro para a classe-base e fazer com que esse ponteiro aponte para um objeto de uma classe-derivada (veja Cap tulo 19 Polimorsmo). Em algumas ocasi oes e necess ario converter o ponteiro da classe-base em um ponteiro de classe-derivada. Isto e feito com o uso de cast din amico, um cast realizado em tempo de execu ca o e que utiliza a palavra-chave dynamic_cast<>. No prot otipo a seguir converte o ponteiro ptrBase para um ponteiro do tipo TipoDerivado. Funciona se TipoDerivado e derivado direta ou indiretamente do TipoBase, caso contr ario retorna uma exce ca o do tipo bad_cast (veremos exce co es no Cap tulo 26 - Exce co es). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

DINAMICA 25.7. CONVERSAO COM DYNAMIC_CAST<> Prot otipo: TipoBase* ptrBase; ptrBase = new TipoDerivado; TipoDerivado* ptr = dynamic cast <TipoDerivado*> (ptrBase);

467

No exemplo a seguir, cria-se um ponteiro pm que aponta para um objeto TImagem (derivado). Posteriormente cria TImagem* im a partir de pm, utilizando dynamic_cast<>. Funciona porque o objeto criado e apontado por pm e um objeto do tipo TImagem. Exemplo: class TMatriz{}; // Classe-base class TImagem: public TMatriz{}; // Classe-derivada TMatriz* pm; // Ponteiro para classe-base pm = new TImagem(); // Aponta para objeto derivado .................... // pm e usado // Converte pm para im usando dynamic_cast<> TImagem * im = dynamic_cast < TImagem* > (pm); Veja no exemplo da listagem 25.3 a utiliza ca o de dynamic_cast<>. Listing 25.3: Usando dynamic_cast e typeid.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 // E x t r a d o do HELP do B o r l a n d C ++ 5.0 e a d a p t a d o # include < iostream > # include < typeinfo > using namespace std ; class Base1 { virtual void f () }; class Base2 {}; // Base1 { };

// Base2

// D e r i v a d a class Derivada : public Base1 , public Base2 { }; int main () { Derivada d ; // Cria objeto d Derivada * pd = 0; // P o n t e i r o para D e r i v a d a Base1 * pb1 = & d ; // P o n t e i r o para Base1 , aponta para objeto d cout << " Tipo do ponteiro resultante = " << typeid ( pb1 ) . name () << endl ; cout << " Realiza um cast din^ a mico ( downcast ) de Base1 para Derivada .\ n " ; if (( pd = d y n a m i c _ c a s t < Derivada * >( pb1 ) ) != 0) { cout << " Tipo do ponteiro resultante = " << typeid ( pd ) . name () << endl ; } // Fique atento a h i e r a r q u i a da classe . // Cast de uma classe B1 para D e depois de D para B2 . Base2 * pb2 = 0; cout << " Realiza um cast din^ a mico ( croscast ) de Base1 para Base2 . " << endl ; if (( pb2 = d y n a m i c _ c a s t < Base2 * >( pb1 ) ) != 0) {

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

468
38 39 40 41 42

COM CONST_CAST<> 25.8. CONVERSAO


cout << " Tipo do ponteiro resultante = " << typeid ( pb2 ) . name () << endl ; }

return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ a . out Tipo do ponteiro resultante = P5Base1 Realiza um cast din^ a mico ( downcast ) de Base1 para Derivada . Tipo do ponteiro resultante = P8Derivada Realiza um cast din^ a mico ( croscast ) de Base1 para Base2 . Tipo do ponteiro resultante = P5Base2

Para uso do cast din amico e necess aria a passagem do par ametro - RTTI para o compilador (leia informa co es de seu compilador). A sigla RTTI signica Run-Time Type Information , ou seja, informa co es sobre os objetos criados em tempo de execu ca o. A utiliza ca o do RTTI e do dynamic_cast<> implica c odigos maiores e mais lentos.

25.7.1

dynamic_cast<> e refer encias

O dynamic_cast<> tamb em pode ser utilizado com refer encias, veja o prot otipo. Se o dynamic_cast<> para uma refer encia falha, uma exce ca o do tipo bad_cast e lan cada. Veremos o uso de exce co es no Cap tulo 26 - Exce co es. Prot otipo: Tipo & ref = dynamic cast< Tipo & >(r);

25.8

Convers ao com const_cast<>

Quando o ponteiro e const, dynamic_cast<> e static_cast<> n ao podem ser utilizados. Neste caso, voc e deve utilizar const_cast<>. Veja a seguir o prot otipo e um exemplo. Observe que o ponteiro ptr vai ser convertido para T*. Prot otipo: const T* constptr; T* ptr = const cast<T*> (constptr); Exemplo: void f(const T* constptr ) { T* ptr = const_cast<T*> (constptr ); .... }

25.9

Convers ao com reinterpret_cast<>

A palavra-chave reinterpret_cast<> permite reinterpretar um cast. Veja exemplo na listagem 21.4. Note que com reinterpret_cast<> podemos for car qualquer tipo de convers ao entre tipos (semelhante ao antigo cast de C). Prot otipo: T* p = reinterpret cast<T*> (ptr); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

25.10. SENTENCAS PARA CONVERSOES Exemplo: int main() { int a = 3; int* pa = &a; cout < < "pa=" < < *pa < < endl; // Imprime o caracter ! cout < < *reinterpret_cast<char*>(pa) < < endl; return 0; }

469

Dica: n ao use reinterpret_cast<>. Se em algum momento precisar dele e sinal de que sua modelagem esta com problemas.

25.10

Senten cas para convers oes

Lembre-se um cast subverte o sistema de verica ca o de tipo, devendo ser evitado. Convers oes denidas pelo programador somente s ao utilizadas implicitamente se forem n ao amb guas. Um n umero inteiro com valor 0 e convertido para false. Qualquer n umero diferente de zero e convertido para true. M etodos de convers ao podem ser virtuais. A biblioteca-padr ao utiliza m etodos de convers ao. No exemplo a seguir o operador while espera um bool (0 ou != 0), enquanto a chamada a cin > > x;, for realizada corretamente; cin e convertido em true, se cin > > x; falha, cin e convertido em false. Exemplo: while( cin > > x ) cout < < "objeto :" < < x < < " lido."; Tente ocultar do usu ario o uso de cast. Segundo [Lischner, 2003], um lvalue e convertido automaticamente para rvalue, se o contexto requer um rvalue. Um valor de uma enumera ca o e convertido automaticamente para int, mas um int n ao e convertido automaticamente para uma enumera ca o. Para converter um int para uma enumera ca o usamos static_cast<>. Veja exemplo na listagem G.2. Um m etodo de convers ao em uma classe-derivada n ao oculta um m etodo de convers ao em uma classe-b asica, a menos que os dois m etodos convertam para o mesmo tipo. Seja cauteloso com o uso de convers oes impl citas, pois elas podem funcionar de modo inesperado. Ou seja, use explicit e evite surpresas. Reduza o n umero de m etodos construtores utilizando argumentos pr e-denidos. Com a palavra-chave explicit, o construtor s o ser a chamado de forma expl cita. Sempre testar o ponteiro ap os o dynamic_cast<>. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

470

25.11. RESUMO DO CAP ITULO

Se o ponteiro for const, voc e deve utilizar const_cast<>. Pode-se reduzir o uso de dynamic_cast<> (que e lento), incluindo-se na classe-base o m etodo que desejamos acessar. Se a classe destino for privada ou protegida, o dynamic_cast<> falha. Observe que voc e n ao deve usar RTTI com o tipo void*. Prera dynamic_cast<> a typeid(). O tempo de processamento para vericar um dynamic_cast<> (ou typeid()) e maior que o usado para localizar um m etodo virtual. Se numa hierarquia voc e tiver classes duplicadas, bases virtuais acess veis por mais de um caminho, deve vericar se o cast desejado n ao e amb guo. Se for amb guo, o dynamic_cast<> retorna 0 (ou bad_cast). Um cast para classe-derivada e chamado dowcast, e para classe-base upcast. 3 Para converter da classe C para a classe H (sendo H n ao herdeira de C), deve-se criar uma fun ca o de convers ao dentro da classe C, e declarar como friend dentro de H. 3 Convers oes impl citas e fun co es friend n ao podem ser criadas com refer encias simples (&). Exemplo: friend ...return X& ; // Erro // Mas podem ser criados para friend...return ...const X& ; friend....return...X;

25.11

Resumo do cap tulo

Neste cap tulo entendemos a necessidade das convers oes. Aprendemos os diferentes prot otipos para realizar convers oes entre objetos. Vimos que podemos realizar convers oes com construtores e com m etodos de convers ao. Vimos ainda que o construtor de convers ao pode ser utilizado para criar objetos novos a partir de objetos de diferentes tipos. Aprendemos a utilizar o operador de convers ao para converter um objeto existente para outros tipos. Eliminamos as convers oes autom aticas nos construtores com o uso de explicit. Aprendemos ainda a utilizar os operadores de convers ao: static_cast<>, const_cast<> e reinterpret_cast<>. Aprendemos a criar um ponteiro para uma classe herdeira da classe-base a partir de um ponteiro para classe-base usando dynamic_cast<>.

25.12

Exerc cios

1. Tente descrever exemplos pr aticos onde o uso de convers oes e importante. 2. Implemente os exemplos da se ca o 25.2, e veja as mensagens de erro. 3. Modique a listagem 25.2. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

25.12. EXERC ICIOS 4. Ampliar a hierarquia da listagem 25.3. 5. Monte um exemplo para convers ao de moedas de diferentes pa ses.

471

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

472

25.12. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 26

Exce c oes
Neste cap tulo apresentaremos os conceitos b asicos e a utiliza ca o de exce co es. Como ca a seq u encia de controle em um programa com exce co es. Iniciamos com uma introdu ca o ` as exce co es (se ca o 26.1). A seguir veremos o prot otipo para exce co es (se ca o 26.2), e seus conceitos b asicos de exce co es (se ca o 26.3), como o uso de try (se ca o 26.3.1), throw (se ca o 26.3.2) e catch (se ca o 26.3.3). Veremos ainda uma lista com as exce co es-padr ao (se ca o 26.4). A seq uencia de execu ca o do programa (se ca o 26.5), sem (se c ao 26.5.1) e com exce ca o (se ca o 26.5.2). Como ca a pilha (heap ) em um programa com exce co es (se ca o 26.6). O que ocorre com exce co es n ao tratadas (se ca o 26.7)? Na se ca o uso avan cado de exce co es (se ca o 26.8) veremos temas como: exce ca o para new (se ca o 26.8.1), controlando entrada com exce co es (se ca o 26.8.1), e uma pol tica para uso de exce co es(se ca o 26.8.1).

26.1

Introdu c ao ` as exce c oes

A utiliza ca o de exce co es permite a constru ca o de programas mais robustos, com maior toler ancia a falhas. O exemplo da listagem 26.1 mostra um problema usual em programas, a divis ao por zero. Observe na sa da que o valor de c, de acordo com o padr ao ANSI C++, e igual a inf, representando um valor muito grande (innito). Listing 26.1: Exce co es: Divis ao por zero.
1 2 3 4 5 6 7 8 9 10 11 12 13 // Uma d i v i s ~ a o por zero sem c o n t r o l e de erro # include < iostream > int main () { float a = 3.0; float b = 0.0; float c = a / b ; float d = c ; std :: cout << " a = " << a << " b = " << b << " c = a / b = " << c << " d = " << d << std :: endl ; return 0; }

[ a n d r e @ m e r c u r i o ] $ ./ a . out a =3 b =0 c = a / b = inf d = inf

473

474

26.2. PROTOTIPO PARA EXCEC OES

A solu ca o usualmente adotada para resolver este problema e algo como apresentado na listagem 26.2. Observe que embora o programa n ao tenha mais um bug, h a a necessidade de se criar um conjunto de ags e verica co es adicionais. Listing 26.2: Exce co es: Divis ao por zero com controle simples.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # include < iostream > using namespace std ; int main () { float a = 3.0; float b ; float c ;

// Uma d i v i s ~ a o por zero com c o n t r o l e de erro

cout << " Entre com b : " ; cin >> b ; cin . get () ; if ( b == 0 ) // c o n t r o l e cout << " Erro b == 0 " << endl ; else { c = a / b; cout << " c = a / b = " << c << endl ; } return 0; } bash -3.00 $ ./ a . out Entre com b :7 c = a / b = 0.428571 bash -3.00 $ ./ a . out Entre com b :0 Erro b == 0

De uma maneira geral, o controle de erros em um programa pode ser feito de duas formas. No meio do c odigo (forma usual), controlando a entrada de dados e os uxos do programa. Esta metodologia de controle deixa o c odigo mais confuso, pois o tratamento dos erros ca no meio do c odigo. Utilizando as t ecnicas de tratamento de exce co es, que permitem uma formula ca o mais robusta para o tratamento e a verica ca o de erros em um programa. O uso das t ecnicas de tratamento de exce co es e o foco deste cap tulo.

26.2

Prot otipo para exce c oes

Veja a seguir o prot otipo para uso de exce co es. Observe que o bloco try tenta executar um bloco de c odigo. Se neste bloco ocorrer algum problema, uma exce ca o e lan cada com throw. A exce ca o e capturada e tratada (processada) pelo bloco catch. Prot otipo: ... try { ... Tipo obj;... Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

26.3. CONCEITOS BASICOS DE EXCEC OES throw obj; } catch(Tipo & obj) { ...tratamento da exce ca o... }

475

26.3

Conceitos b asicos de exce c oes

Uma exce ca o e uma condi ca o excepcional que ocorre em um programa, o que exige um composta basicamente de tr tratamento especial. E es elementos: Um bloco try que cont em o bloco de c odigo a ser executado (veja se ca o 26.3.1). Uma ou mais chamadas a throw, anunciando que ocorreu a exce ca o. O throw lan ca uma exce ca o, lan ca um objeto que ser a capturado por um bloco catch (veja se ca o 26.3.2). Um ou mais blocos catch, que s ao respons aveis pelo tratamento das exce co es lan cadas com throw (veja se ca o 26.3.3). O exemplo da listagem 26.3 ilustra o processo. Neste exemplo inclu mos o tratamento de exce co es. Dentro do bloco try se b == 0, o programa lan ca uma exce ca o do tipo out_of_range. A exce ca o lan cada com throw e capturado pelo bloco catch(out_of_range). Observe que colocamos v arios blocos catch. Ou seja, podemos lan car v arios tipos de exce co es com throw e cada exce ca o lan cada deve ser capturada com o bloco catch correspondente (se ca o 26.3.3). Por exemplo, um throw domain_error; e capturado pelo catch (domain_error obj). Um throw out_of_range; e capturado pelo catch (out_of_range obj). Observe na sa da que quando b == 0, o bloco catch (out_of_range obj) e executado. Listing 26.3: Exce co es: Divis ao por zero com exce co es.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # include < iostream > # include < string > # include < exception > # include < stdexcept > using namespace std ; // Uma d i v i s ~ a o por zero com t r a t a m e n t o de e x c e c~ oes int main () { float a = 3.0; float b ; float c ; // Bloco try try { cout << " Entre com b : " ; cin >> b ; cin . get () ; if ( b == 0) // Lan ca a exce c~ a o do tipo o u t _ o f _ r a n g e throw o u t _ o f _ r a n g e ( " divis~ a o por zero " ) ; c = a / b; cout << " c = a / b = " << c << endl ; } // C a p t u r a e x c e c~ a o do tipo o u t _ o f _ r a n g e ( fora do i n t e r v a l o )

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

476
27 28 29 30 31 32 33 34 35 36 37

26.3. CONCEITOS BASICOS DE EXCEC OES

catch ( o u t _ o f _ r a n g e obj ) { cout << " Exce ca ~ o o u t _ o f _ r a n g e : " << obj . what () << endl ; } // C a p t u r a e x c e c~ a o do tipo d o m a i n _ e r r o r ( erro de d o m nio) catch ( d o m a i n _ e r r o r obj ) { cout << " Exce ca ~ o d o m a i n _ e r r o r : " << obj . what () << endl ;} // C a p t u r a q u a l q u e r tipo de exce c~ a o , devendo , // por este motivo ser o u ltimo catch . catch (...) { cout << " Ocorreu uma exce ca ~ o diferentes de o u t _ o f _ r a n g e . " ; } return 0; } bash -3.00 $ ./ a . out Entre com b :1 c = a / b = 3 bash -3.00 $ ./ a . out Entre com b :0 Exce ca ~ o o u t _ o f _ r a n g e : divis~ a o por zero

Veja a seguir a descri ca o dos tr es componentes de uma exce ca o, o uso de try (se ca o 26.3.1), throw (se ca o 26.3.2) e catch (se ca o 26.3.3)

26.3.1

try

Os blocos try podem lan car uma ou mais exce co es, lan cando diferentes tipos de objetos. Dentro do bloco try voc e pode lan car diretamente uma exce ca o com throw ou chamar m etodos - que podem ser encadeados - e que em algum momento lancem uma exce ca o com throw. Exemplo: try { M1(); M1(){ M2(); M2(){ M3(); M3(){ throw }; }; }; "erro"; }; // // // // Tenta executar o bloco que chama M1() M1() chama M2() M2() chama M3() M3() lan ca uma exce c~ ao

O lan camento de uma exce ca o por um m etodo naliza imediatamente a execu ca o do m etodo, e chama o pr oximo bloco catch que recebe o tipo de objeto lan cado. Observe que uma exce ca o permite a um m etodo ter um retorno diferente do especicado, alterando a linha de execu ca o do programa (veja se ca o 26.6).

26.3.2

throw

O throw e usado para lan car um objeto, indicando que uma exce ca o ocorreu. O uso de throw e similar a chamada de um m etodo. Se um m etodo lan ca uma exce ca o com throw, voc e pode mudar sua declara ca o, incluindo as exce co es que podem ser lan cadas. A vantagem em se declarar os tipos de exce co es que um m etodo pode lan car e que o compilador confere e impede que o m etodo lance uma exce ca o n ao declarada em seu prot otipo. Veremos exemplo na listagem 26.5. Prot otipo: retorno NomeM etodo(par ametros) throw (tipoExce ca o1, tipoExce ca o2, ...); Exemplo: // Declara c~ ao de m etodo informando a exce c~ ao que pode ser lan cada Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

26.3. CONCEITOS BASICOS DE EXCEC OES void M1() throw (out_of_range& ob); // Declara c~ ao de m etodo que pode lan car mais de um tipo de exce c~ ao void M2() throw (out_of_range& ob, string &s);

477

O throw funciona como um retorno multin vel, visto que o retorno do m etodo e diferente do especicado. De um modo geral os objetos lan cados com throw s ao const tipo&. Disparar uma exce ca o com throw fora de um bloco try provoca o encerramento do programa, executando a fun ca o terminate(). Veja se ca o 26.7. Uma exce ca o lan cada com throw e considerada tratada (encerrada), assim que entra no bloco catch. A especica ca o dos tipos de exce co es que podem ser lan cadas n ao fazem parte da assinatura do m etodo (vericada em tempo de compila ca o). Isto indica, que os mesmos s o s ao considerados na execu ca o, devendo ser evitados.

26.3.3

catch

O catch e o tratador de exce co es. O bloco catch ir a capturar o objeto lan cado com throw e realizar a os processamentos necess arios. Logo ap os o bloco try, voc e deve ter o bloco catch. Como um bloco try pode lan car mais de um tipo de exce ca o, voc e pode ter mais de um bloco catch, um para cada tipo de objeto lan cado. Exemplo: // Captura exce c~ ao do tipo string catch(string s) {......}; // Captura exce c~ ao do tipo int catch(int i) {......}; // Captura exce c~ ao do tipo domain_error (erro de dom nio) catch (domain_error obj) { cout < < "Exce c~ ao domain_error: " < < obj.what() < < endl;} // Captura exce c~ ao do tipo invalid_argument (argumento inv alido) catch (invalid_argument obj) { cout < < "Exce c~ ao invalid_argument: " < < obj.what() < < endl;} // Captura exce c~ ao do tipo out_of_range (fora do intervalo) catch (out_of_range obj) { cout < < "Exce c~ ao out_of_range: " < < obj.what() < < endl;} // Captura exce c~ ao do tipo range_error (erro no intervalo) catch (range_error obj) { cout < < "Exce c~ ao range_error: " < < obj.what() < < endl;} // Captura exce c~ ao do tipo overflow_error (n umero muito grande) catch (overflow_error obj) { cout < < "Exce c~ ao overflow_error: " < < obj.what() < < endl;} // Captura exce c~ ao do tipo underflow_error (n umero muito pequeno) catch (underflow_error obj) { cout < < "Exce c~ ao underflow_error: " < < obj.what() < < endl;} Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

478

26.4. EXCEC OES-PADR AO // Trata qualquer tipo de exce c~ ao (deve ser o ultimo catch) catch(...) {......};

Observe que o bloco catch s o e executado se tiver sido lan cada uma exce ca o com throw. Se foi lan cado um objeto do tipo T, o bloco catch a ser executado e aquele que trata um objeto do tipo T. Um grupo de tratamento catch se assemelha a um if..else encadeado. Um catch pode receber um objeto, uma refer encia a um objeto, um objeto constante ou um ponteiro para um objeto. Como um catch(...) trata qualquer tipo de exce ca o, este deve ser o u ltimo catch. Observe ainda que como catch(...) n ao recebe nenhum objeto, n ao tem muita ec acia. Dentro de um bloco catch, voc e pode relan car a exce ca o chamando apenas throw.

26.4

Exce c oes-padr ao

Veremos a seguir algumas exce co es-padr ao do C++. As mesmas est ao listadas nos arquivos de cabe calho <exception> e <stdexcept> (veja Figura 26.1). Estas exce co es s ao lan cadas automaticamente pelo sistema. Por exemplo, se ocorre uma falha de aloca ca o uma exce ca o padr ao do tipo bad_aloc e lan cada. Se o argumento de uma fun ca o e inv alido, uma exce ca o invalid_argument e lan cada. Se uma opera ca o matem atica gera um n umero muito grande, uma exce ca o do tipo overflow_error e lan cada. Ou seja, C++ tem um conjunto de exce co espadr ao, quando a falha ocorre, a exce ca o e lan cada. Exce co es: bad_alloc (falha aloca ca o), bad_cast (falha convers ao), bad_typeid (falha verica ca o de tipo), bad_exception (falha de exce ca o). Para indicar erros l ogicos: invalid_argument (argumento inv alido), lenght_error (dimens ao errada), out_of_range (fora do intervalo), domain_error (fora do dom nio). Para indicar erros em tempo de execu ca o: overflow_error (n umero muito grande), underflow_error (n umero muito pequeno), range_error (erro em opera co es matem aticas). Observe que as exce co es padr ao formam uma hierarquia. Da mesma forma, voc e pode criar hierarquias de classes que far ao o tratamento das exce co es lan cadas. Assim, o c odigo para tratamento de erro pode ser reaproveitado. Outra vantagem e que a declara ca o do m etodo que lan ca a exce ca o pode conter apenas a classe base da hierarquia de exce co es, veja o prot otipo. Prot otipo: retorno NomeM etodo(par ametros) throw (nomeClasseBase);

26.5

Sequ c ao encia de execu

A seq u encia de execu ca o do programa pode ser normal, isto e, sem ocorr encia de exce co es (se ca o 26.5.1) ou com ocorr encia de exce ca o (se ca o 26.5.2). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

26.6. COMO FICA A PILHA ( HEAP)

479

Figura 26.1: Hierarquia de exce co es-padrao.


exception
+<exception>

logic_error
+<stdexcept>

bad_alloc
+<new>

bad_cast
+<typeinfo>

bad_exception
+<exception>

bad_typeid
+<typeinfo

ios_base::failure
+<ios>

out_of_range
+<stdexcept>

lenght_error
+<stdexcept>

invalid_argument
+<stdexcept>

domain_error
+<stdexcept>

runtime_error
+<stdexcept>

underflow_error
+<stdexcept>

overflow_error
+<stdexcept>

range_error
+<stdexcept>

26.5.1

Sequ c ao sem exce c ao encia de execu

No exemplo ilustrado na Figura 26.2, quando n ao ocorre nenhuma exce ca o, a seq u encia executada e dada pelo tem (a). Observe que como n ao ocorre a exce ca o, isto e, a linha throw B; n ao e executada. Depois do bloco try, o programa executa a linha que segue o u ltimo bloco catch, ou seja, restante do c odigo.

26.5.2

Sequ c ao com exce c ao encia de execu

No caso em que ocorre uma exce ca o a seq uencia de execu ca o e modicada, veja o tem (b) da Figura 26.2. Observe que como ocorre a exce ca o do tipo B, isto e, a linha throw B; e executada. O bloco try e encerrado na linha em que ocorre o throw, a seguir e executado o bloco catch (B) e depois a seq uencia continua em restante do c odigo.

26.6

Como ca a pilha (heap )

Quando uma exce ca o e lan cada, os objetos locais criados dentro do bloco try e os objetos din amicos alocados com auto_ptr1 s ao destru dos. A seguir, o pr oximo catch que trata a exce ca o lan cada e executado. Se este catch n ao existe no escopo do try que lan cou a exce ca o, todas as demais chamadas de m etodos que est ao penduradas na pilha e que foram inclu das neste bloco try s ao desempilhadas (desconsideradas). Releia o par agrafo anterior e veja que faz sentido, pois se houve problemas no bloco try, suas subrotinas devem ser descartadas. Veja no exemplo da listagem 26.4 que a classe Teste tem tr es m etodos: M1(), M2(), M3(). Observe que M1() chama M2() e que M2() chama M3().
1 Veremos

o uso de auto_ptr na se ca o F.5.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

480

26.6. COMO FICA A PILHA ( HEAP)

Figura 26.2: Seq u encia de execu ca o sem exce ca o (a) e com exce ca o (b).
(a) Seqncia de execuo sem exceo. (b) Seqncia de execuo com exceo.

exceo = false; int main() { try { ..diversos.. if(exceo) trow B; ... } catch(A) {...} catch (B) {...} catch (C) {...} restante do cdigo... ... }

exceo = true; int main() { try { ..diversos.. if(exceo) trow B; ... } catch(A) {...} catch (B) {...........} catch (C) {...} restante do cdigo... ... }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

26.6. COMO FICA A PILHA ( HEAP)

481

Observe que dentro de main(), n ao existe uma linha throw, a linha com throw ca dentro de M3(). Veja na sa da a execu ca o com e sem exce ca o. Observe que quando o usu ario selecionou a op ca o 0, sem exce ca o, a seq u encia executada e a normal. Quando o usu ario seleciona a op ca o 1, a exce ca o e lan cada dentro de M3(), n ao retornando para M3(), M2() e M1() (n ao escreve Fim M3, Fim M2, Fim M1). Ou seja, os retornos dos m etodos M3(), M2() e M1() s ao retirados da pilha e desconsiderados. Listing 26.4: Exce co es e desempilhamento.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 # include < iostream > # include < stdexcept > # include < string > using namespace std ; class Teste { public : void M3 ( int resp ) { cout << " In cio M3 . " << endl ; if ( resp == 1) throw ( string ( " M e todo 3 " ) ) ; cout << " Fim M3 . " << endl ; } void M2 ( int resp ) { cout << " In cio M2 . " << endl ; M3 ( resp ) ; cout << " Fim M2 . " << endl ; } void M1 ( int resp ) { cout << " In cio M1 . " << endl ; M2 ( resp ) ; cout << " Fim M1 . " << endl ; } }; int main () { int resp ; cout << " \ nDeseja executar sem exce ca ~ o (0) ou com exce ca ~ o (1) : " ; cin >> resp ; cin . get () ; Teste obj ; try { obj . M1 ( resp ) ; } catch ( string s ) { cout << " \ nOcorreu Exce ca ~ o no M e todo : " << s << endl ; } return 0; } [ b u e n o @ l d s c 0 5 ] $ ./ a . out Deseja executar sem exce ca ~ o (0) ou com exce ca ~ o (1) :0 In cio M1 .

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

482
In cio M2 . In cio M3 . Fim M3 . Fim M2 . Fim M1 .

TRATADAS 26.7. EXCEC OES NAO

[ b u e n o @ l d s c 0 5 ] $ ./ a . out Deseja executar sem exce ca ~ o (0) ou com exce ca ~ o (1) :1 In cio M1 . In cio M2 . In cio M3 . Ocorreu Exce ca ~ o no M e todo : M e todo 3

26.7

Exce c oes n ao tratadas

As exce co es n ao tratadas terminam a execu ca o do programa. Quando uma exce ca o e lan cada e n ao capturada, as seguintes fun co es s ao executadas: unexpected(), que chama terminate(), que chama abort(), que naliza o programa. Voc e pode criar suas pr oprias fun co es unexpected() e terminate(), e substituir as default com as fun co es set_terminate() e set_unexpected(). Veja o exemplo a seguir. Exemplo: // Cria uma fun c~ ao sem retorno e sem par^ ametro void minhaFuncaoTerminate() { std::cerr < < "Programa encerrado, a exce c~ ao n~ ao foi capturada\n"; }; // Define como terminate set_terminate(minhaFuncaoTerminate); Veja exemplo na listagem 26.5. Observe que a fun ca o Teste(), lan ca uma exce ca o n ao declarada. Comprovando que o controle das exce co es lan cadas e feito em tempo de execu ca o e n ao de compila ca o. Listing 26.5: Usando set_unexpected() e set_terminate().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # include < iostream > # include < exception > # include < stdexcept > using namespace std ; // Fun c~ a o de teste da lista de e x c e c~ oes void Teste () throw ( string ) { throw 5; // N~ ao inclu d a na l i s t a g e m de throw , vai chamar u n e x p e c t e d } void M i n h a F u n c a o U n e x p e c t e d () { cerr << " Minha fun ca ~ o unexpected foi chamada porque Teste () \ n " << " lan c a uma exce ca ~ o n~ a o inclu da em sua lista .\ n " ; } void M i n h a F u n c a o T e r m i n a t e () { cerr << " Minha fun ca ~ o terminate foi executada .\ n " ; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

26.8. EXCEC OES - USO AVANCADO


22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

483

int main () { cout << " Este programa compila , mas ocorre um erro na execu ca ~ o .\ n " << endl ; // Posso d e f i n i r a fun c~ a o u n e x p e c t e d a ser e x e c u t a d a . u n e x p e c t e d _ h a n d l e r old = s e t _ u n e x p e c t e d ( M i n h a F u n c a o U n e x p e c t e d ) ; // Posso d e f i n i r a fun c~ a o t e r m i n a t e a ser e x e c u t a d a set_terminate ( MinhaFuncaoTerminate ); try { // Inicia bloco try

Teste () ; } catch ( string ) { cerr << " Exce ca ~ o para string ocorreu . " ; } cout << " fim do programa " ; return 0; } Este programa compila , mas ocorre um erro na execu ca ~o . Minha fun ca ~ o unexpected foi chamada porque Teste () lan c a uma exce ca ~ o n~ a o inclu da em sua lista . Minha fun ca ~ o terminate foi executada . Abortado

26.8

Exce c oes - Uso avan cado

Veremos nesta se ca o o uso avan cado de exce co es.

26.8.1

Exce c ao para new2

O operador new foi apresentado na se ca o 15.3.1 e a sobrecarga de new na se ca o 21.8. De uma maneira geral new tenta alocar a mem oria solicitada; Nas vers oes antigas de C++, quando new falhava retornava o ponteiro 0 (NULL) . Nos novos compiladores (Ansi C++), quando new falha, em vez de retornar 0, lan ca uma exce ca o do tipo bad_alloc (throw(bad_alloc)). Se o programa n ao tiver tratamento para exce ca o lan cada, o mesmo e encerrado (veja se ca o 26.7). Veja na listagem 26.6 um exemplo. O programa dene uma estrutura s. A seguir, dentro de main(), cria um vetor. No bloco do for innito, aloca uma estrutura dinamicamente e acrescenta-a ao vetor. Quando a mem oria de seu computador terminar, ocorre uma exce ca o do tipo bad_alloc, e o bloco catch (bad_alloc) e executado. Note que a sa da depende da quantidade de mem oria de seu computador. Listing 26.6: Exce ca o para new.
1 2 3 4 5 6 7 # include < iostream > # include < new > # include < vector > # include < stdexcept > using namespace std ; // Define uma e s t r u t u r a

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

484
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 struct S { int indicador [50000]; double valor [50000]; }; int main () { vector < S > v ; try {

26.8. EXCEC OES - USO AVANCADO

// Cria vetor para a r m a z e n a r // e s t r u t u r a s do tipo S // Uso de try

long int i = 0; for (;;) // Um for i n f i n i t o { S * ptr_s = new S () ; // Aloca m e m oria v . push_back (* ptr_s ) ; // A d i c i o n a no vetor cout << " \ nv [ " << i << " ] alocada " << endl ; i ++; } } catch ( bad_alloc erro ) // T r a t a m e n t o de erro { cout << " \ nExce ca ~ o " << erro . what () << endl ; } } ... v [8190] alocada v [8191] alocada Exce ca ~o St9bad_alloc

Se quiser desativar a chamada da exce ca o para new, use a palavra-chave nothrow. Exemplo: S* ptrS = new (nothrow) S(); Voc e pode criar uma fun ca o f() para tratar a aloca ca o com new, esta deve receber e retornar um void e pode ser ativada com set_new_handler(f). Como voc e redeniu o tratamento para new, a exce ca o para new deixa de ser lan cada e sua fun ca o f() e executada.

26.8.2

Controlando entrada com exce c oes2

No exemplo da listagem 26.7, usamos exce co es para controle da entrada e sa da de dados. Observe que ativamos as exce co es para erros com cin e cout. Isto e, se ocorrer um erro de entrada/sa da, uma exce ca o ser a lan cada e tratada. Observe na sa da que as palavras aparecem ordenadas. Nota: o uso de map ser a descrito no Cap tulo 34 - Os Containers Associativos <set>, <multiset>, <map> e <multimap>. Um map armazena uma chave e um valor. Neste exemplo usamos a palavra como um ndice que e utilizado para acessar o map e a seguir incrementar o contador associado a palavra. Listing 26.7: Usando exce co es para controle de entrada e sa da.
1 2 3 // C o n t r o l e de e n t r a d a e saida ( p r o b l e m a s de I / O ) // A d a p t a d o de C ++ in a n u t s h e l l # include < algorithm >

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

26.8. EXCEC OES - USO AVANCADO


4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 # include # include # include # include # include # include < cstddef > < exception > < iostream > < map > < string > < utility >

485

void Saida ( const std :: pair < std :: string , std :: size_t >& p ) { std :: cout << p . first << \ t << p . second << \ n ; } int main () { using namespace std ; try { string palavra ; map < string , size_t > contador ; cin . exceptions ( ios_base :: badbit ) ; cout . exceptions ( ios_base :: badbit ) ; while ( cin >> palavra ) ++ contador [ palavra ]; ~ d a === " << endl ; cout << " ==== S a A for_each ( contador . begin () , contador . end () , Saida ) ; } catch ( ios_base :: failure & ex ) { std :: cerr << " Erro de E / S : " << ex . what () << \ n ; return 1; } catch ( exception & ex ) { std :: cerr << " Erro fatal : " << ex . what () << \ n ; return 2; } catch (...) { A o diferente de failure e exception : Disastre toral .\ n " std :: cerr << " E x c e ~ A ~ ; return 3; } return 0; } O uso de exce co ~ es e de controle de entrada e sa da facilita o d e s e n v o l v i m e n t o de softwares amig a veis e a prova de erro . O 1 a 1 amig a veis 1 controle 1 de 5 desenvolvimento 1 e 3 entrada 1 erro . 1 exce co ~ es 1 facilita 1

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

486
o 1 prova 1 sa da 1 softwares uso 1

26.9. SENTENCAS PARA EXCEC OES

26.8.3

Adotando uma pol tica para uso de exce c oes2

preciso adotar uma pol E tica clara para uso de tratamento de exce co es e esta pol tica deve ser respeitada pela equipe de desenvolvimento. Veja a seguir dicas de [Sutter, 2006], para uma pol tica de exce co es: Determine uma pol tica global de tratamento de erro para sua aplica ca o ou subsistema e a mantenha. Informe o tipo de erro. Dena como vai ser a propaga ca o dos erros. Dena como ser a o tratamento do erro (API). Escreva throw nos lugares que detectar um erro e n ao puder lidar com ele. Escreva try ou catch nos lugares que tem conhecimento suciente para tratar o erro. Finalmente e bom lembrar que todo sistema de controle de erro deve ser amplamente documentado. O que inclui tens como o que? porque? como? quando?

26.9

Senten cas para exce c oes

Somente utilize exce ca o para casos cr ticos; evite sua utiliza ca o como mais um mecanismo de programa ca o. Uma exce ca o n ao resolve os destinos do seu programa; esta tarefa ainda e sua. Os m etodos para tratamento de exce co es e aqueles de tomada de decis ao devem ser separados do c odigo num erico. Observe que em um sistema tradicional de tratamento de erros, as instru co es de tratamento de erro cam misturadas no c odigo. Com o uso de try, throw e catch, voc e separa aa rea do c odigo da area de tratamento de erros. Depois de um bloco try ou catch n ao coloque o ; (ponto-e-v rgula). A seq u encia dos catchs deve respeitar a hierarquia das classes. Preste aten ca o no exemplo a seguir, o catch da classe-derivada deve vir antes do da classe-base. Exemplo: // Errado catch(Base b) {...} catch(Derivada1 d1) catch(Derivada2 d2) // Correto catch(Derivada2 d2) catch(Derivada1 d1) catch(Base b) {...}

{...} {...} {...} {...}

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

26.9. SENTENCAS PARA EXCEC OES

487

Uma fun ca o/m etodo declarada com throw e uma fun ca o/m etodo que n ao lan ca exce co es. Se um bloco de c odigo pode estar gerando uma exce ca o, coloque-o dentro de um bloco try. Dentro de um m etodo, voc e pode declarar objetos locais, que ser ao eliminados quando do encerramento do m etodo. Mas se dentro do m etodo for lan cada uma exce ca o com throw, o m etodo n ao termina e os objetos locais n ao ser ao eliminados. Para resolver este problema, deve-se ativar a op ca o RTTI do compilador, que assegura que os objetos locais tenham seus destrutores chamados. Mesmo ativando a op ca o RTTI, somente os objetos locais que n ao s ao din amicos s ao destru dos. Objetos din amicos devem ser destru dos antes do lan camento da exce ca o, pelo programador, ou devem ser criados usando auto_ptr<> veja se ca o F.5. Voc e pode lan car uma exce ca o dentro de um construtor; se esta ocorrer, os demais objetos n ao s ao criados, deixando de ser destru dos. Se throw lan ca um const, catch deve capturar um const. Pode-se construir sequ enciar try...catch,...,try...catch.. Se voc e dispara com um throw um ponteiro ou refer encia de um objeto do tipo A, esta deve ser capturada por um catch que recebe um ponteiro ou refer encia do tipo A. Por isso, voc e conclui que um catch (void*) captura todos os lan camentos de ponteiros e deve ser o u ltimo deste tipo. Um bloco try praticamente n ao apresenta custo computacional, mas o lan camento de uma exce ca o com throw tem um custo de performance elevado, [Lischner, 2003]. Segundo [Meyers, 2005], um m etodo/fun ca o seguro deve garantir: Se ocorrer uma exce ca o todo o restante do programa continua num estado v alido (n ao ocorreram corrup co es de dados). Uma garantia forte promete que se uma exce ca o e lan cada, o estado do programa n ao e alterado. Ou seja, a chamada a fun ca o/m etodo e um processo at omico, no sentido de que se ocorrer sucesso, o mesmo e completo, e se ocorrer um fracasso, o programa n ao e alterado (como se a fun ca o nunca tivesse sido chamada). Um construtor pode incluir um bloco try, veja no exemplo a seguir o prot otipo: Exemplo: CNomeClasse(par^ ametros) try : atributo1(valor1),atributo2(valor2),... { ...c odigo do construtor... } catch () {... } A diferen ca entre as fun co es exit() e abort(), e que abort() emite uma mensagem de erro. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

488 Um destrutor n ao deve lan car exce co es.

26.10. RESUMO DO CAP ITULO

Embora um m etodo possa informar quais ser ao as exce co es que podem ser lan cadas em tempo de execu ca o, isto deve ser evitado. O motivo e simples, esta verica ca o n ao e feita em tempo de compila ca o mas em tempo de execu ca o. Ent ao, para ter mais robustes no seu c odigo, evite o uso da declara ca o da exce ca o que pode ser lan cada. Para maiores detalhes, consulte [Sutter, 2006]. Evite usar new (nothrow). Segundo [Sutter, 2006], em sistemas operacionais modernos, que utilizam mem oria virtual, a verica ca o da aloca ca o ap os o uso de new tem pouco sentido pr atico, pois, geralmente, o sistema tem mem oria. Ou ir a travar, antes de new retornar um bad_alloc, em fun ca o do excesso de pagina ca o. [Sutter, 2006] parte do princ pio de que as falhas na aloca ca o com new s ao raras. De um modo geral o problema esta em denir o que ser a feito se o sistema n ao tem mais mem oria. Note que a arma ca o acima n ao tem sentido quando falamos de programa ca o cient ca. 3 N ao e poss vel criar um ponteiro para uma fun ca o que tenha a informa ca o do tipo de exce ca o a ser lan cada usando-se typedef. Mas e poss vel criar o ponteiro diretamente, sem o typedef. Veja o exemplo. Exemplo: typedef void (*pf)()throw(C1,C2,..); // Erro void (*pf)()throw(C1,C2,..); // ok pf = f; // ok Veja na se ca o ?? a utiliza ca o da instru ca o assert.

26.10

Resumo do cap tulo

A quest ao do tratamento de exce co es esta diretamente associada ao controle da execu ca o do programa. O que fazer quando o usu ario entra com um dado errado? o que fazer se a mem oria do sistema acabou? o que fazer se um dispositivo, como o disco r gido come ca a apresentar problemas? Vimos que o controle das exce co es pode ser feito no meio do c odigo, m etodo antigo, ou utilizando o conceito de exce co es, m etodo novo. A vantagem do uso de exce co es e que o tratamento das condi co es de erro e separado do processamento normal, al em disso, a biblioteca padr ao j a fornece um conjunto de classes para os tratamentos mais comuns de erros. Iniciamos o cap tulo com uma introdu ca o ` as exce co es. Vimos os conceitos b asicos de exce co es , o uso de try, throw e catch. A seq uencia de execu ca o do programa, com e sem exce co es. Como ca a pilha (heap ). O que ocorre com exce co es n ao tratadas, exce ca o para new e uma lista com as exce co es-padr ao. Dica: releia os exemplos apresentados com aten ca o, e veja que o uso de exce co es e simples.

26.11

Exerc cios

1. Qual a vantagem do uso de exce co es? Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

26.11. EXERC ICIOS 2. No seu cotidiano, qual tipo de programa pode se beneciar do uso de exce co es? 3. Acrescentar a listagem 26.1 ocorr encias de outros tipos de erros. 4. Reveja o exemplo da listagem 22.7. 5. Modique a listagem 26.3, acrescentando novos tipos de lan camentos com throw. 6. Na listagem 26.4 coloque um coment ario no bloco catch e veja o que acontece. 7. Acrescentar no exerc cio anterior uma fun ca o terminate() (veja se ca o 26.7). 8. Monte exerc cio que use set_new_handler(f). 9. Modique as listagens da se ca o 19.6, acrescentando o uso de exce co es.

489

10. Modique a listagem 26.6, substituindo S *ptr_s = new S(); por S* ptr_s = new (nothrow) S();. 11. Na listagem 26.5, modique as fun co es MinhaFuncaoUnexpected() e MinhaFuncaoTerminate(). 12. Modique a listagem 26.6, retire a linha try() e veja o que acontece. 13. No exerc cio anterior, acrescente uma fun ca o f() para tratar a aloca ca o com new usando set_new_handler(f).

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

490

26.11. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 27

Templates ou Gabaritos
Os conceitos mais u teis e extraordin arios de C++ s ao os de classes, de polimorsmo e de templates. Veremos neste cap tulo o conceito e uso de templates. Veremos uma introdu ca o aos templates (gabaritos) (se ca o 27.1), e a seguir: Fun co es templates (se ca o 27.2): o prot otipo para fun co es templates (se ca o 27.2.1), a instancia ca o e dedu ca o de argumentos (se ca o 27.2.2), a declara ca o expl cita de fun ca o template (se ca o 27.2.3), como resolver problemas de convers oes (se ca o 27.2.4), como implementar a sobrecarga de fun ca o template (se ca o 27.2.5), como criar objetos est aticos dentro de uma fun ca o template (se ca o 27.2.6). Classes templates ou tipos param etricos (se ca o 27.3): o prot otipo para classes templates (se ca o 27.3.1), regras gerais para classes templates (se ca o 27.3.2), e o uso de argumentos pr e-denidos em classes templates (se ca o 27.3.3). No nal do cap tulo veremos algumas senten cas para templates (se ca o 27.4) e alguns exerc cios. No pr oximo cap tulo veremos: Uso avan cado de fun co es template (se ca o 28.1): especializa ca o de fun co es template (se ca o 28.1.1), o que s ao fun co es expandidas em tempo de compila ca o (se ca o 28.1.2), como mapear fun co es template utilizando especializa co es (se ca o 28.1.4), uso de typename com templates (se ca o 28.1.3). Uso avan cado de classes template (se ca o 28.2): templates dentro de classes template (se ca o 28.2.1), como especializar classes (se ca o 28.2.2). Nota: veremos neste cap tulo que a constru ca o de fun co es e classes templates podem incluir par ametros a serem denidos em tempo de compila ca o. Como as fun co es e m etodos tamb em tem seus pr oprios par ametros, a palavra par ametro teria dois usos semelhantes conceitualmente mas diferentes do ponto de vista da implementa ca o. Para facilitar o entendimento e a diferencia ca o dos par ametros de templates dos par ametros de uma fun ca o/m etodo, vamos utilizar a seguinte nomenclatura: Par ametro Refere-se aos par ametros de um m etodo/fun ca o, passados dentro de (). Argumento Refere-se ao argumento de um template, denido em tempo de compila ca o, passado dentro de <>. 491

492

AOS TEMPLATES (GABARITOS) 27.1. INTRODUC AO

27.1

Introdu c ao aos templates (gabaritos)

No Cap tulo 14 - Sobrecarga de M etodos, vericamos que a sobrecarga permite criar m etodos com mesmo nome para manipular diferentes tipos de argumentos: Exemplo: float f(float x) int f(int x) double f(double x)

{ return ( x*x ); } { return ( x*x ); } { return ( x*x ); }

Observe como as fun co es s ao semelhantes; a u nica diferen ca s ao os tipos dos par ametros e do retorno que est ao sendo tratados. No exemplo, o programador cria a fun ca o f() para float, depois para int e double. O ideal seria escrever uma fun ca o gen erica da forma: Tipo f(Tipo x) { return ( x*x ); }

Fun co es template de C++ funcionam exatamente assim. Uma fun ca o template e uma fun ca o denida para um (ou mais) tipo(s) gen erico(s) em tempo de compila ca o. No exemplo anterior, se a fun ca o f() for chamada tendo como par ametro um int, o compilador cria uma fun ca o f() para int; se o par ametro for double, o compilador cria uma fun ca o f() para double, e assim por diante. Ou seja, o compilador ir a gerar uma c opia da fun ca o f() para cada tipo para a qual ela venha a ser chamada. As fun co es template (ou gabaritos de C++) possibilitam a constru ca o de algor tmos com c odigo independente do tipo de dado a ser manipulado (Ornellas et all. (2002)). Segundo o mesmo autor, O principio de trabalho dos gabaritos e fornecer um modelo de algor tmo que e automaticamente replicado pelo compilador, em tempo de compila ca o, de forma a gerar todas as inst ancias da fun ca o necess arias para atender todas as chamadas realizadas. Assim, podemos denir que um template e um gabarito para cria ca o - em tempo de compila ca o - de classes e fun co es como inst ancias do template. A programa ca o usando o conceito de templates e conhecida como programa ca o gen erica ou metaprograma ca o, [Lischner, 2003].

27.2

Fun c oes templates

Nesta se ca o veremos como implementar o conceito de fun c oes template.

27.2.1

Prot otipo para fun c oes templates

Veja a seguir o prot otipo para fun co es templates. Observe na linha anterior ` a declara ca o do nome da fun ca o, que colocamos a palavra-chave template, seguida de <, a palavra-chave typename, os tipos gen ericos (Tipo1, Tipo2,..,Tipon) e >. Estes elementos criam os tipos gen ericos Tipo1, Tipo2,..., Tipon, que ser ao utilizados dentro do bloco da fun ca o template. Prot otipo: template<typename Tipo1,...,typename Tipon> Tipoi NomeFun ca o(Tipoi nome,...,Tipon nomen) {....// Deni ca o da fun ca o template return Tipoi; } Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

27.2. FUNC OES TEMPLATES

493

A fun ca o template do exemplo a seguir recebe um objeto do tipo T e retorna o resultado da multiplica ca o de x por x, que tamb em e um objeto do tipo T. Exemplo: template <typename T> T f(T x) { return ( x*x ); } Tudo bem, voc e ainda n ao entendeu como funciona o template. Bem, template pode ser traduzido para o portugu es como gabarito. traduzido como gabarito, mas funciona como um gabarito? Exatamente. E E como C++ implementa esses gabaritos? simples, E e como um copiar/colar inteligente. Ao encontrar a declara ca o de uma func a o template, o compilador verica se a declara ca o est a correta. Se esta estiver correta, o compilador armazena a declara ca o em um buer (na mem oria). Quando voc e chama a fun ca o declarada com o template, passando como par ametro um int, o compilador reescreve toda a fun ca o, substituindo o tipo gen erico T pelo tipo real int. O compilador faz substituir (T) por (int). Essa busca e substitui ca o e repetida para cada tipo. Veja no exemplo a seguir que o template da fun ca o T f(T x) { return x * x; } para o tipo int ap os o search(T) replace(int) resulta em int f(int obj) { return x * x; }. Exemplo: int f(int x) { return ( x*x ); }

Da mesma forma, ap os o search(T) replace(float) ca da forma Exemplo: float f(float x){ return ( x*x ); } Dica: como um template espera a deni ca o do tipo dentro de <>, e podemos ter um template recebendo outro, voc e deve incluir um espa co antes de >. Evita-se tamb em a ambiguidade com o operador > >. Veja o exemplo: Exemplo: complex< double > c; vector< complex<float> > v;

27.2.2

Inst ancias de fun c oes template e dedu c ao de argumentos

Denimos anteriormente que um objeto e uma inst ancia de uma classe. A classe e a planta para cria ca o de um ou mais objetos. Da mesma forma, um template de uma fun ca o e uma planta para implementa ca o de uma ou mais fun co es, ou seja, o template da fun ca o n ao e a fun ca o em s , apenas um prot otipo. Isto signica que para que o c odigo da fun ca o seja efetivamente escrito, a fun ca o template precisa ser instanciada. Um template da forma Exemplo: template< typename T > T f(T x) { return ( x*x ); } para ser instanciado precisa receber em tempo de compila c ao o argumento T, e o par ametro x. Ou seja Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

494 Exemplo: int x = 4; int resultado = f<int>(x);

27.2. FUNC OES TEMPLATES

note que passamos dentro de <> o argumento do template (o tipo T) e dentro de () o par ametro da fun ca o f(). No exemplo acima o compilador vai criar uma vers ao da fun ca o f() da seguinte forma: Exemplo: int f(int x) { return ( x*x ); }

note que o uso de f<int>(x);, embora seja simples e claro, inclui a necessidade de se passar o argumento <int>. Para reduzir a necessidade de digita ca o os compiladores de C++ podem, em alguns casos, deduzir automaticamento o tipo a ser passado para o template. No exemplo a seguir o tipo <int> e deduzido automaticamente. Exemplo: int x = 4; int resultado = f(x); Note que em alguns casos o template precisa receber v arios argumentos, e nem todos poder ao ser automaticamente identicados. Nestes casos os argumentos mais a esquerda precisam ser passados. Funciona de forma semelhante ao que ocorre com fun co es/m etodos com par ametros pr e-denidos (se ca o 13.6.4). Exemplo: template< typename T1, typename T2> T1 f(T1 x, T2 y) { std::cout < < x < < " " < < y < < std::endl; } .. char c = C; f(5, c); // Argumentos <int,char> identificados automaticamente Poder amos chamar f() da seguinte forma Exemplo: char c = C; f<int>(5, c); note que o argumento <int> e passado explicitamente e o argumento char e deduzido automaticamente pelo compilador. Quando a deni ca o da fun ca o gabarito apresentar v arios par ametros abstratos e houver necessidade de instanci a-los explicitamente, n ao e preciso especicar todos os tipos de dados na chamada, mas somente aqueles que puderem apresentar problemas (Ornellas et al. 2002).

27.2.3

Declara c ao expl cita de fun c ao template

Vimos que a fun ca o template s o ser a implementada para inteiros quando o compilador encontrar uma chamada da fun ca o que utilize inteiros. Se voc e deseja que uma fun ca o template tenha obrigatoriamente uma vers ao para inteiros, basta declarar explicitamente a fun ca o para inteiros. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

27.2. FUNC OES TEMPLATES Exemplo: int f(int); // Declara c~ ao explicita da fun c~ ao f() para int

495

Observe que voc e est a apenas declarando a fun ca o; sua deni ca o ser a dada automaticamente pelo compilador, tendo como base a deni ca o da fun ca o template. No exemplo a seguir, criamos um operador < < utilizando um tipo gen erico T. A seguir, instanciamos o operator< < para o tipo efetivo int, depois para float e depois para char. Observe nesse exemplo que o segundo argumento const int size n ao muda. Exemplo: // Defini c~ ao da fun c~ ao template template < typename T > void operator< <(const T * vetor, const int size) { for ( int i = 0; i < size; i++ ) cout < < vetor[i] < < endl; } // Declara c~ ao expl cita da fun c~ ao operator< <() para int, float e char* void operator< <(const int* vetor, const int size); void operator< <(const float*vetor, const int size); void operator< <(const char** vetor, const int size);

27.2.4

Resolvendo problemas de convers oes

Quando uma chamada a uma fun ca o template n ao puder ser resolvida pelas convers oes padr oes (ou do usu ario), voc e precisa informar explicitamente a vers ao a ser utilizada. Veja o exemplo. Exemplo: int Minimo(int x, int y) { return x < y ? x:y; } // (1)

// (2) unsigned int Minimo(unsigned int x, unsigned int y) { return x < y ? x : y; } unsigned int x = 18; unsigned int minimo = Minimo(x,19); // Ambiguidade, usar (1) ou (2)? O n umero 19 e convertido para int. Como existem duas vers oes para Minimo(), uma para int (1) e outra para unsigned int (2), o compilador ca confuso e n ao sabe qual fun ca o Minimo() chamar, causando uma ambig uidade. Voc e pode resolver este problema especicando diretamente, dentro de <> a vers ao a ser utilizada, veja exemplo abaixo. Exemplo: unsigned int minimo = Minimo< unsigned int >(x,19); // (2)

27.2.5

Sobrecarga de fun c ao template

Se voc e deseja que uma fun ca o tenha o mesmo nome de uma fun ca o denida como template, mas que receba um n umero de par ametros diferente, n ao h a problema, visto que voc e est a sobrecarregando a fun ca o template. Observe, entretanto, que o n umero de par ametros de entrada deve ser diferente, sen ao o compilador vai acusar ambig uidade. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

496

27.3. CLASSES TEMPLATES OU TIPOS PARAMETRICOS Exemplo: template< typename T > T f(T a, T b) // (1) { return a + b; } template< typename T > T f(T a, T b, T c) // (2) Sobrecarga { return a + b + c; }

Note que as fun co es (1) e (2) s ao fun co es com mesmo nome, mas n umero de par ametros diferentes. Veja a seguir exemplo de uso das fun co es (1) e (2). Exemplo: int xi = 3, yi = 4, zi = 5; f(xi,yi); // Cria uma c opia da fun c~ ao float xf = 3.1, yf = 4.2, zf = 5.3; f(xf,yf); // Cria uma c opia da fun c~ ao f(xi,yi,zi); // Cria uma c opia da fun c~ ao f(xf,yf,zf); // Cria uma c opia da fun c~ ao

(1) para o tipo int (1) para o tipo float (2) para o tipo int (2) para o tipo float

Note que as fun co es s ao separadas, uma n ao interfere em nada na outra.

27.2.6

Fun c ao template com objeto est atico

Dentro de uma fun ca o template, voc e pode denir um objeto est atico do tipo T. Ao criar uma fun ca o para inteiros, cria um int est atico. Ao criar uma fun ca o para float, cria um float est atico. Esses objetos n ao se interferem, pois est ao em fun co es distintas. Exemplo: template< typename T > T f(T a, T b) { static T c = 0.0; // Vari avel T est atica, com valor pr e-definido ...resto da fun c~ ao... } Nota: veremos na se ca o 28.1 o uso avan cado de fun co es template.

27.3

Classes templates ou tipos param etricos

A id eia de funcionamento de classes templates e semelhante ao de fun co es template, mas neste caso, v arios atributos e m etodos ser ao denidos a partir dos tipos gen ericos. Ou seja, uma classe template implementa o conceito de uma classe gen erica. Uma classe que pode ser constru da para mais de um tipo, mas que tem a mesma forma (estrutura, gabarito). Uma classe template tamb em pode ser chamada de classe parametrizada ou classe gabarito. Veja a seguir o prot otipo para declarar e denir uma classe template.

27.3.1

Prot otipo para classes template

Veja a seguir o prot otipo para classes templates. Observe que na deni ca o dos m etodos da classe template e preciso especicar novamente cada tipo gen erico. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

27.3. CLASSES TEMPLATES OU TIPOS PARAMETRICOS Prot otipo: // Declara ca o da classe template template < typename Tipo1, typename Tipo2,.... > class TCNome { public: // Declara atributos Tipo1 atributo1; Tipo2 atributo2; // Declara e dene o construtor default TCNome(){....}; // Declara m etodos Tipo1 NomeM etodo(Tipo1 & obj,...); Tipo2 NomeM etodo(Tipo2 & obj,...); }; // Deni ca o dos m etodos da classe template template < typename Tipo1, typename Tipo2,.... > Tipo1 TCNome::NomeM etodo(Tipo1 & obj,...) {...} template < typename Tipo1, typename Tipo2,.... > Tipo2 TCNome::NomeM etodo(Tipo2 & obj,...) {...} // Utiliza ca o da classe template TCNome< Tipo1, Tipo2,.... > nomeObjeto;

497

27.3.2

Regras gerais para classes template

Uma das id eias b asicas do uso de templates e que o tipo gen erico T, passa a se comportar, sob certos aspectos, como sendo um argumento do template. Funcionando de forma semelhante ao par ametro de um m etodo. Isto signica que o resultado da execu ca o do programa vai depender al em das vari aveis/atributos denidos pelo usu ario, do tipo T das classes criadas e utilizadas como argumentos dos templates. Se novos tipos T forem denidos, isto e, novas classes do usu ario, os mesmos poder ao ser utilizados para instancia ca o de novas classes templates. Neste caso o programa precisa ser recompilado, e as novas classes devem ser efetivamente instanciadas. Para construir o template, para um u nico tipo gen erico T, devemos iniciar a deni ca o da classe template usando a seguinte linha. Exemplo: template <typename T> class TCNome { ..uso de T... }; Para criar um objeto da classe TCNome, devemos passar o tipo T a ser utilizado. Ou seja, T funciona como um argumento. Exemplo: TCNome<int> obj; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

498

27.3. CLASSES TEMPLATES OU TIPOS PARAMETRICOS

Se o tipo gen erico n ao for passado dentro de <>, o compilador acusa o erro Exemplo: TCNome obj; // Erro ...class template require template argument list. TCNome<> obj; // Erro ...wrong number of template arguments. Dentro da classe TCNome podemos criar criar atributos e m etodos que usam o tipo gen erico T. Exemplo: template <typename T> class TCNome { // M etodos T& Atributo1() { return atributo1; } const T& Atributo1() const { return atributo1; } // Atributos T atributo1; T atributo2; }; Para construir o template, para mais de um tipo gen erico T, devemos iniciar a deni ca o da classe template usando a seguinte linha. Exemplo: template <typename T1, typename T2, typename T3,..., typename Tn> class TCNome { ..uso de T1, T2, T3, ...Tn... }; Sempre que refer enciarmos, dentro da classe TCNome, um objeto do tipo TCNome, devemos usar TCNome<T>. Observe a forma como declaramos o operador de atribui ca o. Exemplo: template <typename T> class TCNome { public: T atributo1 , atributo2; // Construtor TCNome():atributo1(0), atributo2(0){} void IgualaAtributos() { atributo1 = atributo2; }; // Operador de atribui c~ ao TCNome<T>& operator=(const TCNome<T>& src); }; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

27.3. CLASSES TEMPLATES OU TIPOS PARAMETRICOS

499

No m etodo IgualaAtributos(), igualamos os atributos T atributo1 e T atributo2 (atributo1 = atributo2;). Mas o que acontece se o tipo a ser efetivamente utilizado n ao tiver o operador de igualdade? Neste caso, quando IgualaAtributos() for instanciada, o compilador ir a acusar o erro. Exemplo: TCNome<int> objInt; objInt.IgualaAtributos(); // ok, int tem sobrecarga para = TCNome<TEndereco> objEndereco; objEndereco.IgualaAtributos(); // Erro, TEndere co n~ ao tem o operador = Quando compilamos o arquivo de implementa ca o da classe (*.cpp), todos os atributos e m etodos s ao inclu dos no arquivo objeto (*.o). Entretanto, quando linkamos v arios arquivos para gerar um programa execut avel, somente os trechos de c odigo efetivamente utilizados s ao inclu dos no execut avel nal. Isto signica que se n ao chamarmos objEndereco.IgualaAtributos();, ent ao o c odigo abaixo ir a funcionar. Exemplo: TCNome<int> objInt; objInt.IgualaAtributos(); // ok, int tem sobrecarga para = TCNome<TEndereco> objEndereco; // ok, n~ ao vamos usar IgualaAtributos Alguns compiladores exigem que todo c odigo de uma classe template seja denido na classe .h. Exemplo // Arquivo TCNome.h // Inclui defini c~ ao da classe e dos m etodos da classe. Para estes compiladores, pode-se usar o truque abaixo. Note que o arquivo TCNome.cpp e inclu do dentro do arquivo TCNome.h, Exemplo: // Arquivo TCNome.h, defini c~ ao da classe #ifndef TCNome_h #define TCNome_h template <typename T> class TCNome { public: void M(); }; #include "TCNome.cpp" #endif O arquivo TCNome.cpp, inclui a deni ca o dos m etodos da classe: template <typename T> void TCNome<T>::M() Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

500 {

27.3. CLASSES TEMPLATES OU TIPOS PARAMETRICOS

std::cout < < "Usando m etodo M()." < < std::endl; } No Cap tulo 30 - As Classes <complex>, <bitset> e as Fun co es Matem aticas de <cmath>, descreveremos a classe template <complex>. Um objeto da classe <complex> representa um n umero complexo que pode ser constru do para n umeros float, double e long double, ou seja, se voc e quiser um n umero complexo com precis ao de float, utilize complex<float>, e se quiser um n umero complexo com precis ao de double, utilize complex<double>.

27.3.3

Argumentos pr e-denidos em classes templates

Uma classe template tamb em pode ser denida com argumentos pr e-denidos, de forma semelhante a fun co es com par ametros pr e-denidos (veja se ca o 13.6.4). Veja no prot otipo a seguir que se o Tipo2 n ao for passado, vai assumir Tipo2 = Tipo1. Prot otipo: template <typename Tipo1, typename Tipo2 = Tipo1> class TCNome {... }; Neste prot otipo, a classe TCNome pode ser constru da passando-se os dois tipos (Tipo1 e Tipo2), como no exemplo abaixo: TCNome<int, double> obj1; Ou passando-se apenas o tipo mais a esquerda (Tipo1), como em: TCNome<int> obj2; O exemplo da listagem 27.1 mostra a deni ca o de uma classe template que tem argumentos pr e-denidos. Listing 27.1: Deni ca o de classe template com argumentos pr e-denidos .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 /* * @ c o p y r i g h t ( C ) Andre Duarte Bueno , Vitor S e r a p h i m */ # include < iostream > using namespace std ; // Cria classe t e m p l a t e para p o l i n ^ omios. // Usa p a r ^ a m e t r o com valor pr e - definido , por padr~ a o size e 3 template < typename T , const int size = 3 > class TCPolinomi o { T p [ size ]; public : TCPolinom i o () ; // (1) TCPolinom i o ( const TCPolinomio <T , size > & src ) ; // (2) const int Size () { return size ;} // (3) const T & operator () ( T x ) const ; // (4) T& operator []( int i ) ; // (5) const T & operator []( int i ) const ; // (6) TCPolinomio <T , size >& operator =( const TCPolinomio <T , size > & src ) ; // (7) }; # include " C l a s s e T e m p l a t e C o m A r g u m e n t o s P r e - Definidos . cpp "

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

27.3. CLASSES TEMPLATES OU TIPOS PARAMETRICOS

501

Observe na listagem 27.2 a forma de implementa ca o dos m etodos da classe template. Note que os argumentos do template devem ser utilizados tamb em na deni ca o dos m etodos da classe (devem ser passados para cada m etodo). Isto e necess ario, mesmo quando os argumentos do template n ao s ao tipos gen ericos (no exemplo, o segundo argumento tem tipo denido, const int). Observe ainda que utilizamos o conceito de argumento com valor pr e-denido, no caso, size = 3. Listing 27.2: Deni ca o dos m etodos da classe template com argumentos pr e-denidos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 /* * @ c o p y r i g h t ( C ) Andre Duarte Bueno , Vitor S e r a p h i m M o n t a d o tendo como base tipos f l u t u a n t e s */ // (1) C o n s t r u t o r d e f a u l t template < typename T , const int size > TCPolinomio <T , size >:: TCPolinomi o () { for ( int i =0; i < size ; i ++) p [ i ] = i ;}; // (2) C o n s t r u t o r de c o pia template < typename T , const int size > TCPolinomio <T , size >:: TCPolinomi o ( const TCPolinomio <T , size > & src ) { for ( int i =0; i < size ; i ++) p [ i ] = src . p [ i ];}; // (4) S o b r e c a r g a do o p e r a d o r () // o b s e r v e que pow recebe long double template < typename T , const int size > const T & TCPolinomio <T , size >:: operator () ( T x ) const { T * y = new T (0) ; for ( int i = 0 ; i < size ; i ++) (* y ) += p [ i ] * pow ( static_cast < long double > ( x ) , i ) ; return * y ; }; // (5) S o b r e c a r g a do o p e r a d o r [] template < typename T , const int size > T& TCPolinomio <T , size >:: operator []( int i ) { return p [ i ]; }; // (6) S o b r e c a r g a do o p e r a d o r [] template < typename T , const int size > const T & TCPolinomio <T , size >:: operator []( int i ) const { return p [ i ]; }; // (7) S o b r e c a r g a do o p e r a d o r = template < typename T , const int size > TCPolinomio <T , size >& TCPolinomio <T , size >:: operator =( const TCPolinomio <T , size > & src ) { for ( int i =0; i < size ; i ++) p [ i ] = src . p [ i ]; return * this ; }

Observe na listagem 27.3 a forma de uso dos m etodos da classe template. Listing 27.3: Usando a classe template com argumentos pr e-denidos.
1 2 3 4 5 6 # include < cmath > # include < iostream > using namespace std ; # include " C l a s s e T e m p l a t e C o m A r g u m e n t o s P r e - Definidos . h " // Usando a classe T C P o l i n o m i o

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

502
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

27.3. CLASSES TEMPLATES OU TIPOS PARAMETRICOS

int main () { const int size = 3; int x = 5; cout << " x = " << x << endl ; cout << " Criando polin^ o mio TCPolinomio < int > pInt1 ; " << endl ; TCPolinomio < int > pInt1 ; // (1) cout << " C o e f i c i e n t e s de pInt1 = " ; for ( int i =0; i < size ; i ++) cout << pInt1 [ i ] << \ t ; // (5) cout << endl ; cout << " pInt1 ( x ) = " << pInt1 ( x ) << endl ; // (3) int r = pInt1 [0]; cout << " r = " << r << endl ; const int rc = pInt1 [0]; cout << " rc = " << rc << endl ; // (5) // (6)

cout << " Criando polin^ o mio TCPolinomio < int > pInt2 ; " << endl ; TCPolinomio < int , size > pInt2 ( pInt1 ) ; // (2) pInt2 [0] = 1; cout << " C o e f i c i e n t e s de pInt2 = " ; for ( int i =0; i < size ; i ++) cout << pInt2 [ i ] << \ t ; // (5) cout << endl ; cout << " pInt2 ( x ) = " << pInt2 ( x ) << endl ; // (3) cout << " \ nCriando polin^ o mio TCPolinomio < int , size > pInt3 ( pInt2 ) ; " " usa construto r copia " << endl ; TCPolinomio < int , size > pInt3 ( pInt2 ) ; // (2) cout << " C o e f i c i e n t e s de pInt3 = " ; for ( int i =0; i < size ; i ++) cout << pInt3 [ i ] << \ t ; // (5) cout << endl ; cout << " \ nIgualand o polin^ o mios pInt1 = pInt2 ; " << endl ; pInt1 = pInt2 ; // (7) cout << " C o e f i c i e n t e s de pInt1 = " ; for ( int i =0; i < size ; i ++) cout << pInt1 [ i ] << \ t ; // (5) cout << endl ; cout << " \ nCriando polin^ o mio TCPolinomio < float , size > pFloat1 ; " << endl ; TCPolinomio < float , size > pFloat1 ; // (1) cout << " C o e f i c i e n t e s de pFloat1 = " ; for ( int i =0; i < size ; i ++) cout << pFloat1 [ i ] << \ t ; // (5) cout << endl ; cout << " pFloat1 ( x ) = " << pFloat1 ( x ) << endl ; // (3) // cout << " I g u a l a n d o p o l i n ^ o m i o s de tipos d i f e r e n t e s " // pInt1 = p F l o a t 1 ; // (6) // Erro return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ a . out x = 5 Criando polin^ o mio TCPolinomio < int > pInt1 ; C o e f i c i e n t e s de pInt1 = 0 1 2 pInt1 ( x ) = 55 r = 0 rc = 0

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

27.4. SENTENCAS PARA TEMPLATES


Criando polin^ o mio TCPolinomio < int > pInt2 ; C o e f i c i e n t e s de pInt2 = 1 1 2 pInt2 ( x ) = 56 Criando polin^ o mio TCPolinomio < int , size > pInt3 ( pInt2 ) ; usa construtor copia C o e f i c i e n t e s de pInt3 = 1 1 2 Igualando polin^ o mios pInt1 = pInt2 ; C o e f i c i e n t e s de pInt1 = 1 1

503

Criando polin^ o mio TCPolinomio < float , size > pFloat1 ; C o e f i c i e n t e s de pFloat1 = 0 1 2 pFloat1 ( x ) = 55

Veja outros exemplos de classes template nas listagens 33.2 e 33.4. Nota: a STL usa o mecanismo de argumentos pr e-denidos extensivamente. Por exemplo, a classe <vector> espera como argumento o tipo de objeto a ser armazenado no vetor e o tipo de alocador de mem oria a ser utilizado. Normalmente passamos apenas o primeiro argumento, isto e, o tipo do objeto a ser armazenado no container <vector>.

27.4

Senten cas para templates

N ao e aconselh avel a utiliza ca o de fun co es globais; isso tamb em e v alido para fun co es template globais. N ao crie classes com templates antes de ter total conan ca no c odigo, isto e, primeiro crie classes normais e fa ca todos os testes que forem necess arios. Lembre-se que uma fun ca o pode ter mais de uma declara ca o, mas somente uma deni ca o. O mesmo conceito e v alido para fun co es template. O conceito de friend tamb em pode ser utilizado com templates (se ca o 28.1.5). Observe que com a utiliza ca o de templates, voc e pode desenvolver programas gen ericos, com tipos gen ericos. Para diferenciar classes comuns de classes gabaritos, costuma-se colocar o nome das classes gabaritos dentro de <>, como em <complex>, <vector>. A alguns anos us avamos template<class T>, como a palavra-chave class j a e utilizada para declarar uma classe, prera typename para declarar os templates. Um template de fun ca o (ou classe) pode aceitar argumentos com tipo pr e-denido. No exemplo a seguir const int, e o tipo pr e-denido. Exemplo: template<typename T1, const int n> class TCNome{...}; // Para criar um objeto de TCNome usa-se: TCNome<double, 20> nomeObjeto; Os argumentos com tipo denido em um template (como o int n do exemplo anterior) ser ao sempre const. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

504

27.4. SENTENCAS PARA TEMPLATES

Como uma classe template e apenas reescrita para cada tipo, esta ir a aceitar heran ca de uma classe comum, heran ca de uma classe gabarito e heran ca de uma classe gabarito para uma classe comum. Veja no exemplo a seguir a deni ca o de uma classe template TCPolinomioDerivado. A mesma acrescenta uma hipot etica fun ca o de deslocamento (os coecientes do polin omio s ao deslocados). // TCPolinomioDerivado.h template<typename T, const int size = 3> class TCPolinomioDerivado: public TCPolinomio<T,size> { ... T* p; void Shift(int deslocamento); // Novidade }; // TCPolinomioDerivado.cpp #include "TCPolinomioDerivado.h" template<typename T, const int size > void TCPolinomioDerivado<T,size>::Shift(int d) { T cp[size]; for(int i = 0; i < size ; i++) cp[i] = p[i]; for(int i = 0; i < size ; i++) { if( i + d < size) p[i] = cp[i + d]; else p[i] = cp[size - i - d ] } } 2 Nas classes templates, os m etodos devem ser denidos dentro da classe, ou em arquivos .cpp (inclu dos no .h), ou ainda usando a palavra-chave export. Embora os m etodos sejam inclu dos dentro da classe, e aconselh avel o uso da palavra-chave inline quando voc e deseja que o m etodo seja em linha. 2 Na deni ca o de uma classe template podemos incluir argumentos com valores pr edenidos (como o tipo int no exemplo abaixo). Mas na implementa ca o dos m etodos da classe template somente o tipo dos argumentos devem ser denidos, os valores pr edenidos n ao. Observe no exemplo abaixo que o argumento T2 tem como valor pr e-denido o tipo int. Exemplo: template<typename T1 , typename T2 = int > class TCNome { // Declara c~ ao do construtor TCNome(T1, T2); }; Mas na deni ca o do m etodo construtor, o tipo pr e-denido n ao deve ser passado. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

27.5. RESUMO DO CAP ITULO // Defini c~ ao do construtor template<typename T1 , typename T2 TCNome<T1,T2>::TCNome(T1, T2) {};

505

>

Se o argumento pr e-denido for inclu do na deni ca o, ocorrer a erro na compila ca o, veja abaixo mensagem de erro. XXX.cpp:19: error: default template arguments may not be used in function templates

27.5

Resumo do cap tulo

Agora o leitor pode compreender as vantagens da programa ca o orientada a objeto com C++. A utiliza ca o de conceitos abstratos como classes, que permitem a cria ca o de tipos do usu ario, adequados ` a solu ca o de seus problemas, do polimorsmo, que permitem que o c odigo que altamente gen erico e pequeno, da sobrecarga de operadores, que possibilitam ao programador denir opera co es conhecidas como + - * /, e de templates, que tornam o c odigo gen erico, fazem de C++ uma linguagem de programa ca o extremamente poderosa e moderna. Neste cap tulo aprendemos a usar o conceito de fun co es e classes templates, e suas diversas varia co es. Vimos o prot otipo e o uso de fun co es template. Aprendemos que podemos estanciar explicitamente as fun co es e classes template. Como uma fun ca o template e um prot otipo, podemos implementar conceitos como argumentos pr e-denidos, sobrecarga de fun ca o template, uso de objetos est aticos. Aprendemos ainda a usar classes templates ou tipos param etricos, vimos seu prot otipo e um conjunto de regras para uso de classes templates. Classes template tamb em podem ter argumentos pr e-denidos. Dica: a biblioteca STL utiliza extensivamente o conceito de templates, veja Cap tulo 31 Introdu ca o a Biblioteca Padr ao de Gabaritos de C++.

27.6

Exerc cios

1. Transformar a hierarquia da classe CPonto em uma hierarquia de classes template. O tipo T dos valores de x, y, r1, r2 deve poder ser int, float, double, long double. 2. O exemplo que usa o m etodo Shift() na se ca o 27.4, pode ser otimizado, substitua o vetor cp por uma vari avel tempor aria. 3. No exemplo da listagem 27.1, incluir sobrecarga para operador< < e operador> >. Fa ca com que na sa da o polin omio seja escrito da forma: y = p[0] + p[1]x + p[2]x 2 + .... Dica: veja maiores detalhes de templates na refer encia Nicolai M. Josuttis e David Vandevoordes, C++ Templates - The Complete Guide, [Vandevoorde and Josuttis, 2002].

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

506

27.6. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 28

Templates - Uso Avan cado


No Cap tulo 27 - Templates ou Gabaritos, vimos os conceitos b asicos de templates. Neste cap tulo veremos o uso avan cado de fun co es e classes templates. Aprenderemos como especializar classes e fun co es template. No caso das classes a especializa ca o pode ser total (a classe e inteiramente redeclarada e redenida) ou parcial (apenas alguns membros existentes na declara ca o original s ao redenidos). Uma fun ca o s o pode ser inteiramente redenida. Uso avan cado de fun co es template (se ca o 28.1), especializa ca o de fun co es template (se ca o 28.1.1), o que s ao fun co es expandidas em tempo de compila ca o (se ca o 28.1.2), uso de typename com templates (se ca o 28.1.3), como mapear fun co es template utilizando especializa co es (se ca o 28.1.4), Fun co es template e friend (se ca o 28.1.5). Uso avan cado de classes template (se ca o 28.2) templates dentro de classes template (se ca o 28.2.1), como especializar classes (se ca o 28.2.2), a instancia ca o de classes template (se ca o 28.2.3). Uso de export com templates (se ca o 28.3). Nota: este cap tulo e destinado a usu arios avan cados de C++. Numa primeira leitura deste livro o mesmo pode ser pulado sem perda de sequ encia.

28.1

Fun c oes template uso avan cado

Nesta se ca o veremos o uso avan cado de fun co es template.

28.1.1

Especializa c ao de fun c oes template

Como vimos, um template de fun ca o ou classe e uma deni ca o gen erica. A quest ao e, esta deni ca o geral e v alida em todas as situa co es? Em algumas situa co es, um dado template funcionar a para a maioria dos tipos e falhar a para um tipo espec co. Vamos a um exemplo, uma fun ca o Menor() da forma: 507

508 Exemplo: template < typename Tipo > bool Menor(Tipo obj1, Tipo obj2) { return obj1 < obj2; }

28.1. FUNC OES TEMPLATE USO AVANCADO

Funcionar a para int, float e double, e falhar a para char* (cstring). Pois para comparar uma cstring devemos utilizar a fun ca o strcmp()1 da biblioteca de C. Neste caso, poderemos criar uma especializa ca o para a fun ca o template. A especializa ca o ir a tratar especicamente do caso de char*. Observe no exemplo a seguir o uso de template<> sem argumentos e ap os o nome da fun ca o o tipo especializado dentro de <, ou seja, < const char* >. Exemplo: // Especializa c~ ao de Menor para o tipo const char* template<> bool Menor< const char* >(const char* cstring1,const char* cstring2) { return strcmp(cstring1,cstring2) < 0; } A especializa ca o nada mais e do que a redeni ca o da fun ca o/classe template para um tipo espec co. Veja a seguir prot otipo para especializa ca o de fun ca o template. Prot otipo: template<> Retorno NomeFun ca o < TipoEspecializado > (par ametros) { ...fun ca o em s ... } Note que a fun ca o especializada pode ser totalmente diferente da original. Veja exemplo na listagem 28.1. Embora fun co es template possam ser especializadas, seu uso deve ser evitado, por quest oes de robustes e portabilidade do sistema. [Sutter, 2006], apresenta exemplos em que o uso de fun co es template especializadas apresenta problemas apenas em fun ca o da ordem em que as mesmas foram declaradas. Isto ocorre em fun ca o da ordem em que as fun co es s ao consideradas na avalia ca o da chamada da fun ca o: i) primeiro s ao chamadas as fun co es sem template, ii) a seguir s ao chamadas as fun co es com template, iii) em terceiro lugar s ao consideradas as fun co es com template que foram especializadas. A solu ca o para este problema e simples, como fun co es comuns se encaixam em (i), em vez de especializar a fun ca o template para um tipo X, reescreva a fun ca o para o tipo X usando uma fun ca o comum (n ao template). Outro problema do uso de especializa co es de fun co es template e que eles viabilizam a quebra do encapsulamento da classe. Pois se temos uma fun ca o template f, um outro programador - com m as inten co es - sempre poder a especializar a fun ca o por n os denida para uma tipo denido por ele (uma classe criada por ele). Como a fun ca o especializada ser a reescrita pelo outro programador, o mesmo poder a acessar atributos e m etodos privados da classe, pois a fun ca o especializada esta no mesmo escopo da classe. Veja maiores detalhes em [Sutter, 2006].
1 A fun ca o strcmp() e uma fun ca o de C que compara duas strings no formato const char*. Veja Ap endice K - Arquivos de Cabe calho.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

28.1. FUNC OES TEMPLATE USO AVANCADO

509

Apresentam-se a seguir dois exemplos de otimiza ca o de programas utilizando-se conceitos avan cados de templates.

28.1.2

Fun c oes expandidas em tempo de compila c ao

Voc e pode utilizar templates e especializa ca o de templates para criar fun co es que s ao expandidas em tempo de compila ca o. No exemplo da listagem 28.1, a fun ca o f<>() tem como argumento um int N e chama a si mesma passando N-1 (chamadas recursivas). Quando N = 0, chama a vers ao especializada da fun ca o f<>(), que termina o processo recursivo. Observe que a fun ca o f<>() e criada em tempo de compila ca o pela expans ao recursiva da fun ca o template. Este mecanismo torna a fun ca o muito r apida, pois elimina a chamada recursiva. A contrapartida e o aumento do tamanho do programa execut avel. Observe na sa da que os valores aparecem na ordem 0,1,2....,10, pois colocamos cout < < N= < < N < < \t; depois da chamada de f<N-1>();. Listing 28.1: Exemplo de fun ca o expandida em tempo de compila ca o.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # include < iostream > using namespace std ; // Fun c~ ao template recursiva template < int N > void f () { f <N -1 >() ; // Recurs~ a o , chama a si mesma cout << " N = " << N << \ t ; } // E s p e c i a l i z a c~ a o da fun c~ a o t e m p l a t e para o tipo int == 0 template < > void f <0 >() { cout << " N = " << 0 << \ t ; // Aqui f i n a l i z a a r e c u r s ~ ao } int main () { f <10 >() ; cout << endl ; return 0; } bash -3.00 $ ./ a . out N =0 N =1 N =2 N =3

// Cria i n s t ^ a n c i a da fun c~ ao // t e m p l a t e com N =10

N =4

N =5

N =6

N =7

N =8

N =9

N =10

No exemplo da listagem 28.2, adaptado de [Lischner, 2003], a fun ca o Arredondar() e usada para arredondar um n umero utuante para n casas decimais, e este processo e feito em tempo de compila ca o. A fun ca o, double floor(double x);, denida no arquivo de cabe calho <cmath> (se ca o 30.1.1), retorna o maior inteiro n ao maior que x (arredonda para baixo). A estrutura power_xy<> cria uma enumera ca o cujo valor e o resultado de xy . Observe que a chamada a power_xy<> e recursiva. Note que o programa cria vers oes especializadas para x0 , 0y e 00 . Observe na sa da que o n umero 1.23456789 e arredondado para 2, 4 e 6 casas decimais. Listing 28.2: Fun ca o pot encia expandida em tempo de compila ca o.
1 2 3 // A d a p t a d o de C ++ in a n u t s h e l l de Ray L i s c h n e r # include < cmath > # include < iostream >

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

510
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

28.1. FUNC OES TEMPLATE USO AVANCADO

// Fun c~ ao template - defini c~ a o geral - x ^ y template < int x , unsigned y > struct power_xy { enum { valor = x * power_xy <x , y -1 >:: valor }; }; // Fun c~ ao template - especializa c~ a o para x ^0 template < int x > struct power_xy <x , 0 > { enum { valor = 1 }; }; // Fun c~ ao template - especializa c~ a o para 0^ y template < unsigned y > struct power_xy <0 , y > { enum { valor = 0 }; }; // Fun c~ ao template - especializa c~ a o para 0^0 template < > struct power_xy <0 , 0 > {}; // A fun c~ a o abaixo a r r e d o n d a um n u mero f l u t u a n t e // c o n s i d e r a n d o n casas d e c i m a i s template < unsigned n , typename T > T Arredondar ( T x ) { if ( x < 0.0) return std :: floor ( x * power_xy <10 , n >:: valor - 0.5) / power_xy <10 , n >:: valor ; else return std :: floor ( x * power_xy <10 , n >:: valor + 0.5) / power_xy <10 , n >:: valor ; } int main () { std :: cout << Arredondar <2 >(1.23456789) << std :: endl ; std :: cout << Arredondar <4 >(1.23456789) << std :: endl ; std :: cout << Arredondar <6 >(1.23456789) << std :: endl ; return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ a . out 1.23 1.2346 1.23457

28.1.3

Usando typename com templates

Em alguns casos, a deni ca o de um template pode ser correta, mas amb gua para o compilador. Veja o exemplo: Exemplo: template < typename T > void f( T obj ) {... Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

28.1. FUNC OES TEMPLATE USO AVANCADO T::X(par^ ametro); T::X* ptr; }

511

Se X for um tipo (uma classe aninhada de T), o comando T::X(par^ ametro) e uma chamada de construtor. Neste caso, vai criar um objeto an onimo (sem atribu -lo a algu em). Mas X tamb em pode ser uma fun ca o membro est atica. Assim, o compilador car a em d uvida: X e um tipo e devo chamar seu construtor ou X e uma fun ca o membro est atica? Da mesma forma, se X for um tipo ptr e um ponteiro para o tipo X. Se X for um atributo est atico de T, T::X *ptr; e a multiplica ca o de X por ptr. Para resolver estas ambig uidades o compilador assume por padr ao (default ) que X n ao e um tipo. Para que X seja considerado um tipo, voc e deve usar a palavra-chave typename. Veja o exemplo: Exemplo: template < typename T > void f( T obj) {... typename T::X obj(par^ ametro); } Veja outro exemplo na listagem 28.3.

28.1.4

Mapeando fun c oes template utilizando especializa c oes

Voc e pode mapear vari aveis de fun co es template utilizando especializa co es. No exemplo a seguir, uma fun ca o Media() recebe um vetor e determina a m edia de seus elementos. Exemplo: double Media (const double* vetor, int numeroElementos) { double soma = 0; for( int i = 0; i < numeroElementos; i++) soma += vetor[i]; return soma / numeroElementos; } Pode-se criar um template para esta fun ca o da forma: Exemplo: template< typename T > T Media (const T* vetor, int numeroElementos) { T soma = 0; for(int i = 0; i < numeroElementos; i++) soma += vetor[i]; return soma / numeroElementos; } Entretanto, quando a fun ca o template anteriormente denida for criada para int, ir a apresentar um erro, pois a divis ao soma / numeroElementos ser a truncada (a divis ao entre dois n umeros inteiros e sempre truncada, por exemplo 3/2 = 1). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

512

28.1. FUNC OES TEMPLATE USO AVANCADO

Pode-se resolver este problema criando-se um template de uma estrutura que inclua um typedef de um tipo T que ser a especializado para double quando o tipo T for int. O exemplo da listagem 28.3 esclarece melhor este caso. Observe que a vari avel double_trait< T > ser a do tipo correto. Se T for double, T_double ser a do tipo double, se T for int T_double tamb em ser a do tipo double. Veja na sa da que a fun ca o Media() funciona para int e para double. Listing 28.3: Exemplo de mapeamento de tipo com templates.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 # include < iostream > using namespace std ; // A e s t r u t u r a d o u b l e _ t r a i t cria um t y p e d e f para o tipo T template < typename T > struct d o u b l e _ t r a i t { typedef T T_double ; }; // E s p e c i a l i z a c~ a o da e s t r u t u r a d o u b l e _ t r a i t para int // Se o tipo T for int , T _ d o u b l e deve ser do tipo double template < > struct double_trait < int > { typedef double T_double ; }; // Uma fun c~ a o t e m p l a t e que usa a e s t r u t u r a d o u b l e _ t r a i t acima d e f i n i d a // o r e t o r n o e double_trait <T >:: T _ d o u b l e // o nome e Media // e os p a r ^ a m e t r o s const T * vetor , int n u m e r o E l e m e n t o s template < typename T > typename double_trait < T >:: T_double Media ( const T * vetor , int n u m e r o E l e m e n t o s ) { typename double_trait <T >:: T_double soma = 0; for ( int i =0; i < n u m e r o E l e m e n t o s ; i ++) soma += vetor [ i ]; return soma / n u m e r o E l e m e n t o s ; } // Usando a fun c~ a o t e m p l a t e Media () int main () { int * vetor_int = new int (4) ; for ( int i = 0; i < 4; i ++) vetor_int [ i ] = i ; double media ; media = Media ( vetor_int , 4) ; cout << " M e dia do vetor_int = " << media << endl ; delete [] vetor_int ; double * v e t o r _ d o u b l e = new double (4) ; for ( int i = 0; i < 4; i ++) vetor_double[i] = i; media = Media ( v e t o r _ d o u b l e , 4) ; delete [] v e t o r _ d o u b l e ; cout << " M e dia do v e t o r _ d o u b l e = " << media << endl ; cout << " ( int 3) /( int 2) = " << 3/2 << endl ; return 0; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

28.2. CLASSES TEMPLATE USO AVANCADO


bash -3.00 $ ./ a . out media vetor_int = 1.5 media v e t o r _ d o u b l e = 1.5 ( int 3) /( int 2) = 1

513

28.1.5

Fun c oes template e friend

Uma fun ca o template pode ser indicada como uma fun ca o amiga, veja o exemplo: Exemplo: void F_Global(); template<typename T> void G_Global(T obj); namespace N1 { template<typename T> void f(T& c) {...} } // Declara fun c~ ao global F // // // // Declara fun c~ ao template global G Define um namespace Define um template Define uma fun c~ ao dentro do namespace

class CNome{ friend void F_Global(); template<typename T> friend void G_Global(T obj); friend void N1::f(CNome&); plate como amiga ...};

// Define uma classe // F_Global() e amiga // G_Global() e amiga // Declara uma fun c~ ao tem-

Neste exemplo denimos uma fun ca o template f(), e informamos que a mesma e amiga de CNome. Embora dentro dos padr oes, alguns compiladores n ao aceitam esta declara ca o da fun ca o friend. Uma das poss veis solu co es e usar: Exemplo: // Declara uma fun c~ ao template como amiga friend void N1::f<CNome>(CNome& c);

28.2

Classes template uso avan cado

Nesta se ca o veremos o uso avan cado de classes template.

28.2.1

Templates dentro de uma classe template

A listagem 28.4 mostra a cria ca o de um m etodo template dentro de uma classe normal. Note que criamos dois m etodos, um normal e outro est atico. Listing 28.4: Problema na chamada a m etodos template.
1 2 3 4 5 6 7 8 # include < iostream > class TCNome { public : template < int n > int M () { std :: cout << " normal : "

<< n << std :: endl ; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

514
9 10 11 12 13 14 15 16 17 18 19 20

28.2. CLASSES TEMPLATE USO AVANCADO

template < int n > static int SM () { std :: cout << " estatica : " << n << std :: endl ; } }; int main () { TCNome obj ; obj . M <3 >() ; TCNome :: SM <4 >() ; return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ a . out normal :3 estatica :4

Usando as listagens 27.1 e 27.2 podemos criar objetos polin omios usando int, float, etc. Podemos igualar objetos. Exemplo: TCPolinomio< int > TCPolinomio< int > p1Int = p2Int; p1Int; p2Int; // Cria polin^ omio para tipo inteiro // Cria polin^ omio para tipo inteiro // ok, iguala polin^ omios

Mas se em algum momento quis essemos igualar dois polin omios com tipos diferentes, ter amos um erro. O erro ocorre mesmo tendo implementado o operador igualdade, pois o mesmo e v alido para TCPolinomio< int > = TCPolinomio< int > ou TCPolinomio< float > = TCPolinomio< float >. Mas n ao pode ser usado para pFloat = pInt;. Observe na listagem 27.2, no nal da fun ca o main(), que colocamos o seguinte c odigo: Exemplo: TCPolinomio< float,size > pFloat; // pInt1 = pFloat1; // Cria polin^ omio para tipo float // Erro, tipos diferentes

Se retirarmos o coment ario da linha // pInt1 = pFloat1;, o compilador ir a apresentar a mensagem de erro apresentada na listagem ??.
[ b u e n o @ l d s c 0 5 Parte - II ] $ g ++ T e m p l a t e s C o m E r r o . cpp : In function int main () : :102: error : no match for operator = in pInt1 = pFloat1 :44: note : candidates are : TCPolinomio <T , size >& TCPolinomio <T , size >:: operator =( const TCPolinomio <T , size >&) [ with T = int , int size = 3] : In member function const T & TCPolinomio <T , size >:: operator () ( T ) const [ with T = int , int size = 3] : :63: i n s t a n t i a t e d from here :27: warning : converting to int from long double

Para resolver este problema, devemos criar uma camada adicional de template. Um template extra dentro da deni ca o da classe TCPolinomio, veja exemplo nas listagens 28.5 e 28.6. Observe no nal da deni ca o da classe TCPolinomio, a inclus ao de um construtor de c opia e de um operador de atribui ca o. Listing 28.5: Deni ca o de classe template com template adicional.
1 2 3 4 /* * Inclui t e m p l a t e s a d i c i o n a i s */ // Cria classe t e m p l a t e para polinomios , // Usa p a r ^ a m e t r o com valor pr e - definido , por padr~ a o size e 3 template < typename T , const int size = 3 >

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

28.2. CLASSES TEMPLATE USO AVANCADO


5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class TCPolinom io { T p [ size ]; public : TCPolinom i o () ; // (1) TCPolinom i o ( const TCPolinomio <T , size > & src ) ; // (2) const int Size () { return size ;} // (3) const T & operator () ( T x ) const ; // (4) T& operator []( int i ) ; // (5) const T & operator []( int i ) const ; // (6) TCPolinomio <T , size >& operator =( const TCPolinomio <T , size > & src ) ; // (7) // C o n s t r u t o r de c o pia - T e m p l a t e a d i c i o n a l template < typename E > TCPolinom i o ( const TCPolinomio <E , size > & src ) ; // (8) // O p e r a d o r de a t r i b u i c~ ao - Template adicional template < typename E > // (9) TCPolinomio <T , size >& operator =( const TCPolinomio <E , size > & src ) ; }; # include " T e m p l a t e C o m T e m p l a t e A d i c i o n a l . cpp "

515

Listing 28.6: Implementa ca o dos m etodos da classe template com template adicional.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 // (1) C o n s t r u t o r d e f a u l t template < typename T , const int size > TCPolinomio <T , size >:: TCPolinomi o () { for ( int i = 0; i < size ; i ++) p [ i ] = i ;}; // (2) C o n s t r u t o r de c o pia template < typename T , const int size > TCPolinomio <T , size >:: TCPolinomi o ( const TCPolinomio <T , size > & src ) { for ( int i = 0; i < size ; i ++) p [ i ] = src [ i ];}; // (4) S o b r e c a r g a do o p e r a d o r () // o b s e r v e que pow recebe long double template < typename T , const int size > const T & TCPolinomio <T , size >:: operator () ( T x ) const { T * poli = new T (0) ; for ( int i = 0 ; i < size ; i ++) (* poli ) += p [ i ] * pow ( static_cast < long double > ( x ) , i ) ; return * poli ; }; // (5) S o b r e c a r g a do o p e r a d o r [] template < typename T , const int size > T& TCPolinomio <T , size >:: operator []( int i ) { return p [ i ]; }; // (6) S o b r e c a r g a do o p e r a d o r [] template < typename T , const int size > const T & TCPolinomio <T , size >:: operator []( int i ) const { return p [ i ]; }; // (7) S o b r e c a r g a do o p e r a d o r = template < typename T , const int size > TCPolinomio <T , size >& TCPolinomio <T , size >:: operator =( const TCPolinomio <T , size > & src ) { for ( int i = 0; i < size ; i ++) p [ i ] = src [ i ];

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

516
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 return * this ; }

28.2. CLASSES TEMPLATE USO AVANCADO

// (8) C o n s t r u t o r de c o pia - T e m p l a t e a d i c i o n a l template < typename T , const int size > template < typename E > TCPolinomio <T , size >:: TCPolinom i o ( const TCPolinomio <E , size > & src ) { for ( int i = 0; i < size ; i ++) p [ i ] = src [ i ];}; // (9) O p e r a d o r de a t r i b u i c~ ao - Template adicional template < typename T , const int size > template < typename E > TCPolinomio <T , size >& TCPolinomio <T , size >:: operator =( const TCPolinomio <E , size > & src ) { for ( int i = 0; i < size ; i ++) p [ i ] = src [ i ]; return * this ; }

Veja na listagem 28.7 o uso da classe template criada. Listing 28.7: Uso de classe template com template adicional.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 # include < iostream > # include < cmath > # include " T e m p l a t e C o m T e m p l a t e A d i c i o n a l . h " using namespace std ; // Usando a classe T C P o l i n o m i o int main () { const int size = 3; int x = 5; cout << " x = " << x << endl ; cout << " Criando polin^ o mio TCPolinomio < int > pInt1 ; " << endl ; TCPolinomio < int > pInt1 ; // (1) cout << " C o e f i c i e n t e s de pInt1 = " ; for ( int i =0; i < size ; i ++) cout << pInt1 [ i ] << \ t ; // (5) cout << endl ; cout << " pInt1 ( x ) = " << pInt1 ( x ) << endl ; // (4) cout << " \ nCriando polin^ o mio TCPolinomio < float , size > pFloat1 ; " << endl ; TCPolinomio < float , size > pFloat1 ; // (1) cout << " C o e f i c i e n t e s de pFloat1 = " ; for ( int i =0; i < size ; i ++) cout << pFloat1 [ i ] << \ t ; // (5) cout << endl ; cout << " pFloat1 ( x ) = " << pFloat1 ( x ) << endl ; // (4) cout << " Igualando polin^ o mio s de tipos diferentes ... pInt1 = pFloat1 ; // (9) cout << " ... ok \ n " ; cout << " pInt1 ( x ) = " << pInt1 ( x ) << endl ; // (4) ";

return 0; } [ b u e n o @ l d s c 0 5 Cap -28] $ ./ Usando - T e m p l a t e C o m T e m p l a t e A d i c i o n a l

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

28.2. CLASSES TEMPLATE USO AVANCADO


x = 5 Criando polin^ o mio TCPolinomio < int > pInt1 ; C o e f i c i e n t e s de pInt1 = 0 1 2 pInt1 ( x ) = 55 Criando polin^ o mio TCPolinomio < float , size > pFloat1 ; C o e f i c i e n t e s de pFloat1 = 0 1 2 pFloat1 ( x ) = 55 Igualando polin^ o mios de tipos diferentes ... ... ok pInt1 ( x ) = 55

517

28.2.2

Especializa c ao de classes templates

Podemos usar especializa co es para reescrever toda uma classe para um tipo espec co, em fun ca o deste n ao ter o comportamento esperado (ou padr ao). A especializa ca o customiza a classe template para um tipo espec co. Veja a seguir o prot otipo utilizado na especializa ca o de classes templates. Prot otipo: // Deni ca o da classe template padr ao template< typename Tipo > class TCNome {...}; // Deni ca o da classe template especializada template<> class TCNome< TipoEspecializado > {...}; Com o uso de especializa co es, voc e pode criar vers oes otimizadas da fun ca o/classe template. Note, entretanto, que se voc e especializar uma classe template, ter a de especializar todos os m etodos da classe. Ou seja, ao criar uma especializa ca o de uma classe, a classe ter a de ser totalmente reescrita. Veja no exemplo a seguir como criar uma classe template TCNome que e especializada para o tipo Tipo* (ponteiro gen erico) e para o tipo void* (ponteiro espec co void*). Veremos o uso de ponteiros void* na se ca o F.2. Exemplo // Defini c~ ao da classe template template< typename Tipo > class TCNome {...}; // Especializa c~ ao para Tipo* (qualquer ponteiro) template< typename Tipo > class TCNome< Tipo * > {....}; // Especializa c~ ao espec fica para void* template<> class TCNome< void * > {.....}; Se uma classe com atributos est aticos foi especializada, n ao se esque ca de denir externamente cada atributo est atico para o tipo especializado. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

518

28.2. CLASSES TEMPLATE USO AVANCADO Exemplo: // Defini c~ ao da classe template template < typename T > class TCNome { static T atributoEstatico; }; // Defin c~ ao do atributoEstatico template < typename T > T TCNome<T>::atributoEstatico = 0; // Especializa c~ ao da classe para o tipo int // Defini c~ ao da classe template template < int > class TCNome { static int atributoEstatico; }; // Defin c~ ao do atributoEstatico especializado template<> int TCNome<int>::atributoEstatico = 0;

28.2.3

Instanciando fun c oes e classes template2

O c odigo da listagem 28.8, adaptado de [Lischner, 2003], mostra o uso de fun co es e classes template, como as mesmas podem ser instanciadas. Listing 28.8: Exemplo: Instanciando fun co es e classes template.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // A d a p t a d o de C ++ in a nutshell , de Ray L i s c h n e r // I n s t a n c i a n d o f u n c~ oes e classes templates # include < iomanip > # include < iostream > # include < ostream > const double pi = 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 2 ; // Fun c~ ao template template < typename T > void Saida ( T obj ) { std :: cout << obj << \ n ; } // Fun c~ ao template template < typename T > T sqr ( T x ) { return x * x ; } // I n s t a n c i a c~ ao expl c i t a de sqr para o tipo int template int sqr < int >( int ) ; // Erro : ap os instancia c~ a o de sqr < double > , uso ilegal do mesmo . template < > double sqr ( double x )

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

28.2. CLASSES TEMPLATE USO AVANCADO


30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 { return x * x ; } // Classe t e m p l a t e template < typename T > class TCCirculo { public : TCCirculo ( T r ) : raio ( r ) {} // O b s e r v e que sqr < > e i n s t a n c i a d o quando TCCirculo < > e instanciado. T Area () const { return pi * sqr ( raio ) ; } T Raio () const { return raio ; } private : T raio ; }; // S o b r e c a r g a da Fun c~ a o t e m p l a t e Saida () template < typename T > void Saida ( const TCCirculo < T >& c ) { std :: cout << " TCCirculo ( " << c . Raio () << " ) \ n " ; } // I n s t a n c i a c~ a o e x p l i c i t a de TCCirculo < double > , e // i n s t a n c i a c~ ao impl c i t a sqr < double > template class TCCirculo < double >; int main () { using namespace std ; cout << " Chamando Saida (42) " << endl ; Saida (42) ; cout << " i sqr ( i ) " << endl ; for ( int i = 0; i < 5; ++ i ) // I n s t a n c i a c~ ao impl c i t a de sqr < int > cout << setw (2) << i << setw (4) << sqr ( i ) << \ n ; // I n s t a n c i a c~ a o de TCCirculo < float > e de sqr < float > TCCirculo < float > o b j _ T C C i r c u l o F l o a t (1.0 f ) ; // I n s t a n c i a c~ ao impl c i t a de Saida < TCCirculo < float > > cout << " Chamando Saida ( o b j _ T C C i r c u l o F l o a t ) " << endl ; Saida ( o b j _ T C C i r c u l o F l o a t ) ; }

519

[ b u e n o @ l d s c 0 5 ] $ ./ a . out Chamando Saida (42) 42 i sqr ( i ) 0 0 1 1 2 4 3 9 4 16 Chamando Saida ( o b j _ T C C i r c u l o F l o a t ) TCCirculo (1)

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

520

28.3. USO DE EXPORT COM TEMPLATES3

28.3

Uso de export com templates3

A inclus ao da palavra-chave export, foi alvo de grandes debates no comit e Ansi/ISO C++. Isto ocorreu porque, de um modo geral, primeiro os programadores desenvolvem novos conceitos que s ao posteriormente incorporados nos compiladores e na linguagem padr ao. Com export, o processo foi invertido. Os membros do comit e aprovaram o uso de export sem que nenhum compilador o suporta-se. Somente recentemente alguns poucos compiladores come caram a suportar o uso de export. A id eia por tr as do uso de export e fornecer dois modelos distintos de organiza ca o do c odigo fonte. O primeiro, cl assico, e conhecido como modelo de inclus ao. O segundo, novo, e conhecido como modelo de separa ca o. Veremos as diferen cas nesta se ca o. No modelo atual podemos declarar um m etodo n ao template no arquivo .h e den -lo do .cpp. Podemos compilar o programa tendo apenas a informa ca o disponibilizada no arquivo .h. Mas isto n ao e poss vel com templates. No modelo de inclus ao o c odigo fonte completo do template deve estar vis vel para quem vai o utilizar. Isto tem sido feito incluindo todo c odigo do template no arquivo .h ou incluindo no nal do arquivo .h o arquivo .cpp. No modelo de separa ca o pretende-se permitir a compila c ao separada de templates. Neste caso, a deni ca o do template n ao precisa estar vis vel para quem o chama. A id eia e permitir que um arquivo que use o template seja compilado sem ter sua deni ca o. Mas o que esta por tr as desta mudan ca e porque isto ainda n ao foi colocado em pr atica? Um dos objetivos desta mudan ca e eliminar a necessidade do c odigo-fonte (*.cpp). Seria fornecido diretamente o arquivo .h e o arquivo objeto. Desta forma impede-se o acesso do usu ario da biblioteca ao c odigo-fonte da biblioteca (templates), sendo este um claro interesse da ind ustria de software propriet ario. O segundo objetivo, este sim v alido, consiste em aumentar a velocidade de compila ca o. A segunda quest ao, esta associada ao fato de que pouqu ssimos compiladores tem suporte a export. Em resumo, evite usar export. Espere a pr oxima vers ao do C++, C++0x, e o posicionamento dos gurus de C++, para ver se export, vai ou n ao ser adotado pela comunidade. Para maiores detalhes, consulte [Sutter, 2006].

28.4

Senten cas para uso avan cado de templates

No in cio, C++ permitia o uso de fun co es template e de classes template globais. Voc e n ao podia declarar uma classe normal com um m etodo template. Agora isto e permitido, isto e, um m etodo membro da classe pode ser denido como template. Neste caso, os argumentos do template s ao denidos mediante a an alise dos par ametros do m etodo (listagem 28.4). A instancia ca o de uma classe template n ao garante que todos os membros sejam instanciados. Os membros ser ao instanciados se forem efetivamente utilizados ou se forem necess arios para resolu ca o de alguma sobrecarga de operador. Se numa classe template temos um m etodo M() que tem erros de sintaxe, mas o m etodo n ao e utilizado, ent ao alguns compiladores acusam o erro, outros n ao. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

28.4. SENTENCAS PARA USO AVANCADO DE TEMPLATES

521

Quando uma classe e especializada, teremos a vers ao padr ao e as vers oes especializadas. Quando criamos um objeto da classe template, passando seus argumentos, o compilador procura dentro das vers oes especializadas qual tem maior coincid encia. Se n ao for encontrada uma vers ao especializada, ent ao a vers ao padr ao e utilizada. Se duas vers oes especializadas tiverem o mesmo grau de coincid encia ent ao o compilador acusa uma ambiguidade, [Lischner, 2003]. Quando criamos m etodos template dentro de classes, a chamada ao m etodo pode car inviabilizada pois o compilador, em alguns casos, confunde o operador < como sendo o operador menor que. A solu ca o e informar explicitamente que estamos tratando com um m etodo template. Exemplo: class CNome { public: template< int n > int M(); template< int n > static int SM(); }; int main() { CNome obj; obj.template M<3>(); CNome::template SM<4>(); return 0; } Note que um atributo privado pode ser acessado por qualquer m etodo da classe, incluindo os m etodos/fun co es amigas. Na pr atica, isto signica que estes m etodos podem repassar - de forma oculta - este acesso para terceiros. Por exemplo, um m etodo da classe pode retornar uma refer encia para um atributo privado, violando o conceito de invari ancia da classe. Como um template de fun ca o pode ser especializado, o mesmo pode ser utilizado para violar o conceito de invari ancia da classe. Veja se ca o 28.1.1. 3 Segundo [Meyers, 2005], em classes templates derivadas use refer encias a nomes da classebase utilizando this, usando declara co es using, ou via qualica ca o explicita da classebase. 3 Um template dentro de uma classe normal ou de uma classe template e conhecido como membro template. Segundo [Lischner, 2003], um membro template tem as seguintes restri co es: classes locais n ao podem ter membro template. uma fun ca o membro template n ao pode ser um construtor. uma fun ca o membro template n ao pode ser virtual. se a classe-base tem um m etodo virtual, um m etodo membro template com o mesmo nome e par ametros numa classe-derivada n ao oculta o m etodo da classe-base.

3 Segundo [Sutter, 2006], export n ao implica em compila ca o separada, export apenas oculta depend encias, n ao as elimina. 3 Como export, ainda n ao e devidamente compreendido e n ao e suportado em v arios compiladores, seu uso deve ser evitado. Principalmente em c odigos multiplataforma. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

522

28.5. RESUMO DO CAP ITULO

28.5

Resumo do cap tulo

Neste cap tulo aprendemos a utilizar conceitos avan cados de templates, o uso de fun co es e classes template especializadas. Para atender a casos espec cos, aprendemos a criar especializa co es de fun co es template. Tamb em aprendemos a otimizar o programa utilizando fun co es expandidas em tempo de compila ca o. Vimos ainda que podemos mapear fun co es template utilizando especializa co es, e que em casos especiais precisamos usar a palavra-chave typename para identicar com clareza o que queremos. Aprendemos ainda a criar templates dentro de classes template e a especializa ca o de classes. Finalmente, vimos que ainda n ao devemos usar export. Dica: a biblioteca boost (veja Cap tulo ?? - A biblioteca Boost ), e a biblioteca Blitz++ (veja Cap tulo ?? - A biblioteca Blitz++ ), usam extensivamente os conceitos avan cados de templates, sendo boas refer encias para aprendizado e uso de templates. Dica: veja maiores detalhes de templates na refer encia Nicolai M. Josuttis e David Vandevoordes, C++ Templates - The Complete Guide, [Vandevoorde and Josuttis, 2002].

28.6

Exerc cios

1. Implementar a fun ca o Media(), da se ca o 28.1.4, usando o conceito de especializa ca o, se ca o 28.2.2. Ou seja, sem usar a struct double_trait. 2. Comentar o c odigo da listagem 28.8. 3. Na listagem 28.1, fazer com que a sa da seja em ordem decrescente. 4. Explique o funcionamento da listagem 28.2. 5. Leia o manual da biblioteca Blitz++ (se ca o ??). 6. Usu arios avan cados devem ler o livro C++ Templates - The Complete Guide, [Vandevoorde and Josuttis, 2002].

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 29

Implementando Associa c oes em C++


Como visto na Parte I - Filosoa e Modelagem Orientada a Objetos, existem relacionamentos entre objetos distintos. A esses relacionamentos damos o nome de associa co es ou depend encias. Discutiremos neste cap tulo a implementa ca o de associa co es utilizando C++. Veremos uma introdu ca o ` as associa co es em C++ (se ca o 29.1), o uso de associa ca o sem atributo (se ca o 29.2), e o uso de associa ca o com atributo (se ca o 29.3).

29.1

Introdu c ao ` as associa c oes em C++

Uma associa ca o pode ser unidirecional, bidirecional e pode (ou n ao) ter atributos. De um modo geral, pode ser implementada de tr es formas: Implementar a associa ca o por meio de ponteiros para os objetos. A cria ca o de uma classe que representa a associa ca o; neste caso, ser ao necess arios ponteiros para a classe associa ca o partindo dos objetos associados (veja se ca o 6.4.5). Utiliza ca o de fun co es friend (veja Cap tulo 20 - Friend).

29.2

Associa c ao sem atributo

Se a associa ca o for unidirecional e sem atributo de associa ca o, poder a ser implementada com um ponteiro na classe que faz o acesso. No exemplo a seguir a classe A acessa a classe B. Exemplo: class B; class A {... B* ptr_para_b; }; class B {... }; 523

524

COM ATRIBUTO 29.3. ASSOCIAC AO

Se a associa ca o for bidirecional, ser ao necess arios ponteiros em ambas as classes. No exemplo a seguir, a classe A acessa a classe B e a classe B acessa a classe A. Exemplo: class B; class A {... B* ptr_para_b; }; class B {... A* ptr_para_a; }; Se a associa ca o entre as duas classes for do tipo um para muitos, cardinalidade um A para muitos Bs, ent ao na classe que acessa muitos deve ser implementado um vetor de ponteiros. Exemplo: class B; class A { vector< B* > vetor_b(N); }; class B { A* ptr_para_a; }; Se a associa ca o tiver uma cardinalidade muitos para muitos, uma das solu co es e criar um dicion ario. Veremos como implementar um dicion ario usando <map> na se ca o 34.4. Dica: no programa umbrello, quando modelar uma associa ca o, indicar na linha da associa ca o o nome do papel.

29.3

Associa c ao com atributo

Vimos na se ca o 6.4.5 que uma associa ca o entre duas classes pode gerar uma classe de associa ca o. Veremos na listagem 29.1 como implementar uma classe de associa ca o. Observe que a classe de associa ca o pode ser declarada como amiga de A e B. Listing 29.1: Associa ca o com atributo de liga ca o.
1 2 3 4 5 6 7 8 9 10 11 12 # include < iostream > using namespace std ; class Associacao ; class A { int a ; public : Associacao * p t r A s s o c i a c a o ; friend class Associaca o ; };

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

29.4. RESUMO DO CAP ITULO


13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51

525

class B { int b ; public : Associacao * p t r A s s o c i a c a o ; friend class Associacao ; }; class Associacao { int a t r i b u t o A s s o c i a c a o ; A * ptr_A ; B * ptr_B ; public : Associacao () : a t r i b u t o A s s o c i a c a o (0) , ptr_A (0) , ptr_B (0) int A t r i b u t o A s s o c i a c a o () { return a t r i b u t o A s s o c i a c a o ; }; friend class A ; friend class B ; }; int main () { B b; Associacao associacao ; b . p t r A s s o c i a c a o = & associacao ; cout << " b . ptrAssociacao - > A t r i b u t o A s s o c i a c a o () = " << b . ptrAssociacao - > A t r i b u t o A s s o c i a c a o () << endl ; return 0; } [ b u e n o @ l d s c 0 5 ] $ ./ a . out b. ptr_associacao - > A t r i b u t o A s s o c i a c a o () =0

};

29.4

Resumo do cap tulo

Neste cap tulo aprendemos a implementar associa co es em C++, associa co es sem atributo e associa co es com atributo.

29.5

Exerc cios

1. Modique a listagem 29.1. 2. Monte um diagrama de classes no umbrello que inclua diferentes tipos de associa co es. N ao se esque ca de nomear as associa co es, pois o umbrello usa o nome da associa ca o para gerar o c odigo. Gere os c odigos, veja se ca o 6.8.2. A seguir fa ca uma an alise dos c odigos gerados pelo umbrello.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

526

29.5. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 30

As Classes <complex>, <bitset> e as Fun c oes Matem aticas de <cmath>


Neste cap tulo, veremos: as fun co es matem aticas denidas no arquivo de cabe calho <cmath> (se ca o 30.1), suas fun co es (se ca o 30.1.1), e exemplos de uso (se ca o 30.1.2). a classe <complex> (se ca o 30.2), seus m etodos (se ca o 30.2.1), exemplo de uso de <complex> (se ca o 30.2.2) e um resumo do arquivo <complex> da biblioteca padr ao (se ca o 30.2.3). a classe <bitset> (se ca o 30.3), seus m etodos (se ca o 30.3.1), e exemplos de uso de <bitset> (se ca o 30.3.2) e <bitset> com <vector> (se ca o 30.3.3).

30.1

Introdu c ao ` a biblioteca <cmath> de C

Veremos nesta se ca o a utiliza ca o da biblioteca <cmath> de C, a mesma fornece fun co es matem aticas.

30.1.1

Fun coes de <cmath>

Veja a seguir as fun co es de <cmath>. Observe que nos prot otipos abaixo utilizamos o tipo double, mas estas fun co es s ao denidas para float, double e long double. Prot otipo: double abs(double); Fun ca o valor absoluto. double ceil(double x); Fun ca o menor inteiro n ao menor que x (arredonda para cima). double oor(double x); Fun ca o maior inteiro n ao maior que x (arredonda para baixo). 527

528 double sqrt(double x); Fun ca o raiz quadrada de x.

A ` BIBLIOTECA <CMATH> DE C 30.1. INTRODUC AO

double pow(double x, int y); Fun ca o x elevado a pot encia de y. double cos(double x); Fun ca o cosseno. double sin(double x); Fun ca o seno. double tan(double x); Fun ca o tangente. double acos(double x); Fun ca o arco cosseno. double asin(double x); Fun ca o arco seno. double atan(double x); Fun ca o arco tangente. double atan2(double x, double y); Fun ca o atan de x/y. double cosh(double x); Fun ca o cosseno hiperb olico. double sinh(double x); Fun ca o seno hiperb olico. double tanh(double x); Fun ca o tangente hiperb olico. double exp(double x); Fun ca o expoente na base e de x. double log(double x); Fun ca o logaritmo neperiano, x > 0. double log10(double x); Fun ca o logaritmo na base 10, x > 0. double modf(double x, int* y); Fun ca o parte fracion aria em x, parte inteira em y. Nota: podemos utilizar <math.h> (escopo global, usado por programas em C) ou <cmath> (escopo da std, formato utilizado por programas em C++). Com <math.h>, podemos chamar sin(30), cos(45) diretamente (pois as fun co es sin() e cos() est ao no escopo global). Com <cmath>, estamos no escopo da std, da precisamos usar std::sin(30), std::cos(45). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A ` BIBLIOTECA <CMATH> DE C 30.1. INTRODUC AO

529

30.1.2

Exemplos de uso de <cmath>

Veja na listagem 30.1 exemplo de uso da biblioteca <cmath> de C. Listing 30.1: Usando fun co es matem aticas de <cmath>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 # include < iostream > # include < iomanip > # include < cmath > using namespace std ; int main () { cout << setiosfla g s ( ios :: fixed | ios :: showpoint ) << s e t p r e c i s i o n ( 1 ) << " Raiz quadrada sqrt (700.0) = " << sqrt ( 700.0 ) << " \ n " << " Exponencia l neperiana ( e ^ x ) << s e t p r e c i s i o n (6) exp (1.0) = " << exp (1.0) << " \ n "

<< " logaritmo neperiano log (2.718282) = " << s e t p r e c i s i o n (1) << log (2.718282) << " \ n " << " Logaritmo na base 10 log10 (1.0) = " << log10 ( 1.0 ) << " , log10 (10.0) = " << log10 ( 10.0 ) << " , log10 (100.0) = " << log10 ( 100.0 ) << " \ n " << " Fun ca ~ o valor absoluto , m o dulo fabs (13.5) = " << fabs ( 13.5 ) << " \ n " << " , fabs (0.0) = " << fabs ( 0.0 ) << " , fabs ( -13.5) = " << fabs ( -13.5 ) << " \ n " << " Truncament o ceil (9.2) = " << " , ceil ( -9.8) = " << " A r r e d o n d a m e n t o floor (9.2) = " << " , floor ( -9.8) = " << " Potencia ca ~ o x ^ y pow (2.0 ,7.0) = " << " fmod (13.675 , 2.333) = " << s e t p r e c i s i o n ( 1 ) << " \ n " << ceil ( 9.2 ) << ceil ( -9.8 ) << " \ n " << floor ( 9.2 ) << floor ( -9.8 ) << " \ n " << pow ( 2.0 , 7.0 ) << fmod ( 13.675 , 2.333 )

<< " Fun co ~ es trigonom e trica s , sin , cos , tan \ n " << " sin (0.0) = " << sin ( 0.0 ) << " , cos (0.0) = " << cos ( 0.0 ) << " , tan (0.0) = " << tan ( 0.0 ) << endl ; return 0; }

Raiz quadrada sqrt (700.0) = 26.5 Exponenci al neperiana ( e ^ x ) exp (1.0) = 2.718282 logaritmo neperiano log (2.718282) = 1.0 Logaritmo na base 10 log10 (1.0) = 0.0 , log10 (10.0) = 1.0 , log10 (100.0) = 2.0 Fun ca ~ o valor absoluto , m o dulo fabs (13.5) =13.5 , fabs (0.0) =0.0 , fabs ( -13.5) =13.5 Truncamen to ceil (9.2) = 10.0 , ceil ( -9.8) = -9.0 A r r e d o n d a m e n t o floor (9.2) = 9.0 , floor ( -9.8) = -10.0 Potencia ca ~ o x ^ y pow (2.0 ,7.0) = 128.0 fmod (13.675 , 2.333) = 2.0 Fun co ~ es trigonom e tric as , sin , cos , tan sin (0.0) = 0.0 , cos (0.0) = 1.0 , tan (0.0) = 0.0

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

530

A ` CLASSE <COMPLEX> 30.2. INTRODUC AO

30.2

Introdu c ao ` a classe <complex>

A classe <complex> e uma classe que suporta n umeros complexos, com a parte real e a imagin aria. Com a classe <complex>, voc e pode trabalhar com n umeros complexos diretamente, utilizando os operadores e m etodos sobrecarregados. Pode igualar dois n umeros complexos, fazer compara co es, realizar opera co es aritm eticas (+-*/), exponencia ca o, obter logaritmos, pot encia, entre outros. Os objetos <complex> podem ter precis ao float, double e long double. Para criar um n umero complexo, voc e precisa incluir o arquivo de cabe calho <complex> e, a seguir, denir a precis ao do n umero complexo. Veja o exemplo. Exemplo: #include <complex> int main() { complex <float> cf; complex <double> cd; complex <long double> cld; return 0; }

30.2.1

M etodos de <complex>

Veja a seguir os m etodos da classe <complex>. Construtores e destrutor Como a classe <complex> representa um n umero complexo, voc e pode construir um n umero complexo a partir da parte real, ou a partir da parte real e da imagin aria. complex (const Tipo& real = Tipo(), const Tipo & img = Tipo()); Recebe como par ametro a parte real e a parte imagin aria. Observe que o construtor tem par ametros pr e-denidos, de forma que se os mesmos n ao forem passados, assume o valor default para o tipo, 0 para os tipos num ericos. Note ainda que podemos construir um n umero complexo apenas com a parte real. complex (const complex<Tipo2>&); Construtor de c opia. complex (); Destrutor. Veja o exemplo. Exemplo: // Cria um n umero complexo, do tipo float com nome cf complex <float> cf; // Cria um n umero complexo, do tipo double e passa parte real double parteReal = 3.4; complex <double> cd( parteReal ); // Cria um n umero complexo e passa a parte real e a parte imagin aria double parteImg = 21.5; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A ` CLASSE <COMPLEX> 30.2. INTRODUC AO complex <long double> cld( parteReal , parteImg ); // Construtor de c opia, cria c opia de cf complex <float> cf2( cf ); M etodos utilit arios

531

A classe <complex> fornece um conjunto de m etodos que possibilitam a obten ca o de propriedades deste, como o m odulo, o argumento, a norma, o conjugado, entre outros. Tipo& real(); Retorna a parte real de um n umero complexo. Tipo& imag(); Retorna a parte imagin aria de um n umero complexo. Tipo abs(const complex<Tipo>&); Retorna magnitude. Tipo arg(const complex<Tipo>&); Retorna angulo de fase. Tipo norm(const complex<Tipo>&); Retorna magnitude ao quadrado. complex<Tipo> conj(const complex<Tipo>&); Retorna n umero complexo conjugado. complex<Tipo> polar(const Tipo& rho, const Tipo& theta= 0); Retorna n umero complexo com magnitude rho e angulo theta. Veja a seguir um exemplo. Exemplo: float real = cf.real(); // Retorna parte real float img = cf.imag(); // Retorna parte imagin aria float abs = cf.abs( ); // Retorna m odulo float arg = cf.arg(); // Retorna argumento // Soma dos quadrados da parte real e da imagin aria float norm = cf.norm(); // A magnitude e o ^ angulo de fase const float magnitude =3; const float fase =45; float p = cf.polar (magnitude, fase); // Retorna o conjugado complex <float> cf_conjugado = cf.conj(); M etodos trancendentais A classe <complex> fornece um conjunto de m etodos transcendentais, como acos, asin, atan, atan2, cos, cosh, exp, log, log10, pow, sin, sinh, sqrt, tan, tanh. Veremos na listagem 30.3 um resumo da classe <complex> fornecida pela biblioteca padr ao de C++, o que inclui o prot otipo dos m etodos trancendentais. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

532 Operadores sobrecarregados

A ` CLASSE <COMPLEX> 30.2. INTRODUC AO

Diversos operadores foram sobrecarregados para a classe <complex>, a lista e dada por: +, -, *, /, += ,-= , *= , -, * ,+ , -. Tamb em foram denidos operadores de compara ca o (==, !=) e operadores de inser ca o e extra ca o (stream), ou seja, podemos enviar n umeros complexos diretamente para tela com cout. Veremos na listagem 30.2 exemplos de uso dos operadores que foram sobrecarregados. template plex<X>& template plex<X>& <class X> istream& operator > > (istream& is, comx); <class X> ostream& operator < < (ostream& os, const comx);

30.2.2

Exemplo de uso de <complex>

Veja na listagem 30.2 um exemplo da utiliza ca o da classe <complex>, observe a forma como a classe complexo sobrecarregou os operadores < < e > >. O n umero complexo aparece dentro de par enteses. Listing 30.2: Usando <complex>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # include < iostream > # include < complex > using namespace std ; int main () { complex < double > c1 (1.2 , 3.4) ; complex < double > c2 ( -9.8 , -7.6) ; cout << " c1 = " << c1 << " , c2 = " << c2 << endl ; c1 += c2 ; c2 /= sin ( c2 ) * cos ( c1 ) ; cout << " c1 = " << c1 << " , c2 = " << c2 << endl ; c2 *= log ( c1 ) + pow ( c2 , c1 ) ; c1 -= c1 / c2 ; cout << " c1 = " << c1 << " , c2 = " << c2 << endl ; cout << " Entre com o complexo c1 ( real , imag ) : " ; cin >> c1 ; cin . get () ; cout << " Conte u do de c1 = " << c1 << endl ; return 0; } [ b u e n o @ l d s c 0 5 Parte - II ] $ ./ a . out c1 = (1.2 ,3.4) , c2 = ( -9.8 , -7.6) c1 = ( -8.6 , -4.2) , c2 = (7.77139 e -05 , -0.000364079) c1 = ( -8.6 , -4.2) , c2 = (3.37075 e +23 , -1.75436 e +23) Entre com o complexo c1 ( real , imag ) : (3 ,4) Conte u do de c1 = (3 ,4)

30.2.3

Resumo da classe <complex> fornecida pela biblioteca padr ao

Veja na listagem 30.3 um resumo da classe <complex> fornecida pela biblioteca padr ao de C++. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A ` CLASSE <COMPLEX> 30.2. INTRODUC AO Listing 30.3: A classe <complex> da biblioteca padr ao.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 // Resumo do a r q u i v o c o m p l e x da b i b l i o t e c a padr~ a o de C ++ // As d e f i n i c~ o e s de t e m p l a t e foram t i r a d a s para maior b r e v i d a d e // Cria v e r s ~ o e s de n u m e r o s c o m p l e x o s para float , double , long double class complex ; template < > class complex < float >; template < > class complex < double >; template < > class complex < long double >; // A classe c o m p l e x struct complex { private : Tipo _M_real ; // / Parte real Tipo _M_imag ; // / Parte i m a g i n aria public : // / D e f i n i c~ a o do t y p e d e f para v a l u e _ t y p e . typedef Tipo value_type ; // / C o n s t r u t o r padr~ ao . O primeiro par^ ametro e a parte real , // / o s e g u n d o a parte i m a g i n aria. // / P a r ^ a m e t r o s n~ a o d e f i n i d o s a s s u m e m valor 0. complex ( const Tipo & = Tipo () , const Tipo & = Tipo () ) ; // / C o n s t r u t o r de c o pia . complex ( const complex < Tipo2 >&) ; // / R e t o r n a parte real do n u mero c o m p l e x o Tipo & real () ; const Tipo & real () const ; // / R e t o r n a parte i m a g i n a r i a do n u mero c o m p l e x o Tipo & imag () ; const Tipo & imag () const ; // / O p e r a d o r e s complex < Tipo >& complex < Tipo >& complex < Tipo >& complex < Tipo >& complex < Tipo >& complex < Tipo >& complex < Tipo >& complex < Tipo >& complex < Tipo >& complex < Tipo >& sobrecarregados ( m e t o d o s membro ) operator =( const Tipo &) ; operator +=( const Tipo &) ; operator -=( const Tipo &) ; operator *=( const Tipo &) ; operator /=( const Tipo &) ; operator =( const complex < Tipo2 >&) ; operator +=( const complex < Tipo2 >&) ; operator -=( const complex < Tipo2 >&) ; operator *=( const complex < Tipo2 >&) ; operator /=( const complex < Tipo2 >&) ;

533

// / O p e r a d o r e s s o b r e c a r r e g a d o s ( f u n c~ o e s amigas ) operator +( const complex < Tipo >& __x , const complex < Tipo >& __y ) ; operator +( const complex < Tipo >& __x , const Tipo & __y ) ; operator +( const Tipo & __x , const complex < Tipo >& __y ) ; operator -( const complex < Tipo >& __x , const complex < Tipo >& __y ) ; operator -( const complex < Tipo >& __x , const Tipo & __y ) ; operator -( const Tipo & __x , const complex < Tipo >& __y ) ; operator *( const complex < Tipo >& __x , const complex < Tipo >& __y ) ; operator *( const complex < Tipo >& __x , const Tipo & __y ) ; operator *( const Tipo & __x , const complex < Tipo >& __y ) ; operator /( const complex < Tipo >& __x , const complex < Tipo >& __y ) ; operator /( const complex < Tipo >& __x , const Tipo & __y ) ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

534
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96

A ` CLASSE <BITSET> 30.3. INTRODUC AO

operator /( const Tipo & __x , const complex < Tipo >& __y ) ; operator +( const complex < Tipo >& __x ) ; operator -( const complex < Tipo >& __x ) ; operator > >( basic_istream < _CharT , _Traits >& __is , complex < Tipo >& __x ) ; operator < <( basic_ostream < _CharT , _Traits >& __os , const complex < Tipo >& __x ) ; // F u n c~ oes matem a t i c a s para n umeros complexos // / R e t o r n a m a g n i t u d e Tipo abs ( const complex < Tipo >&) ; // / R e t o r n a angulo de fase Tipo arg ( const complex < Tipo >&) ; // / R e t o r n a m a g n i t u d e ao q u a d r a d o Tipo norm ( const complex < Tipo >&) ; // / R e t o r n a n u mero c o m p l e x o c o n j u g a d o complex < Tipo > conj ( const complex < Tipo >&) ; // / R e t o r n a n u mero c o m p l e x o com m a g n i t u d e rho e angulo theta . complex < Tipo > polar ( const Tipo & , const Tipo & = 0) ; // / M etodos transcendentais: complex < Tipo > cos ( const complex < Tipo >&) ; complex < Tipo > cosh ( const complex < Tipo >&) ; complex < Tipo > exp ( const complex < Tipo >&) ; complex < Tipo > log ( const complex < Tipo >&) ; complex < Tipo > log10 ( const complex < Tipo >&) ; complex < Tipo > pow ( const complex < Tipo >& , int ) ; complex < Tipo > pow ( const complex < Tipo >& , const Tipo &) ; complex < Tipo > pow ( const complex < Tipo >& , const complex < Tipo >&) ; complex < Tipo > pow ( const Tipo & , const complex < Tipo >&) ; complex < Tipo > sin ( const complex < Tipo >&) ; complex < Tipo > sinh ( const complex < Tipo >&) ; complex < Tipo > sqrt ( const complex < Tipo >&) ; complex < Tipo > tan ( const complex < Tipo >&) ; complex < Tipo > tanh ( const complex < Tipo >&) ; };

30.3

Introdu c ao ` a classe <bitset>

Apresentaremos nesta se ca o a classe <bitset>, uma classe criada para manipula ca o de vetores de bits. Voc e vai aprender a criar e usar um vetor de bits com tamanho denido durante a compila ca o. Veja a seguir algumas dicas para uso de <bitset>. O tamanho do vetor de bits deve ser denido em tempo de compila ca o, ou seja, um objeto <bitset> e um objeto est atico. O valor default de cada bit e 0. Um <bitset> pode ser constru do a partir de uma string de zeros (0) e um (1). Todo acesso b[i] e vericado; se i est a fora do intervalo, uma exce ca o do tipo out_of_range e lan cada. N ao confunda um operador sobre bits (& e |) com operadores l ogicos (&& e ||). A grande vantagem de <bitset> e a possibilidade de manipular um vetor de ags (0, 1), consumindo pouca mem oria. Para criar um objeto <bitset>, inclua o arquivo de cabe calho <bitset>. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A ` CLASSE <BITSET> 30.3. INTRODUC AO

535

30.3.1

M etodos de <bitset>

void set(n); Seta o bit n para true. void reset(n); Seta o bit n para false. void ip(n); Inverte o valor do bit n. void set(); Seta todos os bits para true. void reset(); Seta todos os bits para false. void ip(); Inverte o valor de todos os bits. int size(); Retorna a dimens ao do <bitset>. int count(); Retorna o n umero de bits ativos. bool any(); Retorna true se tiver pelo menos um bit ativo. bool none(); Retorna true se todos inativos operator< <(); Rotaciona os bits para esquerda. operator> >(); Rotaciona os bits para direita. operator[] (int i); Retorna o valor do bit na posi ca o i.

30.3.2

Exemplos de uso da classe <bitset>

Veremos uma breve descri ca o de cada m etodo da classe <bitset> no exemplo da listagem 30.4. A listagem e auto-explicativa. Na sa da mostramos que o <bitset> b consome 8 bytes em uma plataforma de 64 bits. Listing 30.4: Exemplo descritivo da classe <bitset>.
1 2 3 4 5 6 7 8 # include < bitset > # include < iostream > using namespace std ; int main () { const int size = 5; cout << " Cria objeto do tipo bitset com tamanho size " << size

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

536
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 << " e nome b . " << endl ; std :: bitset < size > b ; long unsigned int n ;

A ` CLASSE <BITSET> 30.3. INTRODUC AO

cout << " Entre com o bit que deseja modificar n = " ; cin >> n ; cin . get () ; cout << " Seta o bit n = " << n << " para true --> " ; b . set ( n ) ; cout << b << endl ; cout << " Seta o bit n = " << n << " para false - - > " ; b . reset ( n ) ; cout << b << endl ; cout << " Seta todos os bits para true - - > " ; b . set () ; cout << b << endl ; cout << " Seta todos os bits para false - - > " ; b . reset () ; cout << b << endl ; cout << " Inverte o bit n = " << n << " --> " ; b . flip ( n ) ; cout << b << endl ; cout << " Inverte todos os bits - - > " ; b . flip () ; cout << b << endl ; cout << " Usa m e todo teste ( n ) , com n = " << n ; bool t = b . test ( n ) ; cout << " bool t = b . test ( n ) ; t = " << t << endl ; cout << << << << << << cout << " Tamanho do bitset - - > b . size () = " << b . size () " \ nN u mero de bits ativados b . count () = " << b . count () " \ nRetorna true se tem pelo menos um bit esta ativo b . any () = " b . any () " \ nRetorna true se todos os bits est~ a o inativos b . none () = " b . none () << endl ; " Cria bitset b1 e b2 e faz b1 [ n ] = 1; " << endl ;

std :: bitset < size > b1 ; std :: bitset < size > b2 ; b1 [ n ] = 1; if ( b1 cout if ( b1 cout == << != << b2 ) " b1 == b2 " << endl ; b2 ) " b1 != b2 " << endl ;

cout << " Realiza um AND bit a bit e armazena em b1 : b1 &= b2 ; " << endl ; b1 &= b2 ; cout << " b1 - - > " << b1 << " b2 - - > " << b2 << endl ; cout << " Realiza um OR bit a bit e armazena em b1 : b1 [1] = 1; b1 != b2 ; " << endl ; b1 [1] = 1; b1 != b2 ; cout << " b1 - - > " << b1 << " b2 - - > " << b2 << endl ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

A ` CLASSE <BITSET> 30.3. INTRODUC AO


71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

537

cout << " Realiza um XOR bit a bit e armazena em b1 : b1 ^= b2 ; " << endl ; b1 ^= b2 ; cout << " b1 - - > " << b1 << " b2 - - > " << b2 << endl ; b1 . reset () ; b1 [ n ] = 1; b1 > >= n ; cout << " Ap o s b1 . reset () ; b1 [ n ] = 1; b1 > >= n ; " << " b1 - - > " << b1 << endl ; b1 < <= n ; cout << b1 << endl ; cout << " Ap o s b1 < <= n ; " << " b1 - - > " << b1 << endl ; cout << " Veja que o bitset b consome apenas " << sizeof ( b ) << " bytes \ n " ; return 0; } [ b u e n o @ l d s c 0 5 Cap -30] $ ./ E x e m p l o D e s c r i t i v o D a C l a s s e b i t s e t Cria objeto do tipo bitset com tamanho size 5 e nome b . Entre com o bit que deseja modificar n =1 Seta o bit n =1 para true - - >00010 Seta o bit n =1 para false - - >00000 Seta todos os bits para true - - >11111 Seta todos os bits para false - - >00000 Inverte o bit n =1 - - >00010 Inverte todos os bits - - >11101 Usa m e todo teste ( n ) , com n =1 bool t = b . test ( n ) ; t = 0 Tamanho do bitset - - > b . size () =5 N u mero de bits ativados b . count () =4 Retorna true se tem pelo menos um bit esta ativo b . any () =1 Retorna true se todos os bits est~ a o inativos b . none () =0 Cria bitset b1 e b2 e faz b1 [ n ] = 1; b1 != b2 Realiza um AND bit a bit e armazena em b1 : b1 &= b2 ; b1 - - >00000 b2 - - >00000 Realiza um OR bit a bit e armazena em b1 : b1 [1] = 1; b1 != b2 ; b1 - - >00010 b2 - - >00000 Realiza um XOR bit a bit e armazena em b1 : b1 ^= b2 ; b1 - - >00010 b2 - - >00000 Ap o s b1 . reset () ; b1 [ n ] = 1; b1 > >= n ; b1 - - >00001 00010 Ap o s b1 < <= n ; b1 - - >00010 Veja que o bitset b consome apenas 8 bytes

30.3.3

Exemplo de uso de <bitset> com <vector>2

Apresenta-se na listagem 30.5 o uso da classe <bitset> com a classe container <vector>. O container <vector> e descrito em detalhes no Cap tulo 32 - Os Containers Sequ enciais <vector>, <list>, <deque>. O programa cria um vetor com dimens ao nbitsets, sendo cada c elula do vetor um bitset com tamanho nbits. Lembre-se que para criar um vetor de 50 inteiros, utiliza-se vector<int> v(50);. Para criar um vetor de 50 objetos do tipo bitset<nbits>, deve-se fazer vector< bitset<nbits> > v(50);. Com v[i], acessa o objeto bitset [i], e com v[i][j] acessa-se objeto <bitset> [i], bit [j]. Usamos um for para setar os valores de cada elemento da matriz de bits que criamos. No nal o programa solicita a posi ca o do vetor e a posi ca o do bit que deve ser alterado.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

538

A ` CLASSE <BITSET> 30.3. INTRODUC AO Listing 30.5: Usando <bitset> com <vector>, criando uma matriz de bits.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

# include < iostream > # include < cmath > # include < bitset > # include < vector > using namespace std ; int main () { // Dimens~ a o fixa do vetor de bits const int nbits = 24; // Dimens~ a o vari a vel do vetor cout << " Entre com o numero de bitsets :"; int nbitsets ; cin >> nbitsets ; cin . get () ; // Cria o vetor de bitsets , observe que nbits e constante vector < bitset < nbits > > v ( nbitsets ) ; // v [ i ] acessa o bitset i , v [ i ][ j ] acessa o bitset i posi ca ~o j for ( int i = 0; i < v . size () ; i ++) for ( int j = 0; j < nbits ; j ++) v [ i ][ j ] = ( rand () % 2) ; for ( int i = 0; i < v . size () ; i ++) cout << v [ i ] << ; cout << endl ; int d ; do { int bitset_i , bit_j ; cout << "\ nEntre com o bitset que deseja alterar 0 - >" << v . size () -1 << ": "; cin >> bitset_i ; cout << " Entre com o bit que deseja alterar de 0 - >" << nbits - 1 << ": "; cin >> bit_j ; cout << " Entre com o novo valor do bit (0 ou 1) , >1 encerra programa : "; cin >> d ; cin . get () ; v [ bitset_i ][ bit_j ] = d ; cout << "\ nbitset " << bitset_i << " bit " << bit_j << " valor =" << v [ bitset_i ][ bit_j ] << endl ; for ( int i = 0; i < v . size () ; i ++) cout << v [ i ] << " "; } while ( d <= 1) ; return 0; } [ b u e n o @ l d s c 0 5 ] $ ./ a . out Entre com o numero de bitsets :3 110100000110101100111101 001011110101110001111000 101110101011100010010101 Entre com o bitset que deseja alterar 0 - >2: 1 Entre com o bit que deseja alterar de 0 - >23: 3 Entre com o novo valor do bit (0 ou 1) , >1 encerra programa : 0

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

30.4. RESUMO DO CAP ITULO

539

bitset 1 bit 3 valor =0 110100000110101100111101 001011110101110001110000 101110101011100010010101 Entre com o bitset que deseja alterar 0 - >2:

Dica: a STL criou uma especializa ca o para vector<bool> que e utilizada para armazenar verdadeiro/falso (true/false). A vantagem de vector<bool> em rela ca o a <bitset> e que o mesmo pode ser redimensionado, quando <bitset> n ao.

30.4

Resumo do cap tulo

Neste cap tulo aprendemos a usar a classe <complex> da biblioteca padr ao de C++. A classe <complex> e muito u til para solu ca o de problemas matem aticos e de engenharia, e o fato da classe <complex> ter diversos operadores e m etodos trancendentais facilita seu uso. Adicionalmente, os m etodos real(); imag(); abs(); arg() norm(); conj(); polar(); s ao f aceis de usar, o que pode ser vericado atrav es dos exemplos apresentados. Vimos que a classe <bitset> representa um vetor de bits com tamanho denido em tempo de compila ca o. Os m etodos de <bitset>, set(n); reset(n); flip(n); set(); reset(); flip(); size(); count(); any(); none(); tamb em s ao bastante simples. Finalmente vimos as fun co es matem aticas denidas no arquivo de cabe calho <cmath>, seus prot otipos e exemplos de uso.

30.5

Exerc cios

1. Modique a listagem 30.2 , acrescentando novos usos de <complex>. 2. Modique as listagens 30.4, acrescentando novos usos de <bitset>. 3. Monte um programa que utilize as fun co es matem aticas de <cmath>. 4. Implementar a hieraraquia de classes da Figura 30.1. Observe que temos tr es hierarquias de classes, Solver, Funcao e Integral. A classe de teste vai criar um objeto fun ca o e a seguir usar um objeto do tipo Solver para achar o zero de equa co es.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

540

30.5. EXERC ICIOS

Figura 30.1: Pequena hierarquia de m etodos num ericos (solver e integral num erica de fun co es do tipo polin omios).

T t e s l P / N T I t t S l P / N t a c o e a m e s p a c e n e g r a a c o e a m e s p a c e o v e r f * 1 T F u n c a o : V 2 ( ) t e s l t n e g r a i l + n g r I r ~ i f d b l I m n o u : S V l ( ) b l T I l i f d b l I a n e g r a o : m n o u e : l S u p V S S o v p d x e i t t e r i t t e r r v a o s n : l s o v e r d x d b l a o : V b l l t o u n e g r a : ( * ) d b l A F F p u n c u c a o o u e : V I + y ) I t n g a f 1 t p r v f ( i d b l i S d b l ) d b l Z I e m n o u e m u p o u e o u e + : : : , + _ _ ) d b l o o u e : i t n m s o n I S p ( * ) d b l A F F t r e a p r u c a o u c a o u e : : f + u n c a o d t l a y p e o v e r S i T t f 1 n r a z o r v I p ( * ) d b l A F F t r e a p r u c o u n c a o u e : : i + t t e s r e o p F u n c a T F u n c a o l i G T P 1 l i B o n m o o v e r s e c a o d b l x o e : S V d b l 1 a o u e : y u V ( l i f d b l S d b l ) d b l Z I e r o m n u m u p u e o u e : : : 2 , + _ _ ( ) d b l ) d b l t p r a x o e o u e : : + 0 T F n c # ( ) d b l ) d b l t p e r x o u e o u e : : o + ~ l i G 0 d b l ) T P 1 1 o n m a a o u e : i i b A , u e s l h N R t _ _ o v e r w o n a s o n S p a ( ) d b l ) d b l t o p e r a x o u e o u e : : + G ( lim f d b l, im S d b le ) d b le Z I u : e r o n u u u o u : : : f ( d l x : + _ _ ) X o l b ) v u u e l i 2 G T P o n m o Y + 3 d b l a o u e ( d l : a e : V 2 # ( ) d b l ) d b l t p e r x o u e u e : : + i 2 G 0 d b le 2 d b le ) P / N T P 1 t n m a o o u a o u c o a m e s p a c e : : , , _ _ _ T F u no a o G u :a
Andr e Duarte Bueno

Programa ca o Orientada a Objeto com C++

Parte III

Introdu c ao a STL

541

Cap tulo 31

Introdu c ao a Biblioteca Padr ao de Gabaritos de C++ - STL


No Cap tulo 9, aprendemos que C++ e fundamentada na utiliza ca o de tipos, os quais se subdividem em tipos b asicos de C++ (char, int, double etc.), tipos denidos pelo usu ario (SPessoa, UPropriedade, EDia, CPonto, CCirculo etc.) e tipos denidos em bibliotecas externas. Como exemplos de bibliotecas, abordamos a utiliza ca o de strings, de n umeros complexos e a hierarquia de streams (entrada e sa da de dados). Neste cap tulo, veremos a biblioteca-padr ao de gabaritos, a STL - Standard Template Library. Iniciamos este cap tulo denindo o que e a STL (se ca o 31.1), suas caracter sticas (se ca o 31.1.1) e componentes (se ca o 31.1.2). A seguir, apresentamos uma introdu ca o aos diferentes tipos de containers (se ca o 31.2). Os containers seq uenciais <vector>, <list> e <deque> (se ca o 31.2.1), os containers adaptativos <stack>, <queue> e <priority_queue> (se ca o 31.2.2), e os containers associativos <set>, <multiset>, <map> e <multimap> (se ca o 31.2.3). Descreveremos os m etodos e operadores comuns aos diversos containers (se ca o 31.2.4), os m etodos v alidos apenas para os containers seq uenciais (se ca o 31.2.5), e os typedefs comuns aos diversos containers (se ca o 31.2.6). Finalmente, veremos uma introdu ca o aos iteradores (iterators) (se ca o 31.3), os tipos de iteradores (se ca o 31.3.1) e opera co es comuns com iteradores (se ca o 31.3.2). Veremos ainda as fun co es predicado (se ca o 31.6). Nota: uma descri ca o adicional da STL pode ser obtida em http://www.cplusplus.com/ reference/stl/.

31.1

O que e a STL?

A STL, ou Standard Template Library, e uma biblioteca de objetos avan cada e u til, desenvolvida por Alexander Stepanov, Meng Lee e David Musser, utilizando os conceitos mais modernos da programa ca o orientada a objeto. Todo desenvolvimento da STL foi acompanhado e aprovado pelo comit e de padroniza ca o do C++, o ANSI C++ (veja se ca o 7.3). A biblioteca-padr ao de C++ inclui as classes string, streams, internacionaliza ca o, exce co es, classes matem aticas (complex, valarray), utilit arios (auto_ptr), gerenciamento de mem oria (new e delete) e as classes da STL. Ou seja, a STL e uma parte da biblioteca-padr ao de C++. Veja na Figura 31.1 uma ilustra ca o da biblioteca padr ao de C++. Nota: as classes <bitset>, <basic_string>, string, wstring, valarray, e vector<bool> s ao pseudo-container, porque suportam apenas parte dos algoritmos gen ericos. 543

544

A STL? 31.1. O QUE E

Figura 31.1: Diagrama UML da biblioteca padr ao de C++.


stl sequenciais associativos adaptativos streans

ios_base locale <ios>

<sstreambuf> <iomanip>

<vector> <list> <deque>

<set> <multiset> <map> <multimap>

<stack> <queue> <priority_queue> <istream>

<ostream>

<sstream>

<ofstream> <ifstream> <ostringstream> <istringstream> <iostream> <string>

matemticas

<bitset>

<complex>

<valarray>

<stringstream>

<fstream>

excees

exception

logic_error

bad_alloc

bad_cast

bad_exception

bad_typeid

runtime_error

out_of_range

lenght_error

invalid_argument

domain_error

ios_base::failure

underflow_error

overflow_error

range_error

31.1.1

Caracter sticas da STL

N ao utiliza polimorsmo em fun ca o do desempenho. Utiliza extensivamente os templates (veja Cap tulo 27 - Templates). Constru da basicamente sobre tr es conceitos: containers, iteradores e programa ca o gen erica (se ca o 31.1.2).

31.1.2

Componentes da STL

Containers: objeto utilizado para armazenar grupos de objetos (como <vector>). Veja introdu ca o aos containers na se ca o 31.2 e detalhes nos Cap tulos 32, 33 e 34. Iteradores: Vimos no Cap tulo 15 - Utiliza ca o de Ponteiros e Refer encias o uso de ponteiros. Veremos na se ca o 31.3 que iteradores s ao ponteiros inteligentes. Programa c ao gen erica: conjunto de fun co es que podem ser utilizadas com objetos e containers com os mais variados e gen ericos tipos de dados. Inclui fun co es para preenchimento, compara ca o, remo ca o, troca, mistura, pesquisa, ordena ca o, classica ca o e Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

AOS CONTAINERS 31.2. INTRODUC AO

545

transforma ca o dos containers e de seus elementos (veja Cap tulo 35 - Programa ca o Gen erica).

31.2

Introdu c ao aos containers

Se voc e tem um grupo de objetos do mesmo tipo ou de uma mesma hierarquia, pode organiz a-los por meio de um container. Um container e uma esp ecie de caixa onde objetos do mesmo tipo podem ser armazenados. Existem diferentes tipos de containers e a escolha do container mais adequado vai depender do que voc e pretende realizar sobre o seu grupo de objetos. Os containers podem ser divididos em tr es categorias: os seq uenciais (se ca o 31.2.1), os associativos (se ca o 31.2.2) e os adaptativos (se ca o 31.2.3). Estes containers e suas principais caracter sticas s ao descritos a seguir.

31.2.1

Containers sequ encias

Os containers seq uenciais s ao <vector>, <list> e <deque>. Estes s ao u teis para armazenar estruturas de dados (ou objetos) que est ao normalmente em seq u encia. Ser ao descritos no Cap tulo 32 - Containers Seq uenciais <vector>, <list> e <deque>. Veja na Figura 31.2 uma ilustra ca o dos containers seq uenciais. Figura 31.2: Containers seq uenciais - <vector>, <list>, <deque>.

Containers vector
0 1 2

Sequenciais
3 ... n-2 n-1

list

...

n-2

n-1

deque

...

n-2 n-1

Descrevemos a seguir o nome do container, suas caracter sticas b asicas e os iteradores suportados. <vector> O container <vector> funciona como um vetor comum permitindo acesso aleat orio (Figura 31.2). Tem r apida inser ca o de objetos no nal do vetor e lenta no meio. Suporta iterador de acesso rand omico. Ser a descrito na se ca o 32.1. <list> Utilize o container <list> quando precisar de uma lista de objetos em que novos objetos podem ser inclu dos em qualquer posi ca o, ou seja, tem inser ca o e dele ca o r apida em qualquer posi ca o (Figura 31.2). Lento para acesso rand omico. Suporta iterador de acesso bidirecional. Ser a descrito na se ca o 32.2. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

546

AOS CONTAINERS 31.2. INTRODUC AO <deque> Utilize o container <deque> quando precisar de uma lista de objetos em que novos objetos podem ser inclu dos em qualquer posi ca o (Figura 31.2). Tem as vantagens de <vector> uma la com duas pontas. Permite acesso aleat e <list>. E orio. Suporta iterador de acesso rand omico. Ser a descrito na se ca o 32.3.

31.2.2

Containers associativos

Os containers associativos funcionam com o conceito de chaves (keys ). Estes podem ser utilizados para armazenar um grupo de objetos que est ao sempre ordenados (container <set>), ou para relacionar uma determinada chave com um valor (container <map>). Os containers associativos est ao sempre ordenados; por default, o operador < e utilizado para ordena ca o. Ser ao descritos no Cap tulo 31 - Containers Associativos <set>, <multiset>, <map> e <multimap>. Veja na Figura 31.3 uma ilustra ca o dos containers associativos. Figura 31.3: Containers associativos - <set>, <multiset>, <map>, <multimap>.
Containers Associativos

<set> <map>

<multiset> <multimap>

<set> Um container <set> armazena um conjunto de chaves (sem repeti co es) e tem pesquisa r apida. Suporta iterador de acesso bidirecional. Ser a descrito na se ca o 34.2. <multiset> Um container <multiset> armazena um conjunto de chaves (com repeti co es) e tem pesquisa r apida. Suporta iterador de acesso bidirecional. Ser a descrito na se ca o 34.3. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

AOS CONTAINERS 31.2. INTRODUC AO

547

<map> Um container <map> armazena um conjunto de pares [chave, objeto] (sem repeti co es). Suporta iterador de acesso bidirecional. Ser a descrito na se ca o 34.4. <multimap> Um container <multimap> armazena um conjunto de pares [chave,objeto] (com repeti co es dos objetos, isto e, relacionamentos um para muitos, uma chave para muitos objetos). Suporta iterador de acesso bidirecional. Ser a descrito na se ca o 34.5.

31.2.3

Containers adaptativos

S ao containers criados a partir da adapta ca o de um container de seq u encia, ou seja, pode ser constru do tendo como base um <vector>, um <list> ou um <deque>. Ser ao descritos no Cap tulo 30 - Containers Adaptativos <stack>, <queue> e <priority_queue>. <stack> Um container <stack> funciona como uma pilha LIFO (last in, rst out ) (o u ltimo que entra e o primeiro que sai). Semelhante ` a pilha de uma calculadora HP. Pode ser constru do tendo como base um <vector>, <list> (default ) ou <deque>. N ao suporta iteradores. Ser a descrito na se ca o 33.1. <queue> Um container <queue> funciona como uma la FIFO (rst in, rst out ) (o primeiro que entra e o primeiro que sai). Pode ser constru do tendo como base um <vector>, <list> (default ) ou <deque>. N ao suporta iteradores. Ser a descrito na se ca o 33.2. <priority queue> Um container <priority_queue> funciona como uma la ordenada, onde quem sai e sempre o maior valor. Os elementos est ao sempre ordenados. Pode ser constru do tendo como base um <list> ou um <deque> (default ). N ao suporta iteradores. Ser a descrito na se ca o 33.3. J a descrevemos os diferentes tipos de containers, vamos descrever a seguir alguns m etodos/func o es e operadores que s ao comuns e est ao presentes em diversos containers.

31.2.4

M etodos e operadores comuns aos diversos containers

Alguns m etodos e operadores est ao presentes em todos os containers. Esses m etodos e operadores s ao listados na Tabela 31.1 e s ao ilustrados na Figura 31.4. Observe a presen ca de m etodos para inclus ao e elimina ca o de objetos, m etodos que retornam a dimens ao e capacidade do container. Os m etodos push_front() e push_back() s ao utilizados para adicionar ao container objetos no in cio e no m do container, respectivamente. Os m etodos pop_front(), erase() e pop_back() s ao utilizados para apagar objetos do container. Voc e pode obter c opias dos objetos utilizando front(), at() e back(). Para vericar o tamanho alocado do container, utilize capacity(), para obter o n umero de elementos utilizados, use size(), e para obter o limite m aximo que o container pode ter, utilize max_size().

31.2.5

M etodos v alidos apenas para os containers sequ enciais

Alguns m etodos s ao v alidos apenas para os containers seq uenciais e associativos. Esses m etodos s ao listadas a seguir. Os m etodos begin(), end(), rbegin() e rend() retornam iteradores. Veremos na se ca o 31.3 que iteradores s ao objetos ponteiros.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

548

AOS CONTAINERS 31.2. INTRODUC AO

Tabela 31.1: M etodos e operadores comuns a todos os containers. M etodo construtor default construtor de c opia destrutor empty() max_size() size() swap() operator= operator< operator<= operator> operator>= operator== operator!= Descri ca o Cada container tem um conjunto de construtores v alidos. Cria um container novo, uma c opia de um existente. Destr oi o container. Retorna true se o container estiver vazio. Retorna o n umero m aximo de elementos do container (valor alocado). Retorna o n umero de elementos utilizados. Troca todos os elementos do container. Atribue os elementos de um container a outro. Retorna true se C A e menor que C B (C A e o container A e C B o container B). Uso C A < C B. Retorna true se C A e menor ou igual a C B. Uso C A <= C B. Retorna true se C A e maior que C B. Uso C A > C B. Retorna true se C A e maior ou igual a C B. Uso C A >= C B. Retorna true se C A e igual a C B. Uso C A == C B. Retorna true se C A e diferente de C B. Uso C A != C B.

31.2.6

Typedefs comuns aos diversos containers2

Vimos na se ca o 9.5.1 que podemos usar typedefs para criar apelidos. Como as classes templates s ao usadas para criar tipos gen ericos (ex.: complex<float> c1;), para criar um objeto de uma classe template, tenho de usar NomeClasseGabarito<Tipo1, Tipo2,..> nomeObjeto; como no exemplo set< double, less<double> > objeto_double_set; posso criar um typedef para o comando anterior, typedef set< double, less<double> > double_set; podendo criar um objeto double_set usando: double_set objeto_double_set; Ou seja, com o uso de typedefs, podemos criar apelidos abreviados, o que facilita a digita ca o do programa. Pensando nisso, os elaboradores da STL inclu ram dentro das classes containers v arias instru co es do tipo typedef, estando algumas delas presentes em todos os containers. Estes typedefs s ao listados na Tabela 31.3. No exemplo a seguir usamos um typedef pr e-denido para criar um iterador para os elementos do container. A seguir usamos o iterador criado para varrer o container criado do in cio at e o m e enviar os valores do vetor para tela. Observe que o typedef, vector<int>::iterator e um apelido para im iterador. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

AOS ITERADORES - ITERATORS 31.3. INTRODUC AO

549

Figura 31.4: Exemplos de m etodos presentes em alguns containers. Incluso de Objetos:


0 1 2 3 ... n-2 n-1 n

push_front()

push_back()

Eliminao de Objetos:
0 1 2 3 ... i n-2 n-1

pop_front()

erase(i)

pop_back()

Obteno de Objetos:
0 1 2 3 ... n-2 n-1

back() front() size() capacity() max_size() at(3)

Dimenses e capacidades:

Exemplo: vector<int> v(10); // Cria vetor vector<int>::iterator it; // Cria iterador for(it = v.begin(); it != v.end(); it++) // Usa iterador cout < < *it < < endl; Nota: os iteradores ser ao descritos na se ca o 31.3.

31.3

Introdu c ao aos iteradores - iterators

O que e um iterador? Um iterador e um ponteiro inteligente, um objeto ponteiro. Os iteradores foram desenvolvidos para dar suporte aos containers j a descritos (veja se ca o 31.2). Lembre-se de que um ponteiro aponta para determinada posi ca o da mem oria, podendo ser utilizado para percorrer um vetor de objetos. Um iterador funciona da mesma maneira. Veja a seguir os diferentes tipos de iteradores e os operadores que s ao sobrecarregados para os iteradores.

31.3.1

Tipos de iteradores

Existe uma certa hierarquia entre os iteradores. Os dois mais simples s ao o input e o output, pois permitem apenas opera co es de leitura e escrita (respectivamente). A seguir vem o forward, que permite leitura e escrita (mas somente para frente). O iterador bidirecional permite leitura Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

550

AOS ITERADORES - ITERATORS 31.3. INTRODUC AO

Tabela 31.2: Iteradores e m etodos dos containers sequenciais. M etodo begin() end() Descri ca o Retorna um iterador (iterator ou const_iterator) para o primeiro objeto do container (posi ca o 0). Retorna um iterador (iterator ou const_iterator) para uma posi ca o posterior ao u ltimo objeto do container (este elemento n ao e utilizado e est a na posi ca o n). Retorna um iterador (iterator ou const_iterator) para o u ltimo objeto do container (posi ca o n - 1). Retorna um iterador (iterator ou const_iterator) para uma posi ca o anterior ao primeiro objeto do container (elemento n ao utilizado localizado na posi ca o -1). Apaga um ou mais objetos do container. Apaga todos os objetos do container.

rbegin() rend()

erase() clear()

e escrita tanto para frente quanto para tr as. O iterador mais poderoso e o random, que permite a leitura e escrita randomicamente.
input

forward output

bidirecional

random

Veja a seguir as caracter sticas dos iteradores: InputIterator: L e um objeto do container, move-se do in cio para o m do container (suporta somente uma passagem). OutputIterator: Escreve um objeto no container, move-se do in cio para o m do container (suporta somente uma passagem). ForwardIterator: Leitura e escrita somente para frente (suporta somente uma passagem). BidirecionalIterator: Leitura e escrita para frente e para tr as (suporta m ultiplas passagens). RandomAcessIterator: Leitura e escrita acessando randomicamente qualquer objeto do container. Dica: o acesso aos elementos de um container (como <list>, <map>, <set>) e mais r apido quando se usa um iterador. A excess ao e <vector> que e acessado mais rapidamente utilizando-se o operator[].

31.3.2

Opera c oes comuns com iteradores2

Algumas opera co es comuns aos diferentes tipos de iteradores s ao listadas a seguir: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

AOS ITERADORES - ITERATORS 31.3. INTRODUC AO

551

Tabela 31.3: Typedefs comuns aos diversos containers. typedef value_type size_type reference pointer iterator reverse_iterator alocator_type difference_type Descri ca o O tipo de elemento armazenado no container. Tipo usado para contar itens no container e indexar uma seq u encia de containers. Inv alido para <list>. Uma refer encia para o tipo armazenado no container. Um ponteiro para o tipo armazenado no container. Um iterador para o tipo armazenado no container. Um iterador reverso para o tipo armazenado no container. Tipo de gerenciamento de mem oria utilizado. N umero de elementos entre dois iteradores. N ao denido para os containers <list> e adaptativos (<stack>, <queue>, <priority_queue>). Um ponteiro constante para o tipo armazenado no container. Um iterador constante para o tipo armazenado no container. Um iterador reverso constante para o tipo armazenado no container.

const_pointer const_iterator const_reverse_ iterator

Iteradores de leitura (InputIterator) ++it it++ *it it = it1 it == it1 it != it1 Pr e-incremento (avan ca para pr oximo elemento do container). P os-incremento (avan ca para pr oximo elemento do container). Retorna objeto (desreferencia ponteiro). Atribue um iterador a outro. Compara se dois iteradores s ao iguais. Compara se dois iteradores s ao diferentes.

Iteradores de escrita (OutputIterator) ++it it++ *it it = it1 Pr e-incremento. Pos-incremento. Retorna objeto (desreferencia ponteiro). Atribue um iterador a outro.

Iteradores de avan co (ForwardIterator) ++it it++ *it it = it1 Pr e-incremento. Pos-incremento. Retorna objeto (desreferencia ponteiro). Atribue um iterador a outro. Andr e Duarte Bueno

Programa ca o Orientada a Objeto com C++

552 it == it1 it != it1 Compara se dois iteradores s ao iguais.

2 31.4. ITERADORES - USO AVANCADO

Compara se dois iteradores s ao diferentes.

Iteradores bidirecionais (BidirecionalIterator) ++it it++ - -it it- Pr e-incremento. Pos-incremento. Pr e-decremento (retorna para elemento anterior do container). P os-decremento.

Iteradores randomicos (RandomAcessIterator) ++it it++ it += i it -= i it + i it - i it[i] it1 < it2 Pr e-incremento. Pos-incremento. Iterador avan ca i posi co es. Iterador recua i posi co es. Retorna iterador avan cado i posi co es de it. Retorna iterador recuado i posi co es de it. Retorna refer encia ao objeto i. Verdadeiro, se it1 aponta para elemento anterior a it2.

it1<= it2 Verdadeiro, se it1 aponta para elemento anterior/igual a it2. it1 > it2 Verdadeiro, se it1 aponta para elemento acima de it2.

it1 >= it2 Verdadeiro, se it1 aponta para elemento acima/igual a it2. A utiliza ca o dos iteradores ser a esclarecida por meio dos exemplos, veja listagens 32.1, 34.2, 32.3, 35.1.

31.4

Iteradores - Uso avan cado2

Veremos nesta se ca o algumas dicas avan cadas para iteradores.

31.4.1

Iteradores de inser c ao

Algoritmos gen ericos como copy() n ao inserem novos elementos no container, os mesmos substituem os elementos antigos pelos novos. Com o objetivo de possibilitar a inclus ao de novos elementos em um container, a STL inclui iteradores espec cos para inser ca o de elementos, s ao eles: insert iterator(); Chama insert(pos,valor), para inserir o valor na posi ca o pos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

2 31.4. ITERADORES - USO AVANCADO

553

back insert iterator(); Chama push_back(valor), para inserir o valor no nal do container. front insert iterator(); Chama push_front(valor), para inserir o valor no in cio do container. O exemplo da listagem ?? mostra o uso de insert_iterator e de fun ca o predicado. Criamos a fun ca o predicado bool MaiorQue50(int valor), que retorna verdadeiro se valor for maior que 50. A seguir denimos uma fun ca o SeparaValores(), a mesma usa o iterador it do tipo back_insert_iterator. A fun ca o gen erica remove_copy_if() recebe v1, o iterador it e a fun ca o predicado, quando MaiorQue50() retorna verdadeiro, o valor de v1 e copiado para v2. Observe na sa da que os valores de v1 que n ao satisfazem a fun ca o predicado s ao inseridos em v2. Listing 31.1: Usando insert_iterator e fun ca o predicado.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 # include < iostream > # include < iomanip > # include < vector > # include < algorithm > # include < iterator > # include < functional > using namespace std ; // Fun c~ a o predicado , r e t o r n a true se valor > 50 bool MaiorQue50 ( int valor ) { return valor > 50; } // Recebe um vetor v1 e r e t o r n a v2 . vector < int > S e p a r a V e t o r e s ( vector < int >* v1 ) { vector < int > v2 ; // Cria i t e r a d o r de i n s e r c~ a o para v2 back_insert _ it e ra t o r < vector < int > > it ( v2 ) ; r e m o v e _ c o p y _ i f ( v1 - > begin () , v1 - > end () , it , MaiorQue50 ) ; return v2 ; } // S o b r e c a r g a operador < < como fun c~ ao template template < typename T > ostream & operator < <( ostream & os , vector <T > v ) { for ( int i = 0; i < v . size () ; i ++) os << v [ i ] << endl ; return os ; } int main () { // T e s t a n t o a fun c~ ao predicado cout << " MaiorQue50 (100) = " << MaiorQue50 (100) << " \ nMaiorQue5 0 ( 10) = " << MaiorQue50 ( 10) << endl ; // Cria v1 e a d i c i o n a v a l o r e s vector < int > v1 ; int data ; do { cout << " \ nEntre com o dado ( " << setw (3) << v1 . size () << " ) : " ; cin >> data ; cin . get () ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

554
46 47 48 49 50 51 52 53 54 55 if ( cin . good () ) v1 . push_back ( data ) ; } while ( cin . good () ) ;

31.5. SENTENCAS PARA STL E ITERADORES

cout << " \ nVetor v1 antes de S e p a r a V e t o r e s () :\ n " << v1 << endl ; vector < int > v2 ( S e p a r a V e t o r e s (& v1 ) ) ; cout << " Vetor v1 depois de S e p a r a V e t o r e s () :\ n " << v1 << " Vetor v2 depois de S e p a r a V e t o r e s () :\ n " << v2 << endl ; return 0; } [ b u e n o @ l d s c 0 5 Parte - III ] $ ./ a . out MaiorQue5 0 (100) = 1 MaiorQue5 0 ( 10) = 0 Entre Entre Entre Entre Entre com com com com com o o o o o dado dado dado dado dado ( ( ( ( ( 0) :50 1) :100 2) :150 3) :30 4) : S e p a r a V e t o r e s () :

Vetor v1 antes de 50 100 150 30

Vetor v1 depois de S e p a r a V e t o r e s () : 50 100 150 30 Vetor v2 depois de S e p a r a V e t o r e s () : 50 30

Veja exemplo de uso de istream_iterator, ostream_iterator e back_inserter na listagem 35.3

31.5

Senten cas para STL e iteradores

Sempre compare iteradores usando != e n ao <, pois o operador < s o esta sobrecarregado para iteradores rand omicos. Ao usar incremento e decremento com iteradores, prera as vers oes pr e-xadas. Isto e, troque it++ por ++it e it- - por - -it. Pode-se iterar do u ltimo elemento para o primeiro elemento do container usando-se um reverse_iterator ou um const_reverse_iterator. Os containers que suportam o uso de iteradores bidirecionais aceitam o uso de insert_iterator, back_insert_iterator e front_insert_iterator para inserir elementos em um container. Veja listagem listagm 31.1. Como a STL faz parte da biblioteca-padr ao de C++, todas as distribui co es de C++ devem inclu -la, de forma que usar a STL garante maior portabilidade aos seus programas. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

PREDICADO 31.6. FUNC AO

555

31.6

Fun c ao predicado

Um predicado e uma fun ca o que recebe como par ametro um elemento do container, realiza determinada opera ca o e retorna o valor true/false. O prot otipo e um exemplo de uso de uma fun ca o predicado e apresentado a seguir: Prot otipo: bool fun c~ aoPredicado(Tipo x); Exemplo: bool MaiorQue10(int x) { return x > 10; }

31.7

Resumo do cap tulo

Apresentamos neste cap tulo a STL, a biblioteca padr ao de gabaritos de C++, suas caracter sticas e componentes. Iniciamos com uma introdu ca o aos diferentes tipos de containers: os containers seq uenciais <vector>, <list>, <deque>, os containers adaptativos <stack>, <queue>, <priority_queue>, e os containers associativos <set>, <multiset>, <map>, <multimap>. Aprendemos a diferenciar os containers e a identicar qual devemos utilizar. Vimos ainda os m etodos e operadores que s ao comuns aos diversos containers, isto e, os m etodos que est ao presentes em todos os containers, sendo muito utilizados. Observe que o fato de terem os mesmos nomes nos diferentes containers facilita seu uso, pois temos de decorar poucos nomes. Aprendemos que alguns m etodos s ao v alidos apenas para os containers seq uenciais. Vimos ainda as deni co es de tipo - typedefs - que s ao comuns aos diversos containers. No nal do cap tulo vimos uma introdu ca o aos iteradores (iterators), os famosos - ponteiros inteligentes - seus tipos e opera co es comuns. Nos pr oximos cap tulos iremos aprender a utilizar em detalhes os containers, os iteradores e os c odigos gen ericos. Nota: veja no Ap endice I - Links para Sites em C++, um conjunto de endere cos de sites que descrevem a STL em detalhes.

31.8

Exerc cios

1. Comente as caracter sticas da STL. 2. Para um sistema de processamento de dados de uma conta corrente de um banco, qual tipo de container deve ser utilizado? 3. Qual o container ideal para acesso aleat orio? 4. Preciso incluir e eliminar objetos o tempo todo, qual container devo selecionar? 5. Vou montar um programa que simula uma calculadora HP, qual container devo utilizar? 6. Quais os m etodos comuns a todos os containers? 7. O que faz o m etodo begin(). 8. Qual a vantagem do uso de typedefs com containers? 9. Fa ca uma lista dos iteradores e suas caracter sticas. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

556

31.8. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 32

Os Containers Sequ enciais <vector>, <list>, <deque>


Mostraremos neste cap tulo os containers seq uenciais <vector> (se ca o 32.1), <list> (sec a o 32.2) e <deque> (se ca o 32.3). O container <vector> ser a apresentado em detalhes. Os demais containers ser ao apresentados de forma simplicada, pois as suas caracter sticas s ao semelhantes ` as de <vector>. Isto signica que voc e deve ler este cap tulo com aten ca o redobrada, pois seus conceitos se aplicam aos demais containers. Como o conjunto de m etodos fornecidos por cada container e grande, n ao tente decorar nada, apenas preste aten ca o ao conceito. Com os exemplos, voc e ir a aprender a utilizar as classes container com facilidade.

32.1

A classe container <vector>

J a apresentamos brevemente a classe container <vector> nas se co es 9.4.2 e 31.2.1. O container <vector> funciona como um vetor comum, ou seja, os blocos com os elementos est ao cont guos, permitindo acesso aleat orio (iteradores rand omicos). Como em vetores comuns de C, <vector> n ao verica os ndices. Para usar um objeto container do tipo <vector>, inclua o arquivo de cabe calho <vector>. Exemplo: #include <vector> A classe container <vector> e uma classe template declarada da forma: template < typename Tipo, typename Allocator=allocator<Tipo> > class vector{...}; ou seja, recebe o tipo de elemento a ser armazenado e o tipo de aloca ca o a ser utilizada. Veja a seguir os diversos m etodos disponibilizados por <vector>. Primeiro, veremos os construtores, os iteradores e as refer encias, e, depois, os m etodos usuais de <vector>. A Figura 32.1 apresenta um diagrama mostrando os m etodos para inclus ao, obten ca o e elimina ca o de objetos em um container <vector>. 557

558

32.1. A CLASSE CONTAINER <VECTOR>

Nota: na descri ca o dos m etodos, nos prot otipos e exemplos apresentados nesta parte do livro procuramos adotar um padr ao. T e um tipo qualquer, um sin onimo para Tipo; size_type e a dimens ao dos objetos armazenados no container; x,y,z, e e1,e2,e3, s ao elementos do container; n,pos indica uma posi ca o a ser acessada; c,co,c1,c2,c3 s ao objetos containers; cd, d, dest e o container destino; it, it1, it2 s ao iteradores que apontam para elementos do container no intervalo [first, last), ou seja, inclui first e exclue last. O iterador first aponta para o primeiro elemento do container (o mesmo que v.begin()). O iterador last aponta para o elemento n do container, elemento inv alido (o mesmo que v.end()). fpred e uma fun ca o predicado, e uma fun ca o que recebe um elemento do container, realiza determinada opera ca o e retorna 0 ou 1. Alloc e um objeto do tipo allocator_type, usado para aloca ca o de mem oria.

Figura 32.1: M etodos disponibilizados para <vector>.


Incluso de Objetos:
0 1 2 3 ... n-2 n-1 n

push_back()

Eliminao de Objetos:
0 1 2 3 i n-2 n-1

erase(i)

pop_back()

Obteno de Objetos:
0 1 2 3 ... n-2 n-1

back() front() at(3)

espao reservado

Dimenses e capacidades:
size() capacity() max_size() reserve()

32.1.1

Construtores e destrutor

vector<Tipo> (); Cria um vetor para o tipo T com tamanho zero. Complexidade constante. Exemplo: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

32.1. A CLASSE CONTAINER <VECTOR> vector< int > v_int1();

559

vector<Tipo> (size type n, const T& x = T()); Cria um vetor para o tipo com tamanho n, com n c opias do valor T(). Se o valor do elemento x n ao for passado, utiliza o construtor default da classe para construir o objeto. Complexidade linear. No exemplo a seguir v_float1 tem 17 elementos, todos iguais a 3.55. Exemplo: vector< int > v_int2 (15); vector< float > v_float1 (17,3.55); vector<Tipo> (const vector<T>& v); Construtor de c opia, cria uma c opia do vetor v. Exemplo: vector< float > v_float2 (v_float1); vector<Tipo> (InputIterator rst, InputIterator last); Cria um vetor com o tamanho dado pela diferen ca last-rst, com os valores a partir de rst. Observe que rst se refere ao primeiro elemento do container a ser considerado, e last se refere ao ultimo elemento (last n ao e inclu do no container). Complexidade linear. Exemplo: vector< float > v_float3 (v_float1.begin(), v_float1.end()); vector (); Destrutor de < vector >. Complexidade linear.

32.1.2

Iteradores de <vector>

A chamada a um m etodo que retorna um iterador, como begin(), ou end() (veja Figura 32.2), ir a retornar um const_iterator se o objeto destino e do tipo const. Um const_iterator pode ser utilizado para acessar os elementos do container no modo ready-only. A Figura 32.2 apresenta um diagrama mostrando os m etodos que retornam iteradores. Por exemplo, o m etodo begin() retorna um iterator que aponta para o primeiro elemento do container. A maioria das fun co es gen ericas recebe como par ametros os iteradores begin() e end() e usa-os para varrer todo o container. Observe que as fun co es s ao executadas para begin(), porque begin() aponta para o primeiro elemento do container, e n ao s ao executadas para end(), porque end() aponta para um elemento inv alido (veja Figura 32.2). Nota: todos os m etodos abaixo tem complexidade constante. iterator begin(); Retorna um iterador rand omico para o primeiro objeto do container (veja Figura 32.2). iterator end(); Retorna um iterador rand omico para posi ca o n (elemento inv alido). reverse iterator rbegin(); Retorna um iterador rand omico reverso para o u ltimo objeto v alido (posi ca o n-1). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

560

32.1. A CLASSE CONTAINER <VECTOR>

Figura 32.2: M etodos que retornam iteradores.


rend() begin() Iteradores: rbegin() end()

-1

...

n-2

n-1

reverse iterator rend(); Retorna um iterador rand omico para posi ca o -1 (elemento inv alido). const iterator begin() const; Retorna um iterador rand omico e constante para posi ca o 0. const iterator end() const; Retorna um iterador rand omico e constante para posi ca o n (elemento inv alido). const reverse iterator rbegin() const; Retorna um iterador rand omico reverso constante para o u ltimo objeto v alido (posi ca o n-1). const reverse iterator rend() const; Retorna um iterador rand omico e constante para posi ca o -1 (elemento inv alido).

32.1.3

Refer encias e acesso

reference front(); Retorna uma refer encia ao primeiro elemento (veja Figura 32.1). operator[] (size type n); Retorna uma refer encia ao objeto armazenado na casa n (n ao verica o intervalo). S o e v alido para <vector> e <deque>. at(size type n); Retorna uma refer encia ao objeto n; at() testa o intervalo. reference back(); Retorna uma refer encia ao u ltimo elemento. const reference front() const; Retorna uma refer encia constante ao primeiro elemento. const reference operator[] (size type n) const; Retorna uma refer encia constante ao objeto n (veja Figura 32.1). const reference at(size type n) const; Retorna uma refer encia constante ao objeto n (veja Figura 32.1). const reference back() const; Retorna uma refer encia constante ao u ltimo elemento (veja Figura 32.1). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

32.1. A CLASSE CONTAINER <VECTOR>

561

32.1.4

Operadores

vector<T>& operator= (const vector<T>& v); Operador de atribui ca o. Apaga todos os elementos do container e depois copia os valores de v para o container this. Retorna uma refer encia para o conjunto. Complexidade linear.

32.1.5

Capacidade e redimensionamento

Todos os m etodos desta se ca o tem complexidade constante. size type size() const; Retorna o n umero de elementos utilizados pelo container (veja Figura 32.1). size type capacity() const; Retorna o tamanho alocado do container (mem oria alocada) (veja Figura 32.1). size type max size() const; Retorna o tamanho do maior vetor poss vel. Depende da quantidade de mem oria dispon vel em seu computador (veja Figura 32.1). void reserve(size type sz); Dene a capacidade do container em sz elementos. Muda a capacidade do container mas u n ao muda o size. E til quando voc e sabe que ir a adicionar um determinado n umero de elementos ao container, pois evita a realoca ca o do container a cada nova inclus ao. Se sz for menor que a capacidade atual do container, a realoca ca o n ao e realizada (veja Figura 32.1). void resize(size type sz, T e = T()); Altera o tamanho do container (o size). Se o novo tamanho (sz) for maior que o atual, os novos elementos s ao inseridos no nal do vetor. Se o novo tamanho for menor que o atual, os elementos excedentes s ao eliminados. bool empty() const; Retorna true se o container est a vazio.

32.1.6

Inser c ao, dele c ao e atribui c ao

A Figura 32.1 apresenta um diagrama mostrando os m etodos para inclus ao, obten ca o e elimina ca o de objetos em um container <vector>. iterator insert(iterator pos, const T& x = T()); Insere o objeto x, antes da posi ca o pos denida pelo iterador. void insert(iterator pos, size type n, const T& x = T()); Insere n c opias de x antes da posi ca o pos. void insert(iterator pos, InputIterator rst, InputIterator last); Insere c opia dos elementos no intervalo [rst, last) antes da posi ca o pos. void push back(const T& x); Insere uma c opia de x no nal do container. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

562 void erase(iterator pos); Remove o elemento da posi ca o pos. Exemplo: v.erase ( v.begin() + 5 );

32.1. A CLASSE CONTAINER <VECTOR>

void erase(iterator rst, iterator last); Remove os elementos no intervalo [inclusive rst, excluindo last), ou seja, de rst a last-1. A complexidade e fun ca o do tipo de container. void pop back(); Remove o u ltimo elemento (sem retorno). void clear(); Apaga todos os elementos do container. Complexidade linear. void assign(InputIterator rst, InputIterator last); Apaga todos os elementos do container e insere os novos elementos do intervalo [rst, last). void assign(Size n, const T& x = T()); Apaga todos os elementos do container e insere os n novos elementos com o valor de x. void swap(vector<T>& v); Troca os elementos dos dois containers ( e mais r apida que a swap gen erica). Complexidade constante. Exemplo: v1.swap(v2);

32.1.7

Operadores sobrecarregados

bool operator== (const vector<T>& v1, const vector <T>& v2); O operador == retorna true se o container v1 e igual ao container v2 (se cada elemento e igual). bool operator< (const vector<T>&v1, const vector<T>& v2); O operador < retorna true se os elementos contidos em v1 s ao lexicographically menores que os elementos contidos em v2. Os outros operadores sobrecarregados s ao: !=, <=, >=. Dica: para que qualquer um dos operadores ==, !=, possam ser utilizados, e necess ario que o tipo armazenado tenha suporte ao operador (==). Para que qualquer um dos operadores >, <, >=, <=, possam ser utilizados e necess ario que o tipo armazenado tenha suporte ao operador <.

32.1.8

Exemplo de <vector>

Neste momento, voc e pode rever o exemplo de <vector> apresentado na listagem 9.8. A listagem 32.1 mostra a utiliza ca o de <vector>.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

32.1. A CLASSE CONTAINER <VECTOR> Listing 32.1: Usando <vector>.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 # include < iostream > # include < iomanip > # include < vector > using namespace std ; // D e c l a r a c~ a o da s o b r e c a r g a do o p e r a d o r << , uso cout << v ; ostream & operator << ( ostream & os , const vector < int >& v ) ; int main () { vector < int > v ;

563

// Cria vector , do tipo int , com nome v

int data ; cout << " No DOS um ctrl + z encerra a entrada de dados .\ n " << " No Mac um ctrl + d encerra a entrada de dados .\ n " << " No GNU / Linux um ctrl + d encerra a entrada de dados .\ n " ; do { cout << " \ nEntre com o dado ( " << setw (3) << v . size () << " ) : " ; cin >> data ; cin . get () ; if ( cin . good () ) v . push_back ( data ) ; } while ( cin . good () ) ; cout << " \ n " << v << endl ; v [0] = 23427; v . insert ( v . begin () + 2 , 5463) ; cout << " \ nAp o s v [ 0 ] = 23427; e v . insert ( v . begin () + 2 , 5463 ) ;\ n " << v << endl ; // Chama fun c~ a o erase () do objeto v p a s s a n d o p o s i c~ a o v . begin () v . erase ( v . begin () ) ; cout << " \ nAp o s v . erase ( v . begin () ) ;\ n " << v << endl ; // Chama v . erase ( cout << << fun c~ a o erase () do objeto v p a s s a n d o v . begin () +1 e v . end () -1 v . begin () +1 , v . end () -1) ; " \ nAp o s v . erase ( v . begin () +1 , v . end () -1 ) ;\ n " " o vetor esta " << ( v . empty () ? " vazio " : " com elementos " ) << endl ;

// Chama fun c~ a o clear () v . clear () ; cout << " o vetor esta " << ( v . empty () ? " vazio " : " com elementos " ) << endl ; return 0; } // D e f i n i c~ a o da s o b r e c a r g a do o p e r a d o r << para m o s t r a r e l e m e n t o s do vetor . ostream & operator < < ( ostream & os , const vector < int >& v ) { for ( int i = 0; i < v . size () ; i ++) os << " v [ " << setw (3) << i << " ]= " << setw (5) << v [ i ] << ; return os ; }

[ a n d r e @ m e r c u r i o Cap4 - STL ] $ g ++ ex - vector -2. cpp [ a n d r e @ m e r c u r i o Cap4 - STL ] $ ./ a . out No DOS um ctrl + z encerra a entrada de dados . No Mac um ctrl + d encerra a entrada de dados . No GNU / Linux um ctrl + d encerra a entrada de dados . Entre com o dado ( 0) :0 Entre com o dado ( 1) : -1

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

564
Entre com o dado ( 2) : -2 Entre com o dado ( 3) : -3 Entre com o dado ( 4) : v [ 0]= 0 v [ 1]= -1 v [

32.1. A CLASSE CONTAINER <VECTOR>

2]=

-2 v [

3]=

-3

Ap o s v [ 0 ] = 23427; e v . insert ( v . begin () + 2 , 5463 ) ; v [ 0]=23427 v [ 1]= -1 v [ 2]= 5463 v [ 3]= -2 v [ 4]= Ap o s v . erase ( v . begin () ) ; v [ 0]= -1 v [ 1]= 5463 v [

-3

2]=

-2 v [

3]=

-3

Ap o s v . erase ( v . begin () +1 , v . end () -1 ) ; o vetor esta com elementos o vetor esta vazio

Reveja agora a listagem 30.5 que mostra o uso de <vector> com <bitset>.

32.1.9

Senten cas para <vector>

Se n ao for mudar o container, utilize iteradores do tipo const. Note que v.begin() retorna um iterador normal ou constante, veja o exemplo: Exemplo: vector<int> v(10); // Retorna iterador normal vector<int>::iterator it = v.begin(); // Retorna iterador constante vector<int>::const_iterator cit = v.begin(); Sempre reserve um espa co inicial para o vetor, ou seja, procure evitar a realoca ca o a cada inser ca o, alocando todo o bloco que ir a utilizar de uma u nica vez. Os m etodos devem receber <vector> como refer encia para evitar c opias desnecess arias. Exemplo: void funcao(vector<int> & v); Se a classe n ao tem um construtor default, um <vector> s o pode ser criado passando-se o construtor com par ametros. Exemplo: // Construtor com par^ ametros class TUsuario{ TUsuario(int x){...}; }; vector< TUsuario > vet( 200, TUsuario(5) ); Os m etodos assign() s ao utilizados complementarmente aos construtores. O n umero de elementos do vetor ser a aquele passado para assign(). Se o m etodo espera um iterator, voc e n ao deve passar um reverse_iterator. Para converter um reverse_iterator em um iterator, utilize o m etodo base(). Exemplo: reverse_iterator ri; iterator it = ri.base(); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

32.2. A CLASSE CONTAINER <LIST> Se for inserir objetos no meio do vetor, pense em utilizar uma lista (<list>). A classe <vector> n ao possui os m etodos push_front(), pop_front() e front(). Para retornar um vetor de inteiros como refer encia: Exemplo: vector<int>& NomeM etodo(vector<int>& v) {... return v;}

565

O operador ++it retorna uma refer encia ao elemento do container. O operador it++ retorna uma c opia do elemento do container. Para evitar aloca co es desnecess arias ao usar push_back(), reverve um espa co m nimo com reserve(). Para saber o n umero de elementos alocados mas n ao utilizados use capacity()-size(). Observe que a classe string se comporta como um vetor de caracteres. Os containers j a v em com os operadores < e == sobrecarregados. Voc e pode sobrecarregar >, !=, <= e >=, ou utilizar o comando using namespace std::rel_ops; para incluir a sobrecarga desses operadores. Exemplo: #include <utility> using namespace std::rel_ops; Observe que <vector> e <deque> s ao acessados mais rapidamente com o operador[], <list>, <map>, e <set> s ao acessados mais rapidamente utilizando um iterador.

32.2

A classe container <list>

Utilize <list> quando precisar de um container em que novos objetos podem ser inclu dos em qualquer posi ca o. A Figura 32.3 mostra os m etodos disponibilizados para <list>. O container <list> e lento para acesso rand omico, mas e otimizado para inser ca o e remo ca o de elementos em qualquer posi ca o (<list> suporta iterador bidirecional). Um <list> fornece todos os m etodos de um <vector>, com exce ca o de at[], capacity() e reserve(), e acrescenta m etodos novos, como front(), push_front(), pop_front() e insert(pos,elem). <list> n ao tem o operador[], e os iteradores de <list> n ao suportam opera co es aritm eticas, como it+5.

32.2.1

Construtores e destrutor

list(); Cria uma lista vazia. list(size type n, const T& x = T()); Cria uma lista com tamanho n, com n c opias do valor x. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

566

32.2. A CLASSE CONTAINER <LIST>

Figura 32.3: M etodos disponibilizados para <list>.


Incluso e obteno de Objetos:

...

n-2

n-1

front() push_front()

back()

push_back()

Eliminao de Objetos:
0 1 n-2 n-1

pop_back() pop_front()

Dimenses e capacidades:
size() max_size()

list(InputIterator rst, InputIterator last); Cria uma lista do tamanho de last-rst, com os valores de [rst a last). list(const list<T>& l); Cria uma c opia da lista l (construtor de c opia). list(); Destrutor de <list>.

32.2.2

Operadores

list<T>& operator= (const list<T>& l) Operador de atribui ca o. Apaga todos os elementos do container e depois copia os valores de l para o container this. Retorna uma refer encia para o conjunto.

32.2.3

Refer encia e acesso

reference front(); Retorna uma refer encia para o primeiro elemento. Veja Figura 32.3. void pop front(); Remove o primeiro elemento. Veja Figura 32.3. push front(const T& x); Adiciona uma c opia de x no in cio da lista (novo primeiro elemento). Veja Figura 32.3.

32.2.4

Inser c ao, mistura e ordena c ao

void splice(iterator pos, list<T>& l); Insere a lista l antes da posi ca o pos denida pelo iterador. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

32.2. A CLASSE CONTAINER <LIST> void splice(iterator pos, list<T>& l, iterator it); Move de list[i] para posi ca o pos.

567

void splice(iterator pos, list<T>& l, iterator rst, iterator last); Move os elementos no intervalo [rst, last) da lista l para esta lista, inserindo o elemento antes da posi ca o pos. void merge(list<T>& l); Mistura esta lista com a lista l, os valores s ao ordenados com o operador <. Se existirem elementos iguais nas duas listas, os elementos desta lista precedem, a lista l car a vazia. void merge(list<T>& l, Compare comp); Mistura esta lista com a lista l; usando fun ca o de compara ca o. Se existirem elementos iguais nas duas listas, os elementos desta lista (this) precedem, e a lista l car a vazia. void sort(); Ordena de acordo com o operador <. Elementos iguais s ao mantidos na mesma ordem. void sort(Compare comp); Ordena a lista de acordo com a fun ca o de compara ca o comp. void insert(iterator pos, Tipo obj); Insere na posi ca o pos o objeto.

32.2.5

Remo c ao e c opia u nica

void unique(); Move todos os elementos repetidos para o m do container e seta size como sendo o ndice do u ltimo elemento n ao duplicado. Antes de executar unique(), execute um sort(). void unique(Fun c aoPredicado fpred); Apaga elementos consecutivos com a condi ca o true dada pela fun ca o predicado fpred. A primeira ocorr encia n ao e eliminada. Exemplo: bool MaiorQue10(int x) { return x > 10; } ... lista.unique(MaiorQue10); void remove(const T& x); Remove os elementos do container que t em o valor x. c aoPredicado fpred); void remove if(Fun Remove os elementos do container que satisfazem ` a fun ca o predicado fpred. Exemplo: // Remove da lista os objetos que tem a primeira letra ==p. list.remove_if( initial(p) ); void reverse(); Inverte a ordem dos elementos do container. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

568

32.2. A CLASSE CONTAINER <LIST>

32.2.6

Exemplo de <list>

Veja na listagem 32.2 um exemplo de utiliza ca o de <list>. Observe na fun ca o de sobrecarga do operador de extra ca o (< <) o uso de um iterador. A listagem 32.2 inicia-se declarando a fun ca o de sobrecarga do operador < <; esta recebe uma ostream (como cout) e uma refer encia para um container do tipo lista para n umeros float (const std::list<float>& list). Como dito anteriormente, cada container fornece iteradores para acesso aos seus elementos. Neste exemplo, a linha std::list<float>::const_iterator it; e utilizada para criar um iterador do tipo std::list<float>::const_iterator com o nome it. Dentro do for, o iterador it que inicialmente aponta para o primeiro elemento do container it=lista.begin(); e utilizado para percorrer os elementos do container usando it++ e envi a-los para a sa da os < < *it < < ;. Quando o iterador it chegar ao m do container, isto e, it != lista.end(), o for e encerrado. Listing 32.2: Usando <list>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 # include # include # include # include < iostream > < string > < list > < algorithm > // Listas // A l g o r i t m o g e n erico

using namespace std ; // D e c l a r a c~ a o da s o b r e c a r g a do o p e r a d o r de e x t r a c~ a o << para list // Mostra lista . Com vector foi p o s s v e l usar v [ i ] , uma lista n~ a o aceita l [ i ] , // p r e c i s a de um iterator , como a seguir . template < typename T > ostream & operator << ( ostream & os , const std :: list < T >& lista ) { typename std :: list < T >:: c o n s t _ i t e r a t o r it ; for ( it = lista . begin () ; it != lista . end () ; it ++) os << * it << ; return os ; } // D e f i n i c~ a o da fun c~ a o main () int main () { string linha = " \n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\ n " ; // C r i a c~ a o de uma lista para float std :: list < float > clist ; clist . push_front (312.1 f ) ; // Inclui v a l o r e s na lista clist . push_back (313.4 f ) ; clist . push_back (316.7 f ) ; clist . push_front (312.1 f ) ; clist . push_front (313.4 f ) ; clist . push_front (314.1 f ) ; clist . push_front (315.1 f ) ; cout << linha << " Conte u do do container : \ n " << clist << linha << endl ; // E l i m i n a p r i m e i r o e l e m e n t o da lista clist . pop_front () ; cout << " Conte u do do container ap o s : clist . pop_front () ; \ n " << clist << linha << endl ; // E l i m i n a u ltimo e l e m e n t o da lista clist . pop_back () ; cout << " Conte u do do container ap o s : clist . pop_back () ; \ n " << clist << linha << endl ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

32.2. A CLASSE CONTAINER <LIST>


45 46 47 48 49 50 51 52 53 54 55 56 57

569

// Ordena o c o n t a i n e r clist . sort () ; cout << " Conte u do do container ap o s : clist . sort () ; \ n " << clist << linha << endl ; // Move os e l e m e n t o s r e p e t i d o s para o final do c o n t a i n e r // e seta como u ltimo e l e m e n t o v a lido , o u ltimo e l e m e n t o n~ ao repetido. clist . unique () ; cout << " Conte u do do container ap o s : clist . unique () ; \ n " << clist << linha << endl ; return 0; }

[ a n d r e @ m e r c u r i o Cap4 - STL ]# ./ a . out -------------------------------------------------Conte u do do container : 315.1 314.1 313.4 312.1 312.1 313.4 316.7 -------------------------------------------------Conte u do do container ap o s : c o n t a i n e r _ l i s t . pop_front () ; 314.1 313.4 312.1 312.1 313.4 316.7 -------------------------------------------------Conte u do do container ap o s : c o n t a i n e r _ l i s t . pop_back () ; 314.1 313.4 312.1 312.1 313.4 -------------------------------------------------Conte u do do container ap o s : c o n t a i n e r _ l i s t . sort () ; 312.1 312.1 313.4 313.4 314.1 -------------------------------------------------Conte u do do container ap o s : c o n t a i n e r _ l i s t . unique () ; 312.1 313.4 314.1 --------------------------------------------------

Na listagem 32.3 apresentamos o uso de m etodos de <list> como sort(), splice(), merge(), unique(), swap(), assign(), e remove(). No Cap tulo 22 - Entrada e Sa da, aprendemos que as streams s ao utilizadas para enviar e receber dados. Que uma ostream e uma stream utilizada para sa da de dados (output stream ). Vimos que um iterator e uma esp ecie de ponteiro inteligente utilizado para acessar os diversos objetos armazenados no container. Da , conclu mos que um ostream_iterator e um iterador que ser a utilizado para percorrer os elementos do container e os enviar para uma sa da. No exemplo da listagem 32.3, criamos um ostream_iterator na linha: std::ostream_iterator < float > output (cout, " "); e usamos a fun ca o gen erica copy(), para copiar todos os elementos do container para a sa da out. O caracter " " e utilizado como separador. copy (clist1.begin(), clist1.end(), output); A fun ca o copy() e uma fun ca o gen erica (apresentada no Cap tulo 35 - Algoritmos Gen ericos), que ir a percorrer o container do in cio (cset.begin()) ao m (cset.end()), utilizando o iterador out, que envia cada objeto do container para a tela usando cout. Listing 32.3: Usando <list> com as fun co es gen ericas (algoritmos gen ericos).
1 2 3 4 # include < iostream > # include < list > # include < iterator > using namespace std ; // Classe de listas // I t e r a d o r e s // Uso do n a m e s p a c e std

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

570
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

32.2. A CLASSE CONTAINER <LIST>

int main () // D e f i n i c~ a o da fun c~ a o main () { // Cria um i t e r a d o r para ostream , usa cout para enviar floats para tela o s t r e a m _ i t e r a t o r < float > output ( cout , " " ) ; // C r i a c~ a o de duas listas para float std :: list < float > clist1 , clist2 ; // Inclui v a l o r e s na lista clist1 . push_front (312.1 f ) ; clist1 . push_front (312.1 f ) ; clist1 . push_back (313.4 f ) ; clist1 . push_back (316.7 f ) ; // Mostra lista cout << " \ nConte u do do container clist1 : " ; copy ( clist1 . begin () , clist1 . end () , output ) ; // Ordena lista clist1 . sort () ; cout << " \ nConte u do do container clist1 ap o s sort () : " ; copy ( clist1 . begin () , clist1 . end () , output ) ; // A d i c i o n a e l e m e n t o s a lista2 clist2 . push_front (22.0) ; clist2 . push_front (2222.0) ; cout << " \ nConte u do do container clist2 ap o s push_front () : " ; copy ( clist2 . begin () , clist2 . end () , output ) ; // Fun c~ a o splice ( A d i c i o n a ao final de clist1 os v a l o r e s de clist2 ) clist1 . splice ( clist1 . end () , clist2 ) ; cout << " \ nConte u do do container clist1 ap o s splice () : " ; copy ( clist1 . begin () , clist1 . end () , output ) ; // M i s t u r a as duas listas , c o l o c a n d o tudo em clist2 clist1 . merge ( clist2 ) ; cout << " \ nConte u do do container clist1 ap os copy ( clist1 . begin () , clist1 . end () , output cout << " \ nConte u do do container clist2 ap os copy ( clist2 . begin () , clist2 . end () , output clist1 e e l i m i n a n d o tudo de

merge () : " ; ); merge () : " ; );

// E l i m i n a v a l o r e s d u p l i c a d o s clist1 . unique () ; cout << " \ nConte u do do container clist1 ap o s unique () : " ; copy ( clist1 . begin () , clist1 . end () , output ) ; // Chama f u n c~ oes pop_front e pop_back clist1 . pop_front () ; // E l i m i n a p r i m e i r o e l e m e n t o da lista clist1 . pop_back () ; // E l i m i n a ultimo e l e m e n t o da lista cout << " \ nConte u do do container clist1 ap o s pop_front () e pop_back () : " ; copy ( clist1 . begin () , clist1 . end () , output ) ; // Troca tudo entre as duas listas clist1 . swap ( clist2 ) ; cout << " \ nConte u do do container clist1 ap os copy ( clist1 . begin () , clist1 . end () , output cout << " \ nConte u do do container clist2 ap os copy ( clist2 . begin () , clist2 . end () , output // A t r i b u i v a l o r e s de clist2 em clist1

swap () : " ; ); swap () : " ; );

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

32.3. A CLASSE CONTAINER <DEQUE>


66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 clist1 . assign ( clist2 . begin () , clist2 . end () ) ; cout << " \ nConte u do do container clist1 ap o s assign () : copy ( clist1 . begin () , clist1 . end () , output ) ; // M i s t u r a n o v a m e n t e clist1 . merge ( clist2 ) ; cout << " \ nConte u do do container clist1 ap o s merge () : " ; copy ( clist1 . begin () , clist1 . end () , output ) ; // Remove e l e m e n t o na p o s i c~ ao 2 clist1 . remove (2) ; cout << " \ nConte u do do container clist1 ap o s remove () : " ; copy ( clist1 . begin () , clist1 . end () , output ) ; cout << endl ; return 0; } Conte u do Conte u do Conte u do Conte u do Conte u do Conte u do Conte u do Conte u do Conte u do Conte u do Conte u do Conte u do Conte u do do do do do do do do do do do do do do container container container container container container container container container container container container container clist1 : 312.1 312.1 313.4 316.7 clist1 ap o s sort () : 312.1 312.1 313.4 316.7 clist2 ap o s push_front () : 2222 22 clist1 ap o s splice () : 312.1 312.1 313.4 316.7 2222 22 clist1 ap o s merge () : 312.1 312.1 313.4 316.7 2222 22 clist2 ap o s merge () : clist1 ap o s unique () : 312.1 313.4 316.7 2222 22 clist1 ap o s pop_front () e pop_back () : 313.4 316.7 2222 clist1 ap o s swap () : clist2 ap o s swap () : 313.4 316.7 2222 clist1 ap o s assign () : 313.4 316.7 2222 clist1 ap o s merge () : 313.4 313.4 316.7 316.7 2222 2222 clist1 ap o s remove () : 313.4 313.4 316.7 316.7 2222 2222

571

";

32.2.7

Senten cas para <list>

Uma lista n ao aceita (iterator + n). Voc e precisa fazer iterator++, n vezes. Objetos eliminados de <list> s ao deletados. <list> n ao aceita subscript[], reserve() e capacity(). <list> inclui splice(pos,& x); move o objeto x para a posic ao pos. Utilize <list> sempre que precisar de inser ca o e remo ca o r apida. Utilize merge(list & ); para mesclar listas. Para criar uma lista de vetores: Exemplo: std::list< std::vector<int> > nomeLista;

32.3

A classe container <deque>

Um container <deque> e uma la com duas extremidades. Une parte das vantagens das listas <list> e dos vetores <vector>. Tem r apida inser ca o na frente e atr as. De uma maneira geral s ao alocados blocos de mem oria que s o s ao deletados quando o container e destru do. Tem os mesmos m etodos de <vector>, mas adiciona push_front() e pop_front() e suporta iteradores rand omicos. A Figura 32.4 mostra os m etodos disponibilizados para <deque>. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

572

32.3. A CLASSE CONTAINER <DEQUE>

Figura 32.4: M etodos disponibilizados para <deque>.


Incluso de Objetos:
0 1 2 3 ... n-2 n-1 n

push_front()

push_back()

Eliminao de Objetos:
0 1 2 3 i ...n-2 n-1

pop_front() erase(i)

pop_back()

Obteno de Objetos:
0 1 2 3 ... n-2 n-1

front()

back()

Dimenses e capacidades:
size() capacity() max_size() reserve()

32.3.1

Construtores e destrutor

deque(); Construtor default, cria container vazio. deque(size type n, const T& x = T()); Cria container com n elementos contendo n c opias de x. deque(const deque<T>& d); Construtor de c opia, cria uma c opia do deque d. deque(InputIterator rst, InputIterator last); Cria um deque do tamanho de last - rst, preenchido com os valores de [rst a last). deque(); Destrutor. Nota: os m etodos v alidos para <vector> s ao v alidos para <deque>. Veja se ca o 32.1.

32.3.2

Exemplo de <deque>

Veja na listagem 32.4 exemplo de uso de <deque>. A listagem inicia com a cria ca o de uma fun ca o global template que sobrecarrega o operador< <. A fun ca o e usada para enviar os elementos do <deque> para sa da. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

32.4. RESUMO DO CAP ITULO Listing 32.4: Usando <deque>.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 # include < iostream > # include < deque > # include < string > using namespace std ; // S o b r e c a r g a do o p e r a d o r << template < typename T > ostream & operator < <( ostream & os , deque < T > & cdeque ) { for ( int i = 0; i < cdeque . size () ; ++ i ) os << cdeque [ i ] << ; return os ; } int main () { // Cria c o n t a i n e r do tipo deque para string , com o nome cdeque deque < string > cdeque ; // A d i c i o n a n d o o b j e t o s ao deque cdeque . push_front ( " Cidade de sol " ) ; cdeque . push_front (" Floriano polis "); cdeque . push_back ( " e mar . " ) ;

573

// A d i c i o n a r no inicio // A d i c i o n a r no fim

cout << " Dimens~ a o do container deque = " << cdeque . size () << " \ nConte u do do container deque : \ n \ t " << cdeque << endl ; // S e t a n d o um e l e m e n t o do c o n t a i n e r d i r e t a m e n t e cdeque [2] = string ( " e mar com belezas sem par . " ) ; cout << " Conte u do do container deque ap o s atribui ca ~ o direta :\ n \ t " << cdeque << endl ; // R e t i r a n d o p r i m e i r o e l e m e n t o do deque cdeque . pop_front () ; cout << " Conte u do do container deque ap o s um pop_front () :\ n \ t " ; for ( int i = 0; i < cdeque . size () ; ++ i ) cout << cdeque [ i ] << ; cout << endl ; return 0; }

Dimens~ a o do container deque = 3 Conte u do do container deque : Floriano p o l i s Cidade de sol e mar . Conte u do do container deque ap o s atribui ca ~ o direta : Floriano p o l i s Cidade de sol e mar com belezas sem par . Conte u do do container deque ap o s um pop_front () : Cidade de sol e mar com belezas sem par .

32.4

Resumo do cap tulo

Neste cap tulo aprendemos a utilizar os containers seq uenciais <vector>, <list> e <deque>. O container <vector> foi apresentado em detalhes. Aprendemos a criar um <vector> utilizando o construtor default ou o construtor de c opia. Vimos que os iteradores mais utilizados s ao retornados pelos m etodos begin(); e end();. Com front(); obtemos uma refer encia ao primeiro elemento, e com at(n); obtemos uma refer encia ao objeto n;. N ao podemos nos esquecer que podemos acesssar um <vector> exaPrograma ca o Orientada a Objeto com C++ Andr e Duarte Bueno

574

32.5. EXERC ICIOS

tamente da mesma forma que um vetor em C, utilizando o operator[](); que retorna uma refer encia ao objeto armazenado na casa n. Apredemos ainda a utilizar os m etodos: size() que retorna o n umero de elementos utilizados pelo container, capacity() que retorna o tamanho alocado pelo container, e max_size() que retorna o tamanho do maior vetor poss vel (o que depende da quantidade de mem oria dispon vel em seu computador). Vimos que podemos utilizar reserve(); para denir a capacidade do container, ou resize(); para alterar o tamanho do container. Lembre-se ainda que empty() retorna true se o container estiver vazio. Note que temos diversas vers oes de insert(), as memas s ao utilizadas para inserir novos objetos no container. Um m etodo de inser ca o especial e fornecido por push_back();, o mesmo insere um objeto no nal do container. Tamb em podemos eliminar objetos do container utilizando erase(n); para eliminar o elemento n, ou pop_back(); para remover o u ltimo elemento do container. J a clear(); apaga todo container. O container <list> deve ser utilizado quando precisamos inserir novos elementos em qualquer posi ca o do container. Lembre-se <list> e lento para acesso rand omico, mas e otimizado para inser ca o e remo ca o de elementos em qualquer posi ca o. Um <list> fornece todos os m etodos de um <vector>, com exce ca o de at[], capacity() e reserve(), e acrescenta m etodos novos, como front(), push_front(), pop_front() e insert(pos,elem). Vimos que um container <deque> e uma la com duas extremidades, unindo vantagens de <list> e <vector>. Como exemplo a r apida inser ca o na frente e atr as do container. Um <deque> tem os mesmos m etodos de <vector>, mas adiciona push_front(), pop_front() e suporta iteradores rand omicos. Dica: como o conjunto de m etodos fornecidos por cada container e grande, n ao tente decorar nada, apenas preste aten ca o no conceito. Com o tempo voc e ir a aprender a utilizar as classes container com facilidade.

32.5

Exerc cios

1. Diga em poucas linhas, quais as principais diferen cas entre os containers <vector>, <list>, <deque>, <set>, <multiset>, <map>, <multimap>, <stack>, <queue>. 2. Explique o porque da senten ca Uma lista n ao aceita (iterator + n). Voc e precisa fazer iterator++ n vezes.? 3. Porque <list> n ao aceita subscript[]. 4. Comente cada linha da listagem 32.1. 5. Modique a listagem 32.1. Use streans_iterators para entrada dos dados. Transforme o operador < <, em um operador com template, isto e, com tipo a ser denido. Inclua localiza ca o do maior e menor elemento do container. 6. Modique a listagem 32.2. Mostre na tela o conte udo da lista antes e depois de unique(). Verique que os elementos repetidos n ao s ao eliminados, apenas movidos para o m do conteiner. Monte um algoritmo para realmente eliminar os elementos repetidos. 7. Modique a listagem 32.3. Substitua o uso de push_front() e push_back(), por m etodo que possibilite a entrada de dados pelo usu ario. Monte um menu em que o usu ario vai poder selecionar uma das seguintes op co es: Incluir novo elemento; Eliminar elemento; Mostrar elemento; Localizar elemento. Mostrar toda lista; Apagar toda lista. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

32.5. EXERC ICIOS

575

8. 2 Modique a listagem 32.4. Substitua o operador< < (que usa template) por um operador sem template, fazendo o inverso de um de nossos exerc cios anteriores. Possibilite ao usu ario a entrada de dados. Use fun co es rand omicas para embaralhar o texto, como exemplo as fun co es next_permutation.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

576

32.5. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 33

Os Containers Adaptativos <stack>, <queue> e <priority_queue>


Veremos neste cap tulo os containers adaptativos <stack> (se ca o 33.1), <queue> (se ca o 33.2) e <priority_queue> (se ca o 33.3). Nota: neste momento voc e pode reler a descri ca o dos containers adaptativos apresentada na se ca o 31.2.3.

33.1

A classe container <stack>

Um <stack> e um container adaptado que trabalha como uma pilha LIFO (last in, rst out ). O u ltimo elemento colocado na pilha e o primeiro a ser removido, da mesma forma que ocorre com a pilha de uma calculadora HP (veja Figura 33.1). A Figura 33.1 mostra os m etodos disponibilizados para <stack>. Figura 33.1: M etodos disponibilizados para <stack>.
push() top() pop()

size()

Um <stack> e um container adaptado porque e constru do sobre um container <vector>, <list> ou <deque>. Se n ao for fornecido um container, por default e utilizado um <deque>. A Figura 33.2 mostra que a realiza ca o da classe <stack> e feita por <deque>, <vector>, ou 577

578

33.1. A CLASSE CONTAINER <STACK>

<list>. Veja a direita outra forma de representar este relacionamemto usando UML, a classe <stack> aparece como uma interface de acesso a <deque>. Figura 33.2: A classe <stack> funciona como uma interface de acesso a <deque>, <list> ou <vector>.
<<interface>>

deque vector

deque

stack

stack

list

Para utilizar um container <stack>, inclua o arquivo de cabe calho: #include <stack>

33.1.1

M etodos de <stack>

Apresenta-se a seguir alguns m etodos de <stack>. void push(const value type& x); Coloca elemento x na pilha. void pop(); Remove elemento da pilha. value type& top(); Retorna o elemento no topo da pilha, sem remover. const value type& top() const; Retorna o elemento no topo da pilha, como valor constante. size type size() const; Retorna o n umero de elementos da pilha. bool empty() ; Retorna true se a pilha estiver vazia.

33.1.2

A listagem da classe <stack>

Como a classe <stack> e pequena e simples, a mesma e apresentada na ntegra. Observe na listagem 33.1 que se voc e n ao passar o tipo de container a ser utilizado, <stack> usa por padr ao o tipo <deque>. Listing 33.1: A classe container <stack>.
1 2 3 4 5 6 7 8 // A classe c o n t a i n e r stack template < typename T , typename Container = deque <T > > class stack { typedef Container :: value_type value_type ; typedef Container :: size_type size_type ; protected : Container c ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

33.1. A CLASSE CONTAINER <STACK>


9 10 11 12 13 14 15 16 public : void push ( const value_type & x ) ; void pop () ; value_type & top () ; const value_type & top () const ; size_type size () const ; bool empty () ; };

579

33.1.3

Exemplo de <stack>

Veja na listagem 33.2 um exemplo de utiliza ca o do container <stack>. Como novidades temos, o uso de push() para adicionar elementos e de top() para ver o elemento no topo da pilha. Finalmente, usamos pop() para retirar elementos da pilha. Observe na sa da que o primeiro a entrar eou ltimo a sair. Listing 33.2: Usando <stack>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # include < iostream > # include < stack > # include < vector > # include < list > # include < string > using namespace std ; int main () { // Cria uma pilha a partir de stack < string > stack < int , vector < int > > stack < float , list < float > >

um c o n t a i n e r deque , vector e list . politicos ; partidos ; notaDoPolitico;

// A d i c i o n a n d o e l e m e n t o s ao c o n t a i n e r char resp ; do { cout << " Entre com o nome do politico : " ; string n o m e _ p o l i t i c o ; getline ( cin , n o m e _ p o l i t i c o ) ; politicos . push ( n o m e _ p o l i t i c o ) ; cout << " Entre com o n u mero do partido : " ; int n u m e r o P a r t i d o ; cin >> n u m e r o P a r t i d o ; cin . get () ; partidos . push ( n u m e r o P a r t i d o ) ; cout << " Entre com a nota do politico : " ; int nota ; cin >> nota ; cin . get () ; n o t a D o P o l i t i c o . push ( nota ) ; cout << " Continuar ( c ) ou sair ( q ) : " ; cin >> resp ; cin . get () ; } while ( resp != q && resp != Q ) ; cout << " \ nRetirando elementos do container : " << endl ; while (! politicos . empty () ) { cout << politicos . top () << ; politicos . pop () ; cout << partidos . top () << ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

580
44 45 46 47 48 49 50

33.2. A CLASSE CONTAINER <QUEUE>


partidos . pop () ; cout << n o t a D o P o l i t i c o . top () << << endl ; n o t a D o P o l i t i c o . pop () ;

} cout << endl ; return 0; } [ b u e n o @ l d s c 0 5 Parte - III ] $ ./ List_30_1 Entre com o nome do politico : Joao da Silva Entre com o numero do partido :456 Entre com a nota do politico :5 Continuar ( c ) ou sair ( q ) : c Entre com o nome do politico : Claudio Siqueira Entre com o numero do partido :654 Entre com a nota do politico :7 Continuar ( c ) ou sair ( q ) : c Entre com o nome do politico : Jos e Candido Medeiros Entre com o numero do partido :648 Entre com a nota do politico :8 Continuar ( c ) ou sair ( q ) : q Retirando elementos do container : Jos e Candido Medeiros 648 8 Claudio Siqueira 654 7 Joao da Silva 456 5

33.2

A classe container <queue>

Um container <queue> e um container que trabalha como se fosse uma la do tipo FIFO (rst in, rst out ). O primeiro que entra e o primeiro que sai. Um <queue> n ao suporta iteradores. Veja Figura 33.3. Os tens s ao adicionados na parte de tr as (com push()) e removidos da parte da frente (com pop()). O tipo <queue> pode ser adaptado a partir de qualquer container que suporte as opera co es front(), back(), push_back() e pop_front(). Normalmente e utilizado com <list> e <deque> (default ), pois n ao suporta <vector>. Para usar <queue> inclua o header <queue>: #include <queue>

Figura 33.3: M etodos disponibilizados para <queue>.


pop() ... push()

front()

size()

back()

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

33.2. A CLASSE CONTAINER <QUEUE>

581

33.2.1

M etodos de <queue>

Apresenta-se a seguir alguns m etodos de <queue>. value type& back(); Retorna o objeto do m da lista (o u ltimo elemento colocado). bool empty() const; Retorna true se a la estiver vazia. value type& front(); Retorna o elemento da frente da la. Primeiro tem que foi colocado na la. void push(const value type& x); Coloca x na parte de tr as da la. O primeiro que entra e o primeiro a sair. void pop(); Remove o elemento da frente da la. size type size () const; Retorna o n umero de elementos da la. const value type& back() const; Retorna o objeto do m da lista (o u ltimo elemento colocado) como const. const value type& front() const; Retorna o elemento da frente da la como const.

33.2.2

A listagem da classe <queue>

Veja a seguir a classe container <queue>. Listing 33.3: A classe container <queue>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 template < class T , class Container = deque <T > > class queue { public : typedef typename Container :: value_type value_type ; typedef typename Container :: size_type size_type ; protected : Container c ; public : value_type & back () ; bool empty () const ; value_type & front () ; void push ( const value_type & x ) ; void pop () ; size_type size () const ; const value_type & back () const ; const value_type & front () const ; };

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

582

33.3. A CLASSE CONTAINER <PRIORITY_QUEUE>

33.2.3

Exemplo de <queue>

Veja na listagem 33.4 um exemplo de uso do container <queue>. Listing 33.4: Usando <queue>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # include < iostream > # include < queue > # include < vector > # include < list > # include < iomanip > using namespace std ; int main () { // Cria queue a partir de deque , e list std :: queue < int > c o n t a i n e r Q u e u e D e q u e ; std :: queue < int , std :: list < int > > c o n t a i n e r Q u e u e L i s t ; // A d i c i o n a n d o e l e m e n t o s ao c o n t a i n e r for ( int i = 0; i < 10; ++ i ) { c o n t a i n e r Q u e u e D e q u e . push ( i ) ; c o n t a i n e r Q u e u e L i s t . push ( i * i ) ; } cout << " \ nRetirand o elementos do c o n t a i n e r Q u e u e D e q u e : " ; while (! c o n t a i n e r Q u e u e D e q u e . empty () ) { cout << setw (5) << c o n t a i n e r Q u e u e D e q u e . front () << ; c o n t a i n e r Q u e u e D e q u e . pop () ; } cout << " \ nRetirand o elementos do c o n t a i n e r Q u e u e L i s t : " ; while (! c o n t a i n e r Q u e u e L i s t . empty () ) { cout << setw (5) << c o n t a i n e r Q u e u e L i s t . front () << ; c o n t a i n e r Q u e u e L i s t . pop () ; } cout << endl ; return 0; } [ a n d r e @ m e r c u r i o Cap4 - STL ]# ./ a . out Retirando elementos do c o n t a i n e r _ q u e u e _ d e q u e : 0 1 2 3 4 5 6 7 8 9 Retirando elementos do c o n t a i n e r _ q u e u e _ l i s t : 0 1 4 9 16 25 36 49 64 81

33.3

A classe container <priority_queue>

Este container funciona da mesma forma que um <queue>, a diferen ca e que na <priority_queue> a la est a sempre ordenada, ou seja, o elemento retirado com pop() e sempre o maior. Um <priority_queue> compara seus elementos utilizando operador <. Utilize pop() para retornar o maior valor. Para utilizar <priority_queue>, inclua o arquivo de cabe calho: #include <queue> Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

33.4. RESUMO DO CAP ITULO

583

33.4

Resumo do cap tulo

Neste cap tulo aprendemos a utilizar os containers adaptativos <stack>, <queue> e <priority_queue>, containers que s ao constru dos a partir da adapta ca o de um outro container. Lembre-se um <stack> e um container adaptado que trabalha como uma pilha LIFO (last in, rst out ). O u ltimo elemento colocado na pilha e o primeiro a ser removido, da mesma forma que ocorre com a pilha de uma calculadora HP. Vimos que push() coloca o tem x na pilha, que pop() remove um tem da pilha, que top() retorna o tem no topo da pilha, sem o remover. Vimos que um container <queue> e um container que trabalha como se fosse uma la do tipo FIFO (rst in, rst out ), o primeiro que entra e o primeiro que sai. Os tens s ao adicionados na parte de tr as com push() e removidos da parte da frente com pop(). O tipo <queue> e normalmente utilizado com <list> e <deque> (default ), pois n ao suporta <vector>. Entre os m etodos de <queue> temos: back() que retorna o objeto do m da lista, empty() que retorna true se a la estiver vazia. front() que retorna o tem da frente da la. push() que coloca x na parte de tr as da la. pop() que remove o tem da frente da la e size() que retorna o n umero de elementos da la. As classes <stack>, <queue> e <priority_queue> s ao exemplos de classe de interface.

33.5

Exerc cios

1. Explique o funcionamento da listagem 33.2. 2. Modique a listagem 33.2. 3. Modique a listagem 33.4. 4. Implementar um exemplo que utilize <priority_queue>.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

584

33.5. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 34

Os Containers Associativos <set>, <multiset>, <map> e <multimap>


Veremos neste cap tulo a classe <pair> (se ca o 34.1) e os containers associativos <set> (se ca o 34.2), <multiset> (se ca o 34.3), <map> (se ca o 34.3), e <multimap> (se ca o 34.5). Nota: os containers associativos foram brevemente descritos na se ca o 31.2.2.

34.1

A classe <pair>

Toda fun ca o ou m etodo retorna apenas um objeto. Em muitos casos, voc e pode querer que um m etodo retorne dois objetos. Nestes casos, podemos utilizar um objeto da classe <pair>. A classe <pair> e denida no arquivo de cabe calho <utility>. Um <pair> e um objeto composto de dois outros objetos. O mesmo e utilizado em alguns m etodos dos containers <set>, <map> e <multimap>. Veja a seguir o prot otipo para criar e utilizar um <pair>. Prot otipo: Para criar um <pair> pair <Tipo1, Tipo2> objPar (Tipo1 obj, Tipo2 obj); Para usar um <pair> cout < < Primeiro objeto = < < objPar->rst(); cout < < Segundo objeto = < < objPar->second(); Pode-se construir rapidamente um <pair> utilizando-se make_pair(). Veja o exemplo: Exemplo: pair<int,float> objPair = make_pair( 6 , 7.4 );

34.2

A classe container <set>

O container <set> e um container associativo utilizado para armazenar um conjunto de chaves. Veja a seguir algumas caracter sticas do contaier <set>. As chaves n ao podem ser repetidas. 585

586 Aceita acesso bidirecional, mas n ao rand omico. Dene value_type como sendo a chave.

34.2. A CLASSE CONTAINER <SET>

Inclui sobrecarga para os operadores ==, !=, <, >, <=, >= e swap. N ao tem o operador []. Os objetos armazenados em <set> est ao sempre ordenados. Para utilizar o container <set>, inclua o arquivo de cabe calho <set>: #include <set> como um <map>, mas n E ao armazena um valor, somente a chave. A Figura 34.1 mostra os m etodos disponibilizados para <set>. Observe o uso de insert() para incluir uma chave e de erase() para eliminar uma chave. O container <set> inclui os m etodos find() para pesquisa de uma determinada chave, count() para contagem de objetos, al em de lower_bound(), upper_bound() e equal_range(). Figura 34.1: M etodos disponibilizados para <set>.
c 0 c 1 c 2 c 3 ... c n-2 c n-1

erase(chave) insert(chave)

34.2.1

Contrutores e destrutor

set (); Constr oe um set vazio (construtor default ). set (InputIterator rst, InputIterator last); Constr oe um set usando o intervalo [rst,last).

34.2.2

Trocas

void swap(set<Key, Compare, Alloc>& s); Troca o conte udo do container s com o conte udo deste container (de this).

34.2.3

Inser c ao e dele c ao

pair<iterator,bool> insert(const value type& x) ; Insere a chave x no container e retorna um par onde o primeiro elemento e um iterador para posi ca o do objeto no container e o segundo elemento um bool que indica sucesso ou fracasso na inser ca o. iterator insert(iterator pos, const value type& x); Insere a chave x no container no local indicado pelo iterador pos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

34.2. A CLASSE CONTAINER <SET> void erase(iterator pos); Elimina o objeto na posi ca o pos. size type erase(const key type& x); Elimina o objeto indicado pela chave x. void erase(iterator rst, iterator last); Elimina os elementos do container que est ao no intervalo [rst, last). void clear(); Elimina todos os elementos do container.

587

34.2.4

Pesquisa e contagem

iterator nd(const key type& x); Procura pelo elemento associado a chave x. size type count(const key type& x); Conta o n umero de elementos associados a chave x. Complexidade log(n)+count. iterator lower bound(const key type& x); Retorna iterador para o primeiro elemento associado a chave x. Complexidade log(n). iterator upper bound(const key type& x); Retorna iterador para o objeto imediatamente ap os o u ltimo objeto associado a chave x. Complexidade log(n). pair<iterator,iterator> equal range(const key type& x); Retorna um par de iteradores onde rst e o valor retornado por lower_bound() e last o valor retornado por upper_bound(). Complexidade log(n).

34.2.5

Operadores

Os operadores de <set> s ao == e <.

34.2.6

Exemplo de <set>

Veja na listagem 34.1 um exemplo de utiliza ca o do container <set>. O programa cria um container <set>, para n umeros inteiros, com o nome cset. Note que passamos o operador a ser utilizado para ordena ca o do container, std::less<int>. A seguir acrescenta novas chaves no container. Finalmente, criamos um iterador para cout e usamos a fun ca o gen erica copy() para enviar os elementos do container para tela. Observe que na sa da os dados est ao ordenados, mesmo n ao tendo sido inclu dos de forma ordenada. Listing 34.1: Usando <set>.
1 2 3 4 5 6 7 8 9 10 # include < iostream > # include < set > # include < algorithm > # include < iterator > using namespace std ; int main () { // Cria um c o n t a i n e r set , para tipo int // usa o p e r a d o r de c o m p a r a c~ a o std :: less < int >

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

588
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 1 2 set < int , std :: less < int > > cset ;

34.3. A CLASSE CONTAINER <MULTISET>

// Insere o b j e t o s no c o n t a i n e r ( sem ordem ) cset . insert (10) ; cset . insert (1000) ; cset . insert (100) ; cset . insert (10000) ; // Cria i t e r a d o r para uma o s t r e a m std :: o s t r e a m _ i t e r a t o r < int > out ( cout , " \ t " ) ; // Copia o c o n t a i n e r para tela usanto o i t e r a d o r out copy ( cset . begin () , cset . end () , out ) ; cout << endl ; return 0; } [ a n d r e @ m e r c u r i o Parte - IV ] $ ./ a . out 10 100 1000 10000

Dica: a classe <set> da STL costuma ser implementada como uma arvore de pesquisa balanceada, em que cada elemento tem tr es ponteiros. Isto garante performance, mas implica em aumento do consumo de mem oria, [Meyers, 2005].

34.3

A classe container <multiset>

Um container <multiset> trabalha com um conjunto de chaves que podem ser repetidas. Veja a seguir as caracter sticas de <multiset> . O mesmo armazena e recupera o valor da chave rapidamente. O container <multiset> suporta iterador bidirecional. As chaves est ao sempre ordenadas, em ordem crescente. um container associativo. E Para utilizar <multiset>, inclua o arquivo de cabe calho: #include <set> A diferen ca para <set> e que insert() retorna um iterator e n ao um <pair>. A Figura 34.2 mostra alguns m etodos disponibilizados para <multiset>: Figura 34.2: M etodos disponibilizados para <multiset>.
c0 c1 c2 c4 c4
c[n-2] c[n-1]

insert(c3) repetidas

erase(ci)

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

34.4. A CLASSE CONTAINER <MAP>

589

34.3.1

Contrutores e destrutor

multiset (); Construtor default. multiset (InputIterator rst, InputIterator last); Cria um multiset utilizando os valores do intervalo [rst,last).

34.3.2

Operadores

operator= (const multiset<Key, Compare, Alloc>& x);

34.4

A classe container <map>

Nesta se ca o descreveremos o container associativo <map>. Um container <map> trabalha com um conjunto de chaves e de objetos associados a essas chaves, ou seja, trabalha com pares onde a ordena ca o e tomada de decis oes e baseada nas chaves. Veja a seguir as caracter sticas do container <map>. um container associativo. E Em um <map> as chaves n ao podem ser repetidas. Um <map> fornece iteradores bidirecionais. Em um <map>, os dados s ao armazenados de forma ordenada, pelo operador menor que (<). Num <map>, value_type e um pair. Para usar <map> inclua seu arquivo de cabe calho: #include <map> A Figura 34.3 mostra alguns m etodos disponibilizados para <map>. O container <map> e muito u til, como veremos na listagem 34.2. Figura 34.3: M etodos disponibilizados para <map>.
c0 v[0] c1 v[1] c2 v[2] v[j] cj ... ... v[i]
c[n-2] c[n-1]

chave valor

v v [n-2] [n-1]

insert( cj , vj)

erase( ci )

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

590

34.4. A CLASSE CONTAINER <MAP>

34.4.1

Construtores e destrutor

map (); Constr oe um map vazio (construtor default ). Exemplo: map< int, string > meuMap; map (InputIterator rst, InputIterator last); Constr oe um map usando o intervalo denido por [rst,last).

34.4.2

Operadores

Os operadores de <map> s ao == e <. map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x); Operador de atribui ca o.

34.4.3

Inser c ao e dele c ao

pair<iterator,bool> insert(const value type& x); Insere um pair no container (um par(chave,valor)). Exemplo: meuMap.insert(make_pair( 5 , "jo~ ao" ); iterator insert(iterator pos, const value type& x); Insere um pair no container na posi ca o indicada. void erase(iterator pos); Apaga elemento localizado na posi ca o pos. size type erase(const key type& x); Apaga os elementos com a chave x. void erase(iterator rst, iterator last); Apaga os elementos no intervalo [rst-last). void clear() ; Apaga todos os elementos do container.

34.4.4

Pesquisa e contagem

iterator nd(const key type& x) ; Localiza objeto com a chave x; se n ao achar, retorna end(). size type count(const key type& x) ; Conta o n umero de objetos com a chave x. iterator lower bound(const key type& x); Retorna um iterador para primeiro elemento igual a x. Se n ao encontrar x, retorna iterador para primeiro elemento maior que x (ou para end()). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

34.4. A CLASSE CONTAINER <MAP> iterator upper bound(const key type& x) ; Retorna um iterador para o primeiro elemento maior que x.

591

pair<iterator,iterator> equal range(const key type& x) ; Retorna um par onde o primeiro elemento (rst ) e o retorno de lower_bound() e o segundo elemento (second ), o retorno de upper_bound(). const iterator nd(const key type& x) ; Localiza objeto com a chave x; se n ao achar, retorna end(). Retorna iterador constante. const iterator lower bound(const key type& x) ; Retorna um iterador constante para primeiro elemento igual a x. Se n ao encontrar x, retorna iterador para primeiro elemento maior que x (ou para end()). const iterator upper bound(const key typ& x) ; Retorna um iterador constante para o primeiro elemento maior que x. pair<const iterator,const iterator> equal range(const key type& x) ; Retorna um par onde o primeiro elemento (rst ) e o retorno de lower_bound() e o segundo elemento (second ), o retorno de upper_bound(). Os iterador de pair s ao constantes.

34.4.5

Exemplo de <map>

Veja na listagem 34.2 um exemplo que inclui a utiliza ca o de <map>. O c odigo esta documentado. Observe na sa da que os objetos do container s ao listados em ordem alfab etica. Isto ocorre porque <map> e sempre ordenado; a ordena ca o e feita pela chave. Listing 34.2: Usando <map>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # include < iostream > # include < fstream > # include < iomanip > # include < string > # include < map > using namespace std ; class CTelefone // Tipo telefone , a r m a z e n a o p r e f i x o e o n u mero { private : int prefixo ; int numero ; public : // C o n s t r u t o r CTelefone () : prefixo (0) , numero (0) {}; // S o b r e c a r g a de friend istream & friend ostream & friend ofstream & }; istream & operator > >( istream & is , CTelefone & t ) { is >> t . prefixo ; is >> t . numero ; return is ; } s t r e a m s como fun c~ a o friend operator >> ( istream & is , CTelefone & t ) ; operator << ( ostream & os , const CTelefone & t ) ; operator << ( ofstream & os , const CTelefone & t ) ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

592
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

34.4. A CLASSE CONTAINER <MAP>

ostream & operator < <( ostream & os , const CTelefone & t ) { os . setf ( ios :: left ) ; os << " ( " << t . prefixo << " ) -" << t . numero << endl ; return os ; } ofstream & operator < <( ofstream & os , const CTelefone & t ) { os . setf ( ios :: left ) ; os << t . prefixo << << t . numero << endl ; return os ; } int main () { // Usa um typedef , um a p e l i d o para std :: map usando string e C T e l e f o n e // A string e a chave e o C T e l e f o n e o valor . typedef std :: map < string , CTelefone > c o n t a i n e r M a p ; // Cria c o n t a i n e r para a r m a z e n a r lista de t e l e f o n e s containerMap listatelefones; CTelefone telefone ; int resp = 0; string linha ( " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\ n " ) ; do { string nome ; cout << " Entre com o nome da pessoa / empresa : " << endl ; getline ( cin , nome ) ; cout << " Entre com o telefone ( prefixo n u mero ) " << " ( ctrl + d para encerrar entrada ) : " << endl ; cin >> telefone ; cin . get () ; // O b s e r v e a i n s e r c~ a o da chave ( o nome ) e do valor ( o t e l e f o n e ) . if ( cin . good () ) l i s t a t e l e f o n e s . insert ( c o n t a i n e r M a p :: value_type ( nome , telefone ) ) ; } while ( cin . good () ) ; cin . clear () ; cout << linha << " Conte u do do container :\ n " << linha << " \ nChave valor " << endl ; // Sa da para tela a l i n h a d a a e s q u e r d a cout . setf ( ios :: left ) ; // Cria i t e r a d o r c o n t a i n e r M a p :: c o n s t _ i t e r a t o r iter ; for ( iter = l i s t a t e l e f o n e s . begin () ; iter != l i s t a t e l e f o n e s . end () ; ++ iter ) { cout << setw (5) << iter - > first << << iter - > second ; } cout << endl ; // Sa da para disco ofstream fout ( " L i s t a _ t e l e f o n e s _ m a p . dat " ) ; if ( fout ) { for ( iter = l i s t a t e l e f o n e s . begin () ; iter != l i s t a t e l e f o n e s . end () ; ++ iter ) fout << iter - > first << << iter - > second ; fout . close () ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

34.4. A CLASSE CONTAINER <MAP>


93 94 95 96 } cout << endl ; return 0; } [ b u e n o @ l d s c 0 5 Parte - III ] $ ./ a . out Entre com o nome da pessoa / empresa : LENEP Entre com o telefone ( prefixo numero ) ( ctrl + d para encerrar entrada ) : 22 27969700 Entre com o nome da pessoa / empresa : LMPT Entre com o telefone ( prefixo numero ) ( ctrl + d para encerrar entrada ) : 48 33317709 Entre com o nome da pessoa / empresa : Entre com o telefone ( prefixo numero ) ( ctrl + d para encerrar entrada ) : ---------------------------------------------------Conte u do do container : ---------------------------------------------------Chave valor LENEP (22) -27969700 LMPT (48) -33317709

593

34.4.6

Senten cas para <map>

Utilize um <map> para implementar um dicion ario. O m etodo begin() aponta para primeira chave ordenada (de forma crescente) e end(), para u ltima chave +1. O m etodo erase() retorna o n umero de objetos deletados. Se a chave n ao for localizada, <map> insere a chave da pesquisa no <map>, associando o valor a um valor default (zerado). Se voc e quer achar um par (chave,valor), mas n ao tem certeza de que a chave est a no <map>, use o m etodo find(). Pois, como dito na senten ca anterior, se a chave n ao for localizada, ela ser a inserida. A pesquisa no <map> utilizando a chave tem um custo da ordem de log(tamanhoDoMap). Um construtor de <map> pode receber um m etodo de compara ca o, de forma que voc e pode construir dois mapas e usar o mesmo m etodo de compara ca o em ambos. Na seq u encia AAAB, a chamada a lower_bound(A) retorna um iterator para o primeiro A e upper_ bound(A), um iterator para o primeiro elemento depois do u ltimo A, ou seja, para B. Assim, lower_bound() aponta para primeiro elemento na sequ encia e upper_bound() para u ltimo elemento +1. Utilize it->first para acessar a chave e it->second para acessar o valor. Exemplo: map<CChave,CValor>::const_iterator it; for(it = obj.begin(); it != obj.end(); it++) cout < < "chave=" < < it->first < < " valor=" < < it>second < < endl; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

594

34.5. A CLASSE CONTAINER <MULTIMAP>

34.5

A classe container <multimap>

O container <multimap> trabalha com um conjunto de chaves e de objetos associados a essas chaves, ou seja, trabalha com pares. Veja a seguir caracter sticas do container <multimap> . A ordena ca o e a tomada de decis oes s ao baseadas nas chaves. Em um <multimap>, as chaves podem ser repetidas. O container <multimap> n ao tem operador de subscrito (operator[]). um container associativo. E No container <multimap>, o m etodo insert() retorna um iterator e n ao um <pair>. E o uso de insert() sempre ocorre com sucesso pois <multimap> aceita valores repetidos. Para acessar os valores que t em a mesma chave, utilizam-se equal_range(), lower_bound() e upper_bound(). Exemplo: // Primeiro valor igual a x. lower_bound(x); // Primeiro valor maior que x. upper_bound(x); // Retorna um par // first = lower_bound(), second = upper_bound(). equal_range(x); Para utilizar um <multimap>, inclua o arquivo de cabe calho <map>: Exemplo: #include <map>

34.6

Resumo do cap tulo

Neste cap tulo aprendemos a utilizar a classe <pair>, para armazenar pares de dados, e os containers associativos <set>, <multiset> , <map>, e <multimap>. Aprendemos a utilizar <set> para armazenar um conjunto de chaves sem repeti co es, e <map>, para armazenar conjuntos de dados com chaves e valores (sem repeti co es). Montamos um exemplo que implementa, mesmo que basicamente, uma agenda de telefones.

34.7

Exerc cios

1. Monte um exemplo que utilize make_pair(); 2. Modique a listagem 34.1, mudando a ordem de ordena ca o do container. Ou seja, substituir o operador de compara ca o por std::greater<int>. Ver o resultado. 3. Monte um exemplo que utilize <multiset>. 4. Modique a listagem 34.2, acrescente uma classe CEndereco (que deve incluir a cidade, cep, rua, telefone e e-mail). Desta forma o programa vai montar uma agenda com todos os dados de seus amigos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

34.7. EXERC ICIOS

595

5. No exemplo da listagem 34.2, substitua containerMap::value_type(nome, telefone) por make_pair(nome, telefone). 6. Modique o exemplo anterior, usando o endere co de e-mail como chave de acesso.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

596

34.7. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 35

Programa c ao Gen erica


Veremos neste cap tulo um conjunto de fun co es que s ao utilizadas na programa ca o gen erica e que s ao fornecidas com a STL. Iniciaremos vendo uma introdu ca o ` a programa ca o gen erica (se ca o 35.1). A seguir apresentaremos as diferentes formas de classica ca o das fun co es gen ericas (se ca o 35.2), quanto ` a modica ca o do container (se ca o 35.2.1), quanto ` a categoria dos iteradores (se ca o 35.2.2) e quanto ` as opera co es realizadas (se ca o 35.2.3). As fun co es gen ericas s ao ent ao apresentadas: Preenchimento (se ca o 35.3.1) Compara ca o (se ca o 35.3.2) Remo ca o (se ca o 35.3.3) Trocas (se ca o 35.3.4) Misturar/Mesclar/Inverter (se ca o 35.3.5) Pesquisa (se ca o 35.3.6) Ordena ca o (se ca o 35.3.7) Classica ca o (se ca o 35.3.8) Transforma ca o (se ca o 35.3.9) Matem aticos (se ca o 35.3.10) Opera co es com conjuntos (se ca o 35.3.11) Ordena cao de pilhas (heapsort - se ca o 35.3.12) nalizaremos o cap tulo vendo exemplos (se ca o 35.4) e senten cas para c odigo gen erico (se ca o 35.5). Nota: uma descri ca o detalhadas das fun co es gen ericas pode ser obtida em http://www.cplusplus. com/reference/algorithm/. 597

598

A ` PROGRAMAC GENERICA 35.1. INTRODUC AO AO

35.1

Introdu c ao ` a programa c ao gen erica

Embora o conceito de programa ca o gen erica seja antigo (cerca de 30 anos), seu uso se intensicou com a inclus ao na STL de um conjunto de fun co es gen ericas. Ou seja, a STL fornece, al em de uma biblioteca de classes containers, um vasto conjunto de fun co es para pesquisa, ordena ca o, mistura, troca e transforma co es em um container. Cada fun ca o pode ser aplicada a um conjunto espec co de containers. Algumas fun co es gen ericas exigem que a classe container j a tenha sido ordenada. De uma maneira geral, as fun co es gen ericas utilizam iteradores para acessar e manipular os containers. As fun co es gen ericas foram constru das de forma a necessitar de um n umero reduzido de servi cos dos iteradores. O uso de gabaritos (templates) e de fun co es gen ericas permite a implementa ca o de algoritmos independentes do tipo de dados a ser utilizado.

35.2

Classica c ao das fun c oes gen ericas

Veja a seguir uma classica ca o das fun co es gen ericas quanto ` a mudan ca do container, quanto ao iterador necess ario e quanto ao tipo das opera co es.

35.2.1

Classica c ao quanto ` a modica c ao do container

Fun co es que n ao mudam o container: accumulate, nd, max, adjacent nd, nd if, max element, binary search, min, count, nd rst of, for each, min element, count if, includes, mismatch, equal, lexicographical compare, nth element, equal range, lower bound, mismatch, search, search n, nd end, upper bound. Fun co es que mudam o container: copy, remove if, copy backward, replace, ll, replace copy, ll n, replace copy if, generate, replace if, generate n, reverse, inplace merge, reverse copy, iter swap, rotate swap, make heap, rotate copy, merge, set dierence, nth element, next permutation, set intersection, set symmetric dierence, partial sort, set union, partial sort copy, sort, partition, sort heap, prev permutation, stable partition, push heap, stable sort, pop heap, swap, random shue, swap ranges, remove, transform, unique, unique copy, remove copy, remove copy if.

35.2.2

Classica c ao quanto ` a categoria dos iteradores

Algoritmos que n ao usam iterador: max, min, swap. Requer somente InputIterator: accumulate, nd, mismatch, count, nd if, count if, includes, equal, inner product, for each, lexicographical compare. Requer somente OutputIterator: ll n, generate n. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

DAS FUNC 35.2. CLASSIFICAC AO OES GENERICAS

599

L e de um InputIterator e escreve para um OutputIterator: adjacent dierence, replace copy, transform, copy, replace copy if, unique copy, merge, set dierence, partial sum, set intersedtion, remove copy, set symmetric dierence, remove copy if, set union. Requer um ForwardIterator: adjacent nd, lower bound, rotate, binary search, max element, search, equal range, unique, min element, swap ranges, ll, remove, nd rst of, remove if, upper bound, generate, replace, iter swap, replace if. L e de um ForwardIterator e escreve para um OutputIterator: rotate copy. Requer um BidirectionalIterator: copy backward, partition, inplace merge, prev permutation, next permutation, reverse, stable permutation. L e de um BidirectionalIterator e escreve em um OutputIterator: reverse copy. Requer um iterator rand omico, RandomAccessIterator: make heap, pop heap, sort, nth element, push heap, sort heap, partial sort, random shue, stable sort. L e de um InputIterator e escreve para um RandomAccessIterator: partial sort copy.

35.2.3

Classica c ao quanto ` as opera c oes realizadas

Opera co es de preenchimento: ll, ll n, copy, copy backward Opera co es de compara c ao: equal, mismatch, lexicographical compare, includes Opera co es de remo c ao: remove, remove if, remove copy, remove copy if Opera co es de troca (swap): swap, swap ranges, iter swap, replace, replace copy, replace copy if, replace if Opera co es de mistura: inplace merge, merge, reverse, reverse copy, random shue, rotate, rotate copy Opera co es de pesquisa: nd, adjacent nd, nd if, nd rst of, count if, search, nd, binary search, search n, lower bound, equal range, upper bound Opera co es de ordena c ao: sort, partial sort, stable sort, partial sort copy, nth element Opera co es de classica c ao: unique copy, unique Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

600

35.3. FUNC OES GENERICAS

Opera co es de transforma c ao: generate n, generate, for each, transform, partition, stable partition Opera co es matem aticas: max, min, max element, min element, count, count if, accumulate Opera co es de set (conjuntos): set symmetric dierence, set dierence, set union, set intersection Opera co es de pilha: make heap, push heap, pop heap, sort heap, next permutation, prev permutation

35.3

Fun c oes gen ericas

Veremos a seguir uma breve descri ca o de cada fun ca o gen erica oferecida pela STL. Se o leitor n ao compreender determinada fun ca o, a dica e ver os exemplos apresentados no nal deste cap tulo. Observe que apresentamos a forma de uso e n ao o prot otipo; o prot otipo das fun co es gen ericas e encontrado no arquivo de cabe calho <algorithm> ou no site http: //www.sgi.com/tech/stl/.

35.3.1

Preenchimento

As fun co es fill() e copy() s ao utilizadas para preencher o container. ll (d.begin(), d.end(), valor); Utiliza ll para preencher o container de begin() a end() com o valor. Veja listagem 35.1. ll n (d.begin(), n, valor); A partir da posi ca o begin(), preencher n elementos do container com o valor. copy (orig.begin(), orig.end(), out); Copia de rst a last para out. Utilize copy() para gerar uma sa da do container ou para gerar um novo container. A fun ca o copy() e usada para copiar blocos de dados de um container para outro. Veja listagens 35.2 e 35.3. copy backward (orig.begin(), orig.end(), dest.end()); Copia os elementos de orig para dest; orig[0] e colocado no m de dest, e assim sucessivamente.

35.3.2

Compara c ao

Os algoritmos a seguir s ao utilizados para comparar containers ou elementos de containers. Para comparar elementos de containers do mesmo tipo use == ou <. equal (v1.begin(), v1.end(), v2.begin()); Compara a igualdade de cada elemento dos containers v1 e v2. Retorna true se for tudo igual. mismatch (v1.begin(), v1.end(), v2.begin()); Retorna um par de iteradores que apontam para objetos de v1 e v2 que s ao diferentes. Se v1 == v2, os iteradores apontam para end(). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

35.3. FUNC OES GENERICAS lexicographical compare (v1.begin(), v1.end(), v2.begin(), v2.end()); Retorna a posi ca o onde os containers v1 e v2 s ao diferentes.

601

includes (a, a+size, b, b+size); Compara os containers ordenados a e b; se qualquer elemento de b estiver presente em a, retorna true. Veja listagem 36.4.

35.3.3

Remo c ao

Os algoritmos a seguir s ao utilizados para remover elementos do container. Observe que os elementos n ao s ao de fato removidos, apenas movidos para o m do container (no intervalo de valores entre size() e capacity()). remove (v.begin(), v.end(), valor); Percorre todo o container (de begin() a end()) e remove os objetos que t em seu conte udo igual a valor. c aoPredicado); remove if (v.begin(), v.end(), Fun Remove de begin() a end() se a fun ca o predicado retornar true. remove copy (orig.begin(), orig.end(), d.begin(), valor); Remove de begin() a end() o valor e copia para d. Se o container d for pequeno, haver a estouro de pilha. remove copy if (o.begin(), o.end(), d.begin(), fpred); Remove de begin() a end() se a fun ca o predicado retornar true e copia para d.

35.3.4

Troca

Os algoritmos a seguir s ao utilizados para trocar elementos de containers. replace (v.begin(), v.end(), valor, novoValor); Troca de begin() a end() valor por novoValor. c aoPredicado, novoValor); replace if (v.begin(), v.end(), Fun Se a fun ca o predicado retornar true, troca pelo novoValor. replace copy (orig.begin(), orig.end(), d.begin(), valor, novoValor); Troca de begin() a end() valor por novoValor e copia para d. replace copy if (orig.begin(), orig.end(), d.begin(), Fun c aoPredicado, novoValor); Se a fun ca o predicado retornar true, troca por novoValor no destino d. swap (v[0], v[1]); Troca o conte udo de v[0] pelo conte udo de v[1]. iter swap (it1, it2); Troca os objetos apontados por it1 e it2. swap range (v, v+3, v+4); Troca os objetos no intervalo especicado. O primeiro intervalo vai de v a v+3 (excluindo v+3). O segundo intervalo inicia-se em v+4. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

602

35.3. FUNC OES GENERICAS

35.3.5

Misturar/Mesclar/Inverter

Os algoritmos a seguir s ao utilizados para misturar, mesclar ou inverter elementos de diferentes containers. merge (orig1.begin(), orig1.end(), orig2.begin(), orig2.end(), dest.begin()) Pega os containers orig1 e orig2, que devem estar ordenados, e cria um container v3 com todos os elementos de orig1 e orig2. A seguir, copia os elementos de v3 para dest. merge (orig1.begin(), orig1.end(), orig2.begin(), orig2.end(), back inserter(d)) Pega os containers orig1 e orig2, que devem estar ordenados, e cria um container v3 com todos os elementos de orig1 e orig2. Depois copia v3 para d usando push_back(). inplace merge (v.begin(), v.begin()+n, v.end()) Mistura dois conjuntos de dados do mesmo container. Ir a misturar os valores de begin() a begin()+n com os valores a partir de begin()+n (sem ultrapassar v.end()). reverse (v.begin(), v.end()); Muda a ordem; o primeiro passa a ser o u ltimo. Veja listagem 36.4. reverse copy (orig.begin(), orig.end(), back inserter(dest)); Inverte os elementos de orig e copia para dest. A fun ca o back_inserter() chama a fun ca o push_back() de dest para inserir os elementos em dest. rotate (v.begin(), v.end(), v.begin()); Rotaciona ciclicamente. Veja listagem 36.4. random shue (v.begin(), v.end()); Embaralha os elementos do container randomicamente.

35.3.6

Pesquisa

Os algoritmos a seguir s ao utilizados para pesquisar/localizar determinado valor ou condi ca o. Para fazer pesquisa de tr as para frente use um reverse_iterator. nd (v.begin(), v.end(), valor); O find() procura por valor no intervalo especicado. Veja listagens 35.1 e 35.4. nd if (v.begin(), v.end(), Fun c aoPredicado); O find_if() procura no intervalo [rst-last) o objeto que satisfa ca ` a fun ca o predicado. Veja listagem 35.1. nd rst of (v1.begin(), v1.end(), v2.begin(), v2.end()); Retorna iterador para elemento de v1 que existe em v2. nd end(v1.begin(), v1.end(), v2.begin(), v2.end()); Procura a u ltima ocorr encia de uma subsequ encia em um intervalo. Procura no intervalo [v1.begin(), v1.end()) por uma sub-sequ encia de valores iguais no intervalo [v2.begin(), v2.end()) e retorna um iterador para primeiro elemento na sub-sequ encia. adjacent nd (v.begin(), v.end()); Procura pelo primeiro par de valores iguais e adjacentes; retorna iterador para o primeiro elemento. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

35.3. FUNC OES GENERICAS

603

binary search (v.begin(), v.end(), valor); Retorna true se o valor estiver presente no container. O container deve estar ordenado. lower bound (v.begin(), v.end(), valor); Retorna um iterador para o primeiro elemento igual ao valor. Para manter o container ordenado, inserir valor utilizando o iterador retornado. No exemplo a seguir, se o vetor v tem os elementos 3,4,6,12,34,34,34,50 e valor=34, lower_bound() retorna iterador para o primeiro 34. Exemplo: vector<int>::iterator lower; lower = lower_bound(v.begin(),v.end(),valor); upper bound (v.begin(), v.end(), valor); Retorna um iterador para o primeiro elemento maior que valor. Se tiver 3,4,6,12,34,34,50 e valor=34, retorna iterador para 50. Exemplo : vector<int>::iterator uper = uper_bound(v.begin(),v.end(),valor); equal range (v.begin(), v.end(), valor); Retorna um pair para aplica ca o de first=lower_bound() e second=uper_bound(). Exemplo: pair<vector<int>::iterator, vector<int>::iterator> p; p = equal_range(v.begin(),v.end(),valor); search (v.1begin(), v1.end(), v2.begin(), v2.end()); Procura uma seq u encia de v1.begin() a v1.end() que exista em v2.begin() a v2.end(). Ou seja, a seq u encia do container v1 existe no container v2? Retorna iterador para primeiro objeto no container v1. search (v.begin(), v.end(), Fun c aoPredicado); Procura de v.begin() a v.end() os elementos do container que satisfa cam ` a fun ca o predicado. Retorna iterador para primeira ocorr encia. search n (v.begin(), v.end(), n, valor) Procura seq u encia com n combina co es de valor. Retorna iterador para primeiro elemento encontrado.

35.3.7

Ordena c ao

Os algoritmos a seguir s ao utilizados para ordenar um container. sort (v.begin(), v.end()); Ordena o container v, de v.begin(), at e v.end(). O m etodo sort() n ao e dispon vel para <list>; utilize o sort() do pr oprio container <list>. A fun ca o sort() usa um algoritmo do tipo quicksort e tem um custo computacional proporcional a O(N.log(N)). Veja listagens 35.1, 35.2, 35.3, 36.4. Exemplo: sort(v.begin(), v.end(), std::greater<int>); cio, meio, m); partial sort (in Ordena do in cio at e o meio. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

604

35.3. FUNC OES GENERICAS

35.3.8

Classica c ao

Os algoritmos a seguir s ao utilizados para classicar um container. unique copy (orig.begin(), orig.end(), back inserter(dest)); Obt em uma c opia de orig, sem elementos repetidos, e copia para dest. unique (v.begin(), v.end()); Elimina os elementos duplicados, movendo-os para o m do container. Observe que retorna iterador para u ltimo elemento n ao duplicado. Nota: antes de chamar unique(), chame sort(). Apresenta-se no exemplo a seguir uma fun ca o gen erica que realmente elimina os elementos duplicados. Exemplo: template<typename C> void unique2(C& c) { // Ordena o container sort(c.begin(),c.end()); // Move para tr as elementos duplicados typename C::iterator p = unique(c.begin(),c.end()); // Deleta elementos duplicados c.erase(p,c.end()); }

35.3.9

Transforma c ao

Os algoritmos a seguir s ao utilizados para aplicar transforma co es aos elementos de um container. Os elementos transformados podem ser enviados para o pr oprio container destino ou um iterador (como ostream_iterator). generate (v.begin(), v.end(), fun c ao); generate() e usada para gerar novos valores para o container. De v.begin() a v.end() executa a fun ca o que n ao recebe nenhum par ametro mas retorna um novo elemento para o container. Veja listagem 36.4. c ao); generate n (v.begin(), n, fun De begin() a n executa a fun ca o que n ao recebe nada mas retorna um novo elemento para o container. Ou seja, preenche o container de v.begin() at e v.begin()+n. Note que v.begin() e um iterador, logo, a fun ca o pode ser usada n vezes e a sa da enviada para o iterador. for each (v.begin(), v.end(), fun c ao); Para cada elemento do container executa a fun ca o. De v.begin() a v.end() executa a fun ca o, utilizada para aplicar uma dada fun ca o a cada um dos elementos do container. Observe que for_each() n ao modica os elementos do container. transform (orig.begin(), orig.end(), dest.begin(), fun c ao); De orig.begin() a orig.end() executa a fun ca o e armazena o resultado em dest. Observe que a fun ca o deve receber um objeto do container (como const) e deve retornar um objeto Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

35.3. FUNC OES GENERICAS

605

transformado. Por exemplo, para somar o n umero 75 a todos os elementos do container v. Veja outros exemplos nas listagens 36.3, 36.4. No exemplo a seguir o destino e o pr oprio vetor v. Exemplo: transform(v.begin(), v.end(), d.begin(), rand); transform(v.begin(), v.end(), v.begin(), bin2nd(plus<int>(),75); transform (orig1.begin(), orig1.end(), orig2.begin(), d.begin(), fun c ao); De orig1.begin() a orig1.end() executa a fun ca o, usando os dados de orig1 e orig2, e armazena o resultado em d. Observe que a fun ca o deve receber um objeto do container orig1 (como const) e um objeto do container orig2 (como const) e deve retornar um objeto transformado. partition (v.begin(), v.end(), Fun c aoPredicado); Uma parti ca o ordena o container de acordo com a fun ca o predicado. V ao para o in cio do container os objetos que satisfazem ao predicado (retornam true). Veja listagem 36.4. Exemplo: partition(in cio,fim,predicado); Dica: os algoritmos que mudam o container, como tranform(), retornam um iterador para destino.end().

35.3.10

Matem aticos

Os algoritmos a seguir s ao utilizados para realizar opera co es matem aticas, como exemplo obter o maior valor de um container. Veja o arquivo <numerics>. max (a, b); Retorna a, se a > b, ou b, se b > a. Retorna o maior valor. min (a, b); Retorna a, se a < b, ou b, se b < a. Retorna o menor valor. max element (v.begin(), v.end()); Retorna o maior elemento. min element (v.begin(), v.end()); Retorna o menor elemento. count (v.begin(), v.end(),valor); Determina o n umero de elementos igual a valor. Exemplo: int total = count(v.begin(),v.end(),0); c aoPredicado); count if (v.begin(), v.end(), Fun Determina o n umero de elementos que obedecem ` a fun ca o predicado. accumulate (v.begin(), v.end(), valorInicial); Retorna a soma de todos os elementos. Observe que podemos passar o valor inicial do somat orio. Veja listagem 36.4. Exemplo: int somat orio = accumulate(v.begin(),v.end(),0); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

606

35.3. FUNC OES GENERICAS

35.3.11

Opera c oes matem aticas com conjuntos

set dierence (a, a+size, b, b+size, diferen ca); Todos os valores do vetor a que n ao estiverem no vetor b ser ao copiados para o vetor diferen ca. Veja listagem 36.4. Exemplo: int diferenca[size]; set_difference ( a, a + size , b , b + size , diferenca ); c ao); set intersection (a, a+size, b, b+size, interse Todos os valores do vetor a que estiverem no vetor b ser ao copiados para o vetor interse ca o. Veja listagem 36.4. Exemplo: int intersecao[size]; set_intersection (a,a+size,b,b+size,intersecao); ao); set union (a, a+size, b, b+size, uni Todos os valores do vetor a e b ser ao copiados para o vetor uni ao. Veja listagem 36.4. Exemplo: int uniao[size]; set_union (a,a+size,b,b+size,uniao); set symmetric dierence (a, a+size, b, b+size, sym dif ); Determina o conjunto de valores de a que n ao est ao em b e os valores de b que n ao est ao em a, e copia para o vetor sym_dif(). Veja listagem 36.4. Exemplo: int sym_dif[size]; set_symmetric_difference(a, a+size, b,b+size, sym_dif);

35.3.12

Ordena c ao de pilhas - heapsort

Um heap armazena os elementos de uma maneira semi-ordenada, de forma que a procura pelo maior elemento tenha um custo constante. A remo ca o do maior elemento e adi ca o de novos elementos tem tempo de processamento logar tmico. make heap (v.begin(), v.end()); Marca a pilha. O primeiro elemento de v e o maior. sort heap (v.begin(), v.end()); Ordena toda a pilha. push heap (v.begin(), v.end()); Adiciona elemento no container. pop heap (v.begin(), v.end()); Retira elemento do topo da pilha (maior elemento). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

35.4. EXEMPLOS DE USO DAS FUNC OES GENERICAS

607

35.4

Exemplos de uso das fun c oes gen ericas

Veremos a seguir exemplos de uso das fun co es gen ericas. Na listagem 35.1 apresentamos o uso de fun co es gen ericas como sort(); Listing 35.1: Usando sort(), find(), find_if(), fill().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 # include < iostream > # include < fstream > # include < iomanip > # include < string > # include < vector > # include < algorithm > using namespace std ;

// Classe de vetores // Algoritmos gen e ricos // Define o uso do espa c o de nomes std

// Declara ca ~ o de sobrecarg a de << para ostream e vector ostream & operator << ( ostream & os , const vector < int >& v ) { for ( int i = 0; i < v . size () ; i ++) os << " v [" << setw (3) << i << "]=" << setw (5) << v [ i ] << ; return os ; } // Declara ca ~ o de sobrecarg a de << para ofstream e vector ofstream & operator < < ( ofstream & os , const vector < int >& v ) { for ( int i = 0; i < v . size () ; i ++) os << setw (10) << v [ i ] << endl ; return os ; } // Declara ca ~ o e defini ca ~ o de fun ca ~ o predicado // Recebe um objeto do tipo armazenado no container // retorna verdadeiro ou falso . bool maiorQue5 ( int valor ) { return valor > 5; } int main () { string linha =" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\ n "; vector < int > v ; int data ; do { cout << "\ nEntre com o dado (" << setw (3) << v . size () << ") :"; cin >> data ; cin . get () ; if ( cin . good () ) v . push_back ( data ) ; } while ( cin . good () ) ; cin . get () ; cin . clear () ; // Reseta objeto cin para estado ok { ofstream fout (" vector . dat ") ; if (! fout ) return 0; fout << v << endl ; fout . close () ; } cout << "\ n " << linha << v << endl ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

608
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

35.4. EXEMPLOS DE USO DAS FUNC OES GENERICAS

int numero ; cout << "\ nEntre com o n u mero a ser localizado :"; cin >> numero ; cin . get () ; // Ponteiro para a posi ca ~ o localizada vector < int >:: iterator it = find ( v . begin () , v . end () , numero ) ; cout << "\ nN u mero localizad o na posi ca ~ o :" << ( it - v . begin () ) << endl ; // Localiza primeiro elemento que satisfaz a condi ca ~o // dada pela fun ca ~ o maiorQue5 it = find_if ( v . begin () , v . end () , maiorQue5 ) ; cout << "\ nN u mero maior que 5 localizado na posi ca ~ o :" << ( it - v . begin () ) << endl ;; // Ordena o container sort ( v . begin () , v . end () ) ; cout << "\ nVetor ap o s ordena ca ~ o com sort ( v . begin () ,v . end () ) \ n " << linha << v << endl ; // Preenche com o valor 45 fill ( v . begin () , v . end () , 45) ; cout << "\ nVetor ap o s fill ( v . begin () , v . end () , 45) ;\ n " << linha << v << endl ; // Retorna dimens~ a o e capacidade cout << " v . size () =" << v . size () << "\ nv . capacity () =" << v . capacity () << endl ; // R e d i m e n s i o n a o container v . resize (10) ; cout << "\ nVetor ap o s resize (10) :\ n " << linha << v << "\ nv . size () =" << v . size () << "\ nv . capacity () =" << v . capacity () << "\ n " << linha << endl ; cin . get () ; return 0; } [ b u e n o @ l d s c 0 5 Parte - III ] $ ./ a . out Entre com o dado ( 0) :45 Entre com o dado ( 1) :15 Entre com o dado ( 2) :91 Entre com o dado ( 3) :13 Entre com o dado ( 4) :26 Entre com o dado ( 5) : --------------------------------------------------------------v [ 0]= 45 v [ 1]= 15 v [ 2]= 91 v [ 3]= 13 v [ 4]= 26 Entre com o n u mero a ser localizado :91 N u mero localizado na posi ca ~ o :2 N u mero maior que 5 localizado na posi ca ~ o :0 Vetor ap o s ordena ca ~ o com sort ( v . begin () , v . end () ) --------------------------------------------------------------v [ 0]= 13 v [ 1]= 15 v [ 2]= 26 v [ 3]= 45 v [ 4]= 91 Vetor ap o s fill ( v . begin () , v . end () , 45) ; --------------------------------------------------------------v [ 0]= 45 v [ 1]= 45 v [ 2]= 45 v [ 3]= 45 v [ 4]= 45 v . size () =5 v . capacity () =8

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

35.4. EXEMPLOS DE USO DAS FUNC OES GENERICAS


Vetor ap o s resize (10) : --------------------------------------------------------------v[ 0]= 45 v [ 1]= 45 v [ 2]= 45 v [ 3]= 45 v [ 4]= 45 v[ 5]= 0 v [ 6]= 0 v [ 7]= 0 v [ 8]= 0 v [ 9]= 0 v. size () =10 v. capacity () =10 ---------------------------------------------------------------

609

No exemplo da listagem 35.2 mostramos o uso de sort() e copy(). O programa ordena as linhas de texto digitadas pelo usu ario ou as linhas de um arquivo de disco usando a fun ca o global OrdenaLinhasArquivo(). Listing 35.2: Usando sort() e copy() para ordenar linhas de texto.
# include # include # include # include # include # include < fstream > < iostream > < string > < vector > < iterator > < algorithm >

void O r d e n a L i n h a s A r q u i v o ( std :: istream & in , std :: ostream & out ) { std :: string linha ; std :: vector < std :: string > v ; while ( std :: getline ( in , linha ) ) v . push_back ( linha ) ; std :: sort ( v . begin () ,v . end () ) ; std :: cout << std :: endl ; std :: copy ( v . begin () ,v . end () , std :: ostream_iter at or < std :: string >( out ,"\ n " ) ) ; in . clear () ; return ; } int main () { using namespace std ; // Ordena linhas digitadas cout << " Digite diversas linhas de texto , e depois pressione ctrl + d :\ n "; O r d e n a L i n h a s A r q u i v o ( cin , cout ) ; cout << "\ nEntre com o nome do arquivo a ser ordenado :" < < endl ; string nomeArqui vo ; getline ( cin , nomeArquiv o ) ; ifstream fin ( nomeArquiv o . c_str () ) ; ofstream fout ((" Ordenado " + nomeArqui vo ) . c_str () ) ; O r d e n a L i n h a s A r q u i v o ( fin , fout ) ; return 0; } [ b u e n o @ l d s c 0 5 Parte - III ] $ ./ a . out Digite diversas linhas de texto , e depois pressione ctrl + d : Testando a ordem em que o texto vai sair ser a que vai dar certo ? Testando a ordem certo ? em que o texto vai sair ser a que vai dar Entre com o nome do arquivo a ser ordenado :

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

610
Entrada . dat

35.4. EXEMPLOS DE USO DAS FUNC OES GENERICAS

No exemplo da listagem 35.3 usamos copy(), para copiar dados de um arquivo de disco para um vetor. A seguir ordenamos o vetor e o enviamos para tela. Listing 35.3: Usando copy() para copiar dados de um arquivo de disco para um <vector>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include # include # include # include # include < algorithm > < fstream > < iostream > < iterator > < vector >

int main () { using namespace std ; ifstream in (" dados . dat ") ; vector < int > v ; copy ( istream_itera to r < int >( in ) , istream_iter at or < int >() , b a c k _ i n s e r t e r ( v ) ) ; sort ( v . begin () ,v . end () ) ; copy ( v . begin () , v . end () , ostream_iter at or < int >( cout , "\ n ") ) ; return 0; } [ b u e n o @ l d s c 0 5 Parte - III ] $ ./ a . out 15 25 35 48 65 75 98

Na listagem 35.4 apresentamos o uso de fun co es gen ericas como nth_element() e find() para obter a mediana de um grupo de dados. A listagem e documentada. Note que estamos acostumados a usar container<tipo>::value_type para obter a informac a o do tipo de valor armazenado no container. Mas na fun ca o Mediana() n ao temos o container. Temos apenas os iteradores. Ou seja, precisamos obter o container a partir dos iteradores. Este e o motivo para criarmos o apelido typedef typename std::iterator_traits<iterador>::value_type value_type; Listing 35.4: Usando <vector> com algoritmos gen ericos: C alculo da mediana.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # include # include # include # include # include < iostream > < algorithm > < functional > < iterator > < vector >

template < typename iterador , typename operadorCo mp ar a ca o > iterador Mediana ( iterador first , iterador last , o p e r a d o r C o m p a r a c a o opComp ) { // Cria apelido typedef typename std :: iterator_trai ts < iterador >:: value_type value_type ; std :: vector < value_type > tmp ( first , last ) ; // Determina posi ca ~ o m e dia typename std :: vector < value_type >:: size_type posicao = tmp . size () / 2; // Localiza no container recebido o valor da mediana std :: nth_eleme nt ( tmp . begin () , tmp . begin () + posicao , tmp . end () , opComp ) ; return std :: find ( first , last , tmp [ posicao ]) ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

35.4. EXEMPLOS DE USO DAS FUNC OES GENERICAS


20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 } int main () { // Cria vetor e armazena dados std :: vector < int > v ; v . push_back (1243) ; v . push_back (2367) ; v . push_back (7383) ; v . push_back (3928) ; v . push_back (8734) ; v . push_back (7382) ;

611

v . push_back (7284) ; v . push_back (6032) ; v . push_back (9284) ;

// Determina a mediana e mostra na tela int mediana = * Mediana ( v . begin () , v . end () , std :: less < int >() ) ; std :: cout << mediana << std :: endl ; return 0; } [ b u e n o @ l d s c 0 5 Parte - III ] $ ./ a . out 7284

No exemplo da listagem 35.5 criamos uma classe TCSeries que recebe dois par ametros, o n umero de elementos a serem criados e o incremento. Note que o operador() e sobrecarregado, e retorna o pr oximo valor da s erie. Ou seja, o objeto TCSeries se comporta como uma fun ca o que e chamada n vezes. Um objeto do tipo TCSeries e criado na chamada ao m etodo generat_n(), passamos para o construtor o valorInicial e o incremento. O m etodo generat_n(), executa nRepeti co es (chamadas) ao operator() do objeto criado, e envia para tela os valores retornados. Listing 35.5: Usando generator_n() para gerar uma s erie de dados.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 # include < algorithm > # include < iostream > # include < iterator > template < typename T > class TCSeries { public : // Construtor TCSeries ( const T & n =0 , const T & i =1) : proximo (n - i ) , incremento ( i ) {} // Operador s o b r e c a r r e g a d o T operator () () { return proximo += incremento ; } private : T proximo ; T incremento ; }; int main () { int valorInicial , incremento , nRepeticoe s ; std :: cout << " Entre com o valor inicial :"; std :: cin >> v a l o r I n i c i a l ; std :: cin . get () ; std :: cout << " Entre com o valor do incremento :"; std :: cin >> increment o ; std :: cin . get () ; std :: cout << " Entre com o n u mero de elementos :"; std :: cin >> nRepeticoe s ; std :: cin . get () ; std :: generate_n ( std :: ostream_itera t or < int >( std :: cout ,"\ n ") , // Destino nRepeticoes , // N u mero repeti co ~ es TCSeries < int >( valorInicial , incremento ) // Objeto fun ca ~o ); }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

612
Entre com o valor inicial :123 Entre com o valor do increment o :3 Entre com o n u mero de elementos :6 123 126 129 132 135 138

35.5. SENTENCAS PARA CODIGO GENERICO

35.5

Senten cas para c odigo gen erico

D e uma olhada na Internet e procure por STL. Voc e encontrar a muitos sites com exemplos interessantes. next_permutation() e prev_permutation() permutam os elementos do container. Veja listagem 36.4. No exemplo abaixo, o vetor v1 e adicionado ao m de v2. A fun ca o back_inserter() chama v2.push_back() para cada elemento de v1. copy ( v1.begin(), v1.end(), back_inserter(v2) ); No exemplo abaixo, o deque d1 e adicionado no m de d2, front_insert() chama a fun ca o push_front() para cada elemento de d2. copy ( d1.begin(), d1.end(), front_inserter(d2) ); Se um algoritmo qualquer tem uma vers ao gen erica e uma c opia espec ca para um determinado container ( e um m etodo do container), ent ao a vers ao do container e mais r apida. A classe <string> pode ser usada como um vetor. Veja os exemplos. Exemplo: for(int i = 0; i < s.size(); i++) cout < < s[i] < < endl; for(string::const_iterator it = s.begin(); it != s.end(); it++) cout < < *it < < endl; Voc e encontra informa co es e outros exemplos de uso das fun co es da STL nas refer encias [Deitel and Deitel, 2002], e sobre programa ca o gen erica, em [Austern, 1998].

35.6

Resumo do cap tulo

Neste cap tulo aprendemos a utilizar um conjunto de fun co es que s ao utilizadas na programa ca o gen erica e que s ao fornecidas com a STL. Vimos uma introdu ca o ` a programa ca o gen erica, e a seguir apresentamos a classica ca o das fun co es gen ericas (se modica ou n ao o container, tipo de iterador utilizado, e tipos de opera co es suportadas). Vimos que as fun co es gen ericas s ao classicadas da seguinte forma: preenchimento, compara ca o, remo ca o, trocas, misturar/mesclar/inverter, pesquisa, ordena ca o, classica ca o, transforma ca o, matem aticos, opera co es com conjuntos, ordena cao de pilhas. No nal do cap tulo vimos diversos exemplos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

35.7. EXERC ICIOS Nota: no cap tulo Cap tulo 36 - Objetos Fun co es da STL, veremos outros exemplos.

613

35.7

Exerc cios

1. Quais as fun co es gen ericas que n ao mudam o container? 2. Modique a listagem 35.1. Acrescente o uso de: nd rst of(); adjacent nd(); binary search(); lower bound(); upper bound(); equal range(); search(); search n();. 3. Modique a listagem 35.2, de tal forma que o usu ario possa denir o nome do arquivo de disco e a ordem de ordena ca o (ascendente/descendente). 4. S o para sentir a diferen ca, implemente a listagem 35.3 sem usar a STL. 5. Modique a listagem 35.4. Adicione o c alculo da m edio e desvio padr ao. 6. Modique a listagem 35.5. Crie a possibilidade de se criar s eries logar tmicas. 7. Monte um exemplo que leia de um InputIterator e escreva para um OutputIterator. 8. Quais os algoritmos gen ericos utilizados para opera co es de transforma ca o? 9. Monte um exemplo que utilize as fun co es de preenchimento (se ca o 35.3.1) e de remo ca o (se ca o 35.3.3). 10. Monte um exemplo que utilize as fun co es de compara ca o (se ca o 35.3.2) e de trocas (se ca o 35.3.4). 11. Monte um exemplo que fa ca pesquisas em um vetor (se ca o 35.3.6) e localize n umeros primos. 12. Monte um exemplo que aplique algoritmos de transforma ca o em polin omios (se ca o 35.3.9). 13. Implemente e teste a fun ca o unique2() (veja se ca o 35.3.8). 14. Voc e deve comentar o c odigo abaixo, e a seguir dizer o que faz o m etodo M? Exemplo: #include <fstream> #include <iterator> void CNome::M(string arqA, string arqB) { std::ifstream fin ( arqA.c_str() ); std::ofstream fout( arqB.c_str() ); std::copy(std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(fout)); } 15. Procure na Internet informa co es sobre os algoritmos stable_partition e stable_sort. 16. Procure na Internet informa co es sobre os algoritmos next_permutation e prev_permutation.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

614

35.7. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Cap tulo 36

Objetos Fun c oes da STL


Veremos neste cap tulo os objetos fun co es da STL, objetos que se comportam como fun co es. Iniciamos com uma introdu ca o aos objetos fun co es da STL (se ca o 36.1). As fun co es un arias (se ca o 36.1.1) e bin arias (se ca o 36.1.2). Os objetos fun co es fornecidos pela STL (se ca o 36.2). As fun co es aritm eticas (se ca o 36.2.1), de compara c ao (se ca o 36.2.2), e l ogicas (se ca o 36.2.3). A se ca o dicas avan cadas de STL (se ca o 36.3), apresenta alguns adaptadores fornecidos pela STL como o adaptador para fun ca o objeto bin2nd() (se ca o 36.3.1), para fun ca o objeto negators() (se ca o 36.3.2) e para fun ca o membro (se ca o 36.3.3). Finalmente descreve-se como extender a STL apresentando um exemplo de especializa ca o para std::swap() (se ca o 36.3.4).

36.1

Introdu c ao aos objetos fun c oes da STL

Algumas classes podem ter o operator() sobrecarregado. Desta forma, pode-se fazer: Tipo NomeObjeto; TipoParametro parametro; int resultado = NomeObjeto(parametro); ou seja, o objeto se comporta como sendo uma fun ca o. Como esse procedimento e muito usado, a STL inclui classes para objetos fun co es. Uma classe para fun co es que recebem um par ametro (fun co es un arias, se ca o 36.1.1) e outra classe para fun co es que recebem dois par ametros (fun co es bin arias, se ca o 36.1.2). Essas fun co es s ao inclu das no arquivo de cabe calho <functional>.

36.1.1

Fun c oes un arias

Fun co es un arias recebem apenas um par ametro. Como seu uso e muito comum, a STL inclui a classe template unary_function<TipoPar^ ametro, TipoRetorno>. Assim, voc e pode criar suas pr oprias fun co es un arias fazendo uma heran ca de unary_function. Veja o exemplo: Exemplo: #include <cmath> class seno: public unary_function< double, double > { public: double y; 615

616

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL double operator() (double x) // Operador sobrecarregado { return y = std::sin(x); } };

36.1.2

Fun c oes bin arias

Fun co es bin arias recebem dois par ametros. Como seu uso tamb em e muito comum, a STL inclui a classe template binary_function<TipoPar^ ametro,TipoPar^ ametro, TipoRetorno>. Assim, voc e pode criar suas pr oprias fun co es bin arias fazendo uma heran ca de binary_function. Veja o exemplo: Exemplo: #include <cmath> class potencia : public binary_function< double, double, double > { public: double z; double operator() (double x,double y) { return z = std::pow(x,y); } };

36.2

Objetos fun c oes fornecidos pela STL

Al em das classes unary_function e binary_function, a STL fornece um conjunto de func o es objetos de uso comum. Essas fun co es s ao listadas a seguir.

36.2.1

Fun c oes aritm eticas

As fun co es atitm eticas podem ser utilizadas em algoritmos gen ericos. Por exemplo, a fun ca o bin aria plus<> realiza a soma de dois elementos do mesmo tipo. Observe que o operador+ precisa ter sido sobrecarregado para o tipo. plus<> Soma (x + y). minus<> Subtra ca o (x - y). times<> Multiplica ca o (x * y). multiplies<> Multiplica ca o (x * y). divides<> Divis ao (x / y). modulus<> M odulo (x % y). negate<> Nega ca o (- x). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL

617

No exemplo a seguir cria-se um objeto fun ca o div, que e usado para realizar a divis ao de 20.5 por 3. Listing 36.1: Usando divides<>.
1 2 3 4 5 6 7 8 9 10 11 # include < functional > # include < iostream > int main () { // Cria objeto fun c~ a o para r e a l i z a c~ a o de d i v i s ~ a o de n u m e r o s float std :: divides < float > div ; std :: cout << div ( 20.5 , 3 ) << std :: endl ; return 0; } 6.83333

No exemplo a seguir usamos a fun ca o gen erica accumulate() e o objeto fun ca o multiplies<>, para calcular a m edia geom etrica de um vetor. . Listing 36.2: Usando multiplies<>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # include < cmath > # include < vector > # include < numeric > # include < functional > # include < iostream > using namespace std ; double M e d i a G e o m e t r i c a ( const vector < int >& v ) { double temp = accumulate ( v . begin () , v . end () , 1 , multiplies < int >() ) ; return ( pow ( temp ,1.0/ v . size () ) ) ; } int main () { vector < int > v ; int valor ; cout << " Entre com valores inteiros : " << endl ; while ( cin >> valor ) { v . push_back ( valor ) ; } cout << " M e dia Geom e tric a = " << M e d i a G e o m e t r i c a ( v ) << endl ; return 0; } Entre com valores inteiros : 5 6 7 8 9 4 3 2 1 M e dia Geom e trica = 4.14717

36.2.2

Fun c oes de compara c ao

equal to<> Testa igualdade (x == y). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

618 not equal to<> Testa diferen ca (x != y). greater<> Maior que (x > y). less<> Menor que (x < y).

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL

greater equal<> Maior que ou igual a (x >= y). less equal<> Menor que ou igual a (x <= y). No exemplo a seguir criamos um objeto do tipo priority_queue que ir a armazenar n umeros do tipo float. O container a ser utilizado e um <vector>, e utilizamos greater<float> (maior que) para denir o operador de compara ca o a ser utilizado na ordena ca o. Exemplo: priority_queue< float, vector<float>, greater<float> > objQueue;

36.2.3

Fun c oes l ogicas

logical and<> E logico (x & & y). logical or<> Ou l ogico (x || y). logical not<> Negac ao l ogica (! x)

Veja na listagem 36.3 um exemplo de classe fun ca o. O exemplo inicia-se denindo uma classe fun ca o objeto CFatorial, herdeira de unary_function. Dentro de main(), cria um <deque> com 10 elementos e preenche-os com valores seq uenciais. A seguir, usa a fun ca o gen erica transform() para executar o objeto fun ca o CFatorial para cada elemento do deque d e armazenar o resultado no vetor v. Observe que a fun ca o gen erica transform() aplica uma transforma ca o a cada elemento do <deque> d. A seguir, armazena o resultado dessa transforma ca o em v. Listing 36.3: Criando e usando uma classe fun ca o.
1 2 3 4 5 6 7 8 9 10 11 12 13 # include < iostream > # include < functional > # include < deque > # include < vector > # include < algorithm > # include < iterator > # include < iomanip > using namespace std ; // Classe fun c~ a o , cria uma fun c~ a o objeto a partir de uma fun c~ a o un a ria template < typename Parametro , typename Retorno > class TCFatorial : public unary_function < Parametro , Retorno > {

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL


14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 public : Retorno operator () ( const Parametro & arg ) { Retorno r = 1; for ( Parametro i = 2; i <= arg ; i ++ ) r *= i ; return r ; } }; int main () { // Cria um deque deque < int > origem (10) ; // P r e e n c h e o deque for ( int i = 0; i < origem . size () ; i ++) origem [ i ] = i ; // Cria um vetor d e s t i n o para a r m a z e n a r os f a t o r i a i s vector < int > destino (10) ;

619

// D e t e r m i n a o f a t o r i a l dos n u m e r o s a r m a z e n a d o s em origem // e a r m a z e n a no vetor d e s t i n o transform ( origem . begin () , origem . end () , destino . begin () , TCFatorial < int , int >() ) ; cout << " N u meros : " ; copy ( origem . begin () , origem . end () , ostream_iter at or < int >( cout , " \ t " ) ) ; cout << " \ ne fatoriais : " ; copy ( destino . begin () , destino . end () , ostream_itera to r < int >( cout , " \ t " ) ) ; cout << endl << endl ; char resp ; TCFatorial < int , int > o b j e t o _ f u n c a o ; do { cout << " Entre com um n u mero ( int ) : " ; int numero ; cin >> numero ; cin . get () ; cout << " N u mero = " << setw (7) << numero << " fatorial = " << setw (7) << o b j e t o _ f u n c a o ( numero ) << " \ nContinua r ( s / n ) ? " ; cin . get ( resp ) ; cin . get () ; } while ( resp == s || resp == S ) ; return 0; }

N u meros 9

: 0 1

1 2

2 6

3 24

5 120

6 720

7 5040

8 40320

e fatoriais : 1 362880

Entre com um n u mero ( int ) :5 N u mero = 5 fatorial = Continuar ( s / n ) ? n

120

Veja na listagem 36.4 outro exemplo de uso de fun co es gen ericas. Neste exemplo criamos a classe CTesteFuncoesGenericas, com os m etodos EntradaUsuario(), InicializaVetor() e Run(). Os m etodos EntradaUsuario() e InicializaVetor(), s ao utilizados para deni ca o dos valores do vetor a ser usado nos algoritmos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

620

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL

Na primeira parte da fun ca o Run(), estamos enviando para tela a lista de fun co es dispon veis para teste. Observe que o nome das fun co es s ao armazenadas no vetor fun co es e que usamos setw() para mostrar de forma organizada a lista de fun co es. Na segunda parte de Run() diversas fun co es gen ericas s ao testadas. Note que o usu ario entra com o n umero da fun ca o a ser testada e a seguir a fun ca o e testada. O exemplo e extenso e mostra o uso de diversas fun co es gen ericas. Listing 36.4: Usando fun co es gen ericas e objetos da STL.
# include # include # include # include # include # include # include # include # include < iostream > < iomanip > < string > < vector > < algorithm > < memory > < cstdlib > < numeric > < functional > // // // // // // // // // E n t r a d a e sa da de dados Manipuladores S t r i n g s de C ++ Classe de v e t o r e s Classe para a l g o r i t m o s g e n ericos destroe e construct Fun c~ a o rand Fun c~ ao inner_product Fun c~ oes diversas

using namespace std ;

// Define o uso do espa c o de nomes std

/* * Classe para teste dos a l g o r i t m o s g e n e r i c o s */ class C T e s t e F u n c o e s G e n e r i c a s { public : vector < int > v , v2 , v3 ; // A t r i b u t o s string msg ; C T e s t e F u n c o e s G e n e r i c a s () // C o n s t r u t o r { InicializaVetor(v); // P r e e n c h e o vetor v com v a l o r e s v3 = v2 = v ; msg = " \n - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\ n " ; } // M etodos p ublicos void E n t r a d a U s u a r i o ( vector < int >& vetor ) ; void I n i c i a l i z a V e t o r ( vector < int >& vetor , int n = 5 ) ; bool Run () ; private : // M etodos privados void U s o _ d e _ f i l l _ n () ; // P r e e n c h i m e n t o void U s o _ d e _ e q u a l () ; // C o m p a r a c~ ao void U s o _ d e _ m i s m a t c h () ; void U s o _ d e _ i n c l u d e s () ; void U s o _ d e _ r e m o v e _ c o p y _ i f () ; // R e m o c~ ao void U s o _ d e _ r e p l a c e _ c o p y _ i f () ; // Trocas void U s o _ d e _ i n p l a c e _ m e r g e () ; // M i s t u r a r / m e s c l a r / i n v e r t e r void U s o _ d e _ r e v e r s e _ c o p y () ; void U s o _ d e _ r a n d o m _ s h u f f l e () ; void U s o _ d e _ f i n d _ i f _ o f f () ; // P e s q u i s a void U s o _ d e _ a d j a c e n t _ d i f f e r e n c e () ; void U s o _ d e _ s e a r c h _ n () ; void U s o _ d e _ b i n a r y _ s e a r c h () ; void U s o _ d e _ a d v a n c e () ; void U s o _ d e _ n e x t _ p e r m u t a t i o n () ; // O r d e n a c~ ao void U s o _ d e _ r e v e r s e () ; void U s o _ d e _ r o t a t e () ; void U s o _ d e _ g e n e r a t e () ; // T r a n s f o r m a c~ ao void U s o _ d e _ f o r _ e a c h () ; void U s o _ d e _ t r a n s f o r m () ; void U s o _ d e _ n t h _ e l e m e n t () ; // M a t e m aticos void U s o _ d e _ c o u n f _ i f () ; void U s o _ d e _ a c c u m u l a t e () ; void U s o _ d e _ i n n e r _ p r o d u c t () ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL


void U s o _ d e _ s e t _ u n i o n () ; void U s o _ d e _ s e t _ i n t e r s e c t i o n () ; void U s o _ d e _ s e t _ d i f f e r e n c e () ; void U s o _ d e _ s e t _ s y m m e t r i c _ d i f f e r e n c e () ; void U s o _ d e _ m a k e _ h e a p () ; // O r d e n a c~ a o por pilha void Uso_de_pl u s () ; // F u n c~ o e s objeto void U s o _ d e _ m i n u s () ; void U s o _ d e _ t i m e s () ; void U s o _ d e _ m u l t i p l i e s () ; void U s o _ d e _ d i v i d e s () ; void U s o _ d e _ m o d u l u s () ; void U s o _ d e _ n e g a t e () ; void U s o _ d e _ e q u a l _ t o () ; void U s o _ d e _ n o t _ e q u a l _ t o () ; void U s o _ d e _ g r e a t e r () ; void Uso_de_le s s () ; void U s o _ d e _ g r e a t e r _ e q u a l () ; void U s o _ d e _ l e s s _ e q u a l () ; void U s o _ d e _ l o g i c a l _ a n d () ; // F u n c~ oes l ogicas void U s o _ d e _ l o g i c a l _ o r () ; void U s o _ d e _ l o g i c a l _ n o t () ; void U s o _ d e _ b i n d 2 n d () ; // A d a p t a d o r e s ( not1 f i n d _ i f ) void U s o _ d e _ m e n _ f u n _ r e f ( const vector < string >& s ) ; }; // fim da classe // S o l i c i t a v a l o r e s do vetor void C T e s t e F u n c o e s G e n e r i c a s :: E n t r a d a U s u a r i o ( vector < int >& vetor ) { vetor . clear () ; // Zera o vetor int data ; do { cout << " Entre com o dado ( " << setw (3) << vetor . size () << " ) ( ctrl + d encerra entrada ) : " ; cin >> data ; cin . get () ; if ( cin . good () ) vetor . push_back ( data ) ; } while ( cin . good () ) ; cin . clear () ; // Reseta objeto cin para estado ok } // P r e e n c h e n d o o vetor com uma s e q u ^ e n c i a de v a l o r e s p a d r ~ oes void C T e s t e F u n c o e s G e n e r i c a s :: I n i c i a l i z a V e t o r ( vector <int >& vetor , int n ) { vetor . clear () ; for ( int i = 0; i < n ; i ++) vetor . push_back ( i ) ; } // D e c l a r a c~ ao e defini c~ a o da s o b r e c a r g a de << template < typename Tipo > ostream & operator < < ( ostream & os , const vector < Tipo >& v ) { for ( int i = 0; i < v . size () ; i ++) os << setw (5) << setfill ( ) << v [ i ] << \ t ; return os ; } // Fun c~ a o de s e l e c~ a o da fun c~ a o a ser t e s t a d a bool C T e s t e F u n c o e s G e n e r i c a s :: Run () {

621

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

622

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL

char * vs [] = { " fill_n " , " equal " , " mismatch " , " includes " , " r e m o v e _ c o p y _ i f " , " replace_copy_if", " inplace_merge", " reverse_copy", " random_shuffle", " find_if " , " find_if_of f " , " a d j a c e n t _ d i f f e r e n c e " , " search_n " , " b i n a r y _ s e a r c h " , " advance " , " n e x t _ p e r m u t a t i o n " , " reverse " , " rotate " , " generate " , " for_each " , " transform " , " nth_eleme n t " , " counf_if " , " accumulate " , " i n n e r _ p r o d u c t " , " set_union " , " s e t _ i n t e r s e c t i o n " , " s e t _ d i f f e r e n c e " , " s e t _ s y m m e t r i c _ d i f f e r e n c e " , " make_heap " , " plus " , " minus " , " times " , " multiplies " , " divides " , " modulus " , " negate " , " equal_to " , " n o t _ e q u a l _ t o " , " greater " , " less " , " g r e a t e r _ e q u a l " , " less_equal " , " logical_a nd " , " logical_or " , " logical_n o t " , " bind2nd " , " not1 " , " men_fun_r ef " , " Mostra vetor " , " Sair do Programa " }; vector < string > funcoes ; cout << " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \ n " << " = = = = = = = = = = = = = Qual fun ca ~ o deseja testar ??? = = = = = = = = = = = = = = = = \ n " << " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \ n " ; for ( int i = 0; i < 30 ; i ++ ) { funcoes . push_back ( vs [ i ]) ; if ( funcoes [ i ] != " " ) cout << " Uso de " << funcoes [ i ] << setw (50 - funcoes [ i ]. size () ) << setfill ( . ) << i << endl ; } int selecao ; cin >> selecao ; cin . get () ; if ( selecao >= funcoes . size () ) return 0; InicializaVetor(v); cout << setfill ( ) << " Vetor v = " << v << endl ; if ( funcoes [ selecao ]== " fill_n " ) U s o _ d e _ f i l l _ n () ; else if ( funcoes [ selecao ]== " equal " ) U s o _ d e _ e q u a l () ; else if ( funcoes [ selecao ]== " mismatch " ) U s o _ d e _ m i s m a t c h () ; else if ( funcoes [ selecao ]== " includes " ) U s o _ d e _ i n c l u d e s () ; else if ( funcoes [ selecao ]== " r e m o v e _ c o p y _ i f " ) U s o _ d e _ r e m o v e _ c o p y _ i f () ; else if ( funcoes [ selecao ]== " r e p l a c e _ c o p y _ i f " ) U s o _ d e _ r e p l a c e _ c o p y _ i f () ; else if ( funcoes [ selecao ]== " i n p l a c e _ m e r g e " ) U s o _ d e _ i n p l a c e _ m e r g e () ; else if ( funcoes [ selecao ]== " r e v e r s e _ c o p y " ) U s o _ d e _ r e v e r s e _ c o p y () ; else if ( funcoes [ selecao ]== " r a n d o m _ s h u f f l e " ) U s o _ d e _ r a n d o m _ s h u f f l e () ; else if ( funcoes [ selecao ]== " find_if " ) U s o _ d e _ b i n d 2 n d () ; // Uso de find_if else if ( funcoes [ selecao ]== " find_if_o ff " ) U s o _ d e _ f i n d _ i f _ o f f () ; else if ( funcoes [ selecao ]== " a d j a c e n t _ d i f f e r e n c e " ) U s o _ d e _ a d j a c e n t _ d i f f e r e n c e () ; else if ( funcoes [ selecao ]== " search_n " ) U s o _ d e _ s e a r c h _ n () ; else if ( funcoes [ selecao ]== " b i n a r y _ s e a r c h " ) U s o _ d e _ b i n a r y _ s e a r c h () ; else if ( funcoes [ selecao ]== " advance " ) U s o _ d e _ a d v a n c e () ; else if ( funcoes [ selecao ]== " n e x t _ p e r m u t a t i o n " ) U s o _ d e _ n e x t _ p e r m u t a t i o n () ; else if ( funcoes [ selecao ]== " reverse " ) U s o _ d e _ r e v e r s e () ; else if ( funcoes [ selecao ]== " rotate " ) U s o _ d e _ r o t a t e () ; else if ( funcoes [ selecao ]== " generate " ) U s o _ d e _ g e n e r a t e () ; else if ( funcoes [ selecao ]== " for_each " ) U s o _ d e _ f o r _ e a c h () ; else if ( funcoes [ selecao ]== " transform " ) U s o _ d e _ t r a n s f o r m () ; else if ( funcoes [ selecao ]== " nth_eleme nt " ) U s o _ d e _ n t h _ e l e m e n t () ; else if ( funcoes [ selecao ]== " counf_if " ) U s o _ d e _ c o u n f _ i f () ; else if ( funcoes [ selecao ]== " accumulate " ) U s o _ d e _ a c c u m u l a t e () ; else if ( funcoes [ selecao ]== " i n n e r _ p r o d u c t " ) U s o _ d e _ i n n e r _ p r o d u c t () ; else if ( funcoes [ selecao ]== " set_union " ) U s o _ d e _ s e t _ u n i o n () ; else if ( funcoes [ selecao ]== " s e t _ i n t e r s e c t i o n " ) U s o _ d e _ s e t _ i n t e r s e c t i o n () ; else if ( funcoes [ selecao ]== " s e t _ d i f f e r e n c e " ) U s o _ d e _ s e t _ d i f f e r e n c e () ; else if ( funcoes [ selecao ]== " s e t _ s y m m e t r i c _ d i f f e r e n c e " ) U s o _ d e _ s e t _ s y m m e t r i c _ d i f f e r e n c e () ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL


else else else else else else else else else else else else else else else else else else else if ( funcoes [ selecao ]== " make_heap " ) if ( funcoes [ selecao ]== " plus " ) if ( funcoes [ selecao ]== " minus " ) if ( funcoes [ selecao ]== " times " ) if ( funcoes [ selecao ]== " multiplies " ) if ( funcoes [ selecao ]== " divides " ) if ( funcoes [ selecao ]== " modulus " ) if ( funcoes [ selecao ]== " negate " ) if ( funcoes [ selecao ]== " equal_to " ) if ( funcoes [ selecao ]== " n o t _ e q u a l _ t o " ) if ( funcoes [ selecao ]== " greater " ) if ( funcoes [ selecao ]== " less " ) if ( funcoes [ selecao ]== " g r e a t e r _ e q u a l " ) if ( funcoes [ selecao ]== " less_equal " ) if ( funcoes [ selecao ]== " logical_a n d " ) if ( funcoes [ selecao ]== " logical_or " ) if ( funcoes [ selecao ]== " logical_n o t " ) if ( funcoes [ selecao ]== " bind2nd " ) if ( funcoes [ selecao ]== " not1 " ) not1 else if ( funcoes [ selecao ]== " men_fun_r e f " ) U s o _ d e _ m a k e _ h e a p () ; Uso_de_plu s () ; U s o _ d e _ m i n u s () ; U s o _ d e _ t i m e s () ; U s o _ d e _ m u l t i p l i e s () ; U s o _ d e _ d i v i d e s () ; U s o _ d e _ m o d u l u s () ; U s o _ d e _ n e g a t e () ; U s o _ d e _ e q u a l _ t o () ; U s o _ d e _ n o t _ e q u a l _ t o () ; U s o _ d e _ g r e a t e r () ; Uso_de_les s () ; U s o _ d e _ g r e a t e r _ e q u a l () ; U s o _ d e _ l e s s _ e q u a l () ; U s o _ d e _ l o g i c a l _ a n d () ; U s o _ d e _ l o g i c a l _ o r () ; U s o _ d e _ l o g i c a l _ n o t () ; U s o _ d e _ b i n d 2 n d () ; U s o _ d e _ b i n d 2 n d () ; // Uso de U s o _ d e _ m e n _ f u n _ r e f ( funcoes ) ;

623

// Mostra o vetor else if ( funcoes [ selecao ]== " Mostra vetor " ) cout << setfill ( ) << " Vetor v = " << v << endl ; // Sai do p r o g r a m a else if ( funcoes [ selecao ]== " SAIR DO PROGRAMA " ) return 0; cout << " \a - - > Pressione enter para continuar " ; cin . get () ; cin . clear () ; return 1; // Se n~ a o e s c o l h e u sair r e t o r n a v e r d a d e i r o } // P r e e n c h i m e n t o void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ f i l l _ n () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // C o m p a r a c~ ao void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ e q u a l () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ m i s m a t c h () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ i n c l u d e s void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ i n c l u d e s () { v3 = v2 = v ; v3 . push_back (123) ; v2 . push_back (333) ; cout << setw (30) << " Vetor v2 = " << v2 << endl ; cout << setw (30) << " Vetor v3 = " << v3 << endl ; // cout . imbue ( locale (" pt_BR ") ) ; // o p c i o n a l cout << setw (30) << " v inclui v2 -> " << boolalpha << includes ( v . begin () , v . end () , v2 . begin () , v2 . end () ) << endl ; cout << setw (30) << " v3 inclui v2 -> " << boolalpha << includes ( v3 . begin () , v3 . end () , v2 . begin () , v2 . end () ) << endl ; cout << setw (30) << " v inclui v3 -> " << boolalpha << includes ( v . begin () , v . end () , v3 . begin () , v3 . end () ) << endl ; cout << setw (30) << " v2 inclui v3 -> " << boolalpha << includes ( v2 . begin () , v2 . end () , v3 . begin () , v3 . end () ) << endl ; cout << setw (30) << " v2 inclui v -> " << boolalpha << includes ( v2 . begin () , v2 . end () , v . begin () , v . end () ) << endl ; cout << setw (30) << " v3 inclui v -> " << boolalpha <<

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

624

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL


includes ( v3 . begin () , v3 . end () , v . begin () , v . end () ) << endl ;

} // R e m o c~ ao void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ r e m o v e _ c o p y _ i f () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // Trocas void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ r e p l a c e _ c o p y _ i f () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // M i s t u r a r / m e s c l a r/ i n v e r t e r void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ i n p l a c e _ m e r g e () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ r e v e r s e _ c o p y () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // E m b a r a l h a os e l e m e n t o s do c o n t a i n e r void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ r a n d o m _ s h u f f l e () { r a n d o m _ s h u f f l e ( v . begin () ,v . end () ) ; cout << " Vetor v ap o s r a n d o m _ s h u f l e = " << v << endl ; sort ( v . begin () ,v . end () ) ; cout << " Vetor v ap o s sort = " << v << endl ; } // P e s q u i s a void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ f i n d _ i f _ o f f () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ a d j a c e n t _ d i f f e r e n c e void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ a d j a c e n t _ d i f f e r e n c e () { cout << " uso de a d j a c e n t _ d i f f e r e n c e : " ; a d j a c e n t _ d i f f e r e n c e ( v . begin () , v . end () , ostream_itera to r < int >( cout , " " ) ) ; cout << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ s e a r c h _ n () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ b i n a r y _ s e a r c h // R e t o r n a v e r d a d e i r o se o valor for e n c o n t r a d o void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ b i n a r y _ s e a r c h () { cout << " Valor " << 3 << ( b i n a r y _ s e a r c h ( v . begin () ,v . end () ,3) ? " encontrado " : " n~ a o encontrado " ) << endl ; cout << " Valor " << 22 << ( b i n a r y _ s e a r c h ( v . begin () ,v . end () ,22) ? " encontrado " : " n~ a o encontrado " ) << endl ; } // Avan ca o iterador void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ a d v a n c e () { cout << " A partir da posi ca ~ o 0 , devo avan c ar quantas casas ( maximo = " << v . size () << " ) : " ; int n ; cin >> n ; cin . get () ; vector < int >:: iterator it = v . begin () ; advance ( it , n ) ; cout << " O iterador aponta agora para o elemento na posi ca ~o "

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL


<< ( it -v . begin () ) << " com o valor " << * it << endl ; } // O r d e n a c~ ao // R e a l i z a p e r m u t a c~ a o dos e l e m e n t o s do c o n t a i n e r void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ n e x t _ p e r m u t a t i o n () { for ( int i = 0; i < v . size () * v . size () ; i ++) { n e x t _ p e r m u t a t i o n ( v . begin () ,v . end () ) ; cout << " Vetor v ap o s n e x t _ p e r m u t a t i o n = " << v << endl ; } } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ r e v e r s e () { reverse ( v . begin () , v . end () ) ; cout << " Vetor v ap o s reverse = " << v << endl ; } // C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ r o t a t e void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ r o t a t e () { rotate ( v . begin () ,v . begin () + v . size () /2 , v . end () ) ; cout << " Vetor v ap o s rotate ( v . begin () , v . begin () + v . size () /2 , " << " v . end () ) = " << v << endl ; }

625

// T r a n s f o r m a c~ ao // C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ g e n e r a t e : a fun c~ a o c h a m a d a por g e n e r a t e n~ ao // recebe p a r ^ a m e t r o e r e t o r n a um e l e m e n t o para o c o n t a i n e r no e x e m p l o a // seguir chama a fun c~ a o rand para p r e e n c h e r o c o n t a i n e r com n umeros aleat orios void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ g e n e r a t e () { generate ( v . begin () ,v . end () , rand ) ; cout << " Vetor de n u meros aleat o rios v = " << v << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ f o r _ e a c h () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ t r a n s f o r m () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // M a t e m aticos void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ n t h _ e l e m e n t () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ c o u n f _ i f () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // A c u m u l a v a l o r e s no i n t e r v a l o e s p e c i f i c a d o void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ a c c u m u l a t e () { for ( int i = 0; i < v . size () ; i ++ ) cout << " Valor acumulado at e " << i << " = " << accumulate ( v . begin () ,v . begin () ,0 ) << endl ; // + 1 } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ i n n e r _ p r o d u c t () { cout << " ENTRE COM OS DADOS DO VETOR v \ n " ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

626

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL

EntradaUsuario(v); // E n t r a d a dos dados do vetor v cout << " \ nENTRE COM OS DADOS DO VETOR v2 \ n " ; E n t r a d a U s u a r i o ( v2 ) ; // E n t r a d a dos dados do vetor v2 cout << " \ n " << " Vetor v = " << v << " \ nVetor v2 = " << v2 << " \ n P r o d u t o I n t e r n o v . v2 = " << i n n e r _ p r o d u c t ( v . begin () ,v . end () , v2 . begin () ,0) << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ s e t _ u n i o n () { v3 = v2 = v ; v3 . push_back (123) ; v2 . push_back (333) ; cout << " Vetor v2 = " << v2 << " \ nVetor v3 = " << v3 << " \ nUni~ a o de v2 e v3 = " ; set_union ( v3 . begin () , v3 . end () , v2 . begin () , v2 . end () , ostream_iter at or < int >( cout , " \ t " ) ) ; cout << endl ; } // C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ s e t _ i n t e r s e c t i o n void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ s e t _ i n t e r s e c t i o n () { cout << " Interse ca ~ o de v e v2 = " ; s e t _ i n t e r s e c t i o n ( v . begin () ,v . end () , v2 . begin () , v2 . end () , ostream_itera to r < int >( cout , " \ t " ) ) ; cout << endl ; } // C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ s e t _ d i f f e r e n c e void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ s e t _ d i f f e r e n c e () { cout << " diferen c a de v2 e v3 ( tem em v2 e n~ a o tem em v3 ) = " ; s e t _ d i f f e r e n c e ( v2 . begin () , v2 . end () , v3 . begin () , v3 . end () , ostream_itera to r < int >( cout , " \ t " ) ) ; cout << endl ; } // C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ s e t _ s y m m e t r i c _ d i f f e r e n c e void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ s e t _ s y m m e t r i c _ d i f f e r e n c e () { cout << " diferen c a sim e trica de v2 e v3 ( tem em v2 e n~ a o tem em v3 " ; cout << " ou tem em v3 e n~ a o tem em v2 ) = " ; s e t _ s y m m e t r i c _ d i f f e r e n c e ( v2 . begin () , v2 . end () , v3 . begin () , v3 . end () , ostream_iter at or < int >( cout , " \ t " ) ) ; cout << endl ; } // O r d e n a c~ a o por pilha void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ m a k e _ h e a p () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // F u n c~ o e s objeto // Uso da fun c~ ao bin a r i a plus e de t r a n s f o r m void C T e s t e F u n c o e s G e n e r i c a s :: Uso_de_pl us () { cout << " Vetor v = " << v << " \ nVetor v2 = " << v2 << endl ; transform ( v . begin () ,v . end () , v2 . begin () , v3 . begin () , plus < int >() ) ; cout << " Vetor v3 = v + v2 = " << v3 << endl ; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL


// C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ f u n c~ ao bin a r i a da stl // Uso da fun c~ ao bin a r i a minus e de t r a n s f o r m void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ m i n u s () { cout << " Vetor v2 = " << v2 << endl ; transform ( v . begin () ,v . end () , v2 . begin () , v3 . begin () , minus < int >() ) ; cout << " Vetor v3 = v - v2 = " << v3 << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ t i m e s () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // Uso da fun c~ ao bin a r i a m u l t i p l i e s e de t r a n s f o r m void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ m u l t i p l i e s () { cout << " Vetor v = " << v << " \ nVetor v2 = " << v2 << endl ; v . size () > v2 . size () ? v3 = v : v3 = v2 ; transform ( v . begin () ,v . end () , v2 . begin () , v3 . begin () , multiplies < int >() ) ; cout << " Vetor v3 [ i ] = v [ i ] * v2 [ i ] = " << v3 << endl ; } // Uso da fun c~ ao bin a r i a divides , t r a n s f o r m e b i n d 2 n d void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ d i v i d e s () { // Cada e l e m e n t o do vetor e d i v i d i d o pelo valor c o n s t a n t e const float valor = 2; vector < float > vd ( v . size () ) ; transform ( v . begin () , v . end () , vd . begin () , bind2nd ( divides < float >() , valor ) ) ; cout << " Vetor de n u meros float vd [ i ]= v [ i ]/2.0= " << vd << endl ; } // Cada e l e m e n t o do vetor e d i v i d i d o pelo valor constante , // r e t o r n a o m o dulo void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ m o d u l u s () { const float valor = 2; vector < float > vd ( v . size () ) ; transform ( v . begin () , v . end () , vd . begin () , bind2nd ( modulus < int >() , valor ) ) ; cout << " Vetor de n u meros vd = %( v / 2.0) = " << vd << endl ; } // Cada e l e m e n t o do vetor e negado void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ n e g a t e () { transform ( v . begin () , v . end () , v . begin () , negate < int >() ) ; cout << " Vetor v ap o s negate = " << v << endl ; } // Cada e l e m e n t o do vetor que for igual a 2 ir a para o in cio do vetor void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ e q u a l _ t o () { InicializaVetor(v); const float valor = 2; partition ( v . begin () , v . end () , bind2nd ( equal_to < int >() , valor ) ) ; cout << " Rearranja o vetor de forma que todos os elementos " << " \ niguais a 2 v~ a o para o in cio " << " \ nVetor v ap o s equal_to < int >(2) = " << v << endl ; } // Cada e l e m e n t o do vetor que for d i f e r e n t e de 2

627

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

628

36.2. OBJETOS FUNC OES FORNECIDOS PELA STL

// ir a para o in cio do vetor void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ n o t _ e q u a l _ t o () { InicializaVetor(v); const float valor = 2; partition ( v . begin () , v . end () , bind2nd ( not_equal_to < int >() , valor ) ) ; cout << " Rearranja o vetor de forma que todos os elementos " << " \ ndiferente s de 2 v~ a o para o in cio " << " \ nVetor v ap o s not_equal_to < int >(2) = " << v << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ g r e a t e r () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // Cada e l e m e n t o do vetor menor que 2 ir a para o in cio void C T e s t e F u n c o e s G e n e r i c a s :: Uso_de_le ss () { InicializaVetor(v); const float valor = 2; partition ( v . begin () , v . end () , bind2nd ( less < int >() , valor ) ) ; cout << " Rearranja o vetor de forma que todos os elementos " << " \ nmenores que 2 v~ a o para o in cio " << " \ nVetor v ap o s less < int >(2) = " << v << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ g r e a t e r _ e q u a l () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ l e s s _ e q u a l () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // F u n c~ oes l ogicas void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ l o g i c a l _ a n d () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ l o g i c a l _ o r () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ l o g i c a l _ n o t () { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } // A d a p t a d o r e s void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ b i n d 2 n d () { vector < int >:: iterator it = find_if ( v . begin () ,v . end () , not1 ( bind2nd ( greater_equal < int >() ,20) ) ) ; cout << " Valor maior que 20 localizado na posi ca ~ o " << ( it - v . begin () ) << " com o valor " << * it ; } void C T e s t e F u n c o e s G e n e r i c a s :: U s o _ d e _ m e n _ f u n _ r e f ( const vector < string >& s ) { { cout << msg << " Exerc cio : Montar este exemplo . " << msg << endl ; } /* vector < string >:: c o n s t _ i t e r a t o r it = f i n d _ i f( s . begin () ,s . end () , m e n _ f u n _ r e f (& string :: empty ) ) ; cout << " String vazia na p o s i c~ a o :" << it - s . begin () << endl ; */ } int main () { C T e s t e F u n c o e s G e n e r i c a s obj ; while ( obj . Run () ) ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

36.3. STL - USO AVANCADO


return 0; }

629

Nota: voc e encontra a sa da da listagem 36.4 no arquivo UsandoFuncoesGenericasEObjetosDaSTL.out.

36.3

STL - Uso Avan cado

Apresenta-se nesta se ca o algumas dicas de uso avan cado da STL.

36.3.1

O adaptador bin2nd()

Alguns objetos fun co es, como greater_equal() precisam receber dois par ametros. Exemplo: greater_equal(20,30); Se uma fun ca o gen erica varre o container e utiliza apenas um par ametro, ent ao o uso de fun co es como greater_equal() ca inviabilizado. Para resolver este problema a STL incluiu o m etodo bin2nd(). O mesmo recebe a fun ca o gen erica a ser executada e o segundo par ametro a ser utilizado. O primeiro par ametro e obtido do container. Veja exemplos de uso de bind2nd nos m etodos Uso_de_bind2nd(); e Uso_de_divides(); da listagem 36.4.

36.3.2

Os adaptadores not1(),not2()

A fun ca o gen erica not1() e usada para negar uma fun ca o un aria e not2() para negar uma fun ca o bin aria. Podemos usar not1() para negar o resultado de uma fun ca o predicado. Veja exemplo de uso de not1() no m etodo Uso_de_bind2nd() da listagem 36.4.

36.3.3

Os adaptadores - men_fun(), men_fun_ptr() e men_fun_ref()

O conjunto de fun co es men_fun s ao adaptadores da biblioteca padr ao, que possibilitam a aplica ca o de algoritmos da biblioteca padr ao aos m etodos de objetos denidos pelo usu ario. e um adaptador que possibilita a aplica ca o de algoritmos da bibliA fun ca o men_fun ref() oteca padr ao a m etodos de objetos denidos pelo usu ario. No exemplo a seguir, criamos um vetor de endere cos e a seguir executamos o m etodo Saida() de cada objeto do vetor usando o algoritmo for_each(): Exemplo: std vector< CEndereco > ve; ... std::for_each(ve.begin(), ve.end(), std::men_fun_ref(&CEndereco::Saida)); Note no exemplo acima que o vetor armazena objetos do tipo CEndereco e n ao ponteiros para CEndereco. A pergunta que ca e, e se tiv essemos um vetor de ponteiros, como executar amos for_each()? A solu ca o e usar o algoritmo men_fun(). Veja o exemplo: Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

630

36.4. RESUMO DO CAP ITULO Exemplo: std vector< CEndereco* > vpe; std::for_each(vpe.begin(), vpe.end(), std::men_fun(&CEndereco::Saida)).

J a a fun ca o men_fun_ptr() e utilizada para retornar um ponteiro para uma fun ca o membro (diferenciando um ponteiro de fun ca o de um objeto fun ca o). Na listagem 36.4, a fun ca o men_fun_ref() e usada para converter o ponteiro de m etodo string::empty, em uma referencia para fun ca o (veja o m etodo Uso_de_men_fun_ref()). Lembre-se, a maneira como devemos passar um ponteiro para um m etodo membro (se ca o F.7) e diferente da maneira como passamos um ponteiro de fun ca o (se ca o F.6). Nota: a biblioteca Boost, Cap tulo ?? - A Biblioteca Boost, inclui vers oes mais elaboradas dos adaptadores men_fun(). Consulte o manual da biblioteca.

36.3.4

Extendendo a STL - especializa c ao para std::swap

Podemos criar nossos pr oprios algor tmos gen ericos. O exemplo a seguir, adaptado de [Solter and Kleper, 2005] mostra uma fun ca o gen erica. A fun ca o padr ao std::swap(A,B); troca o conte udo de A por B usando um objeto tempor ario, o que pode ser lento, pois todos os atributos de A e B precisam ser copiados. Em alguns casos voc e quer trocar apenas parte do objeto. Isto pode ser resolvido usando-se uma especializa ca o de swap (o que e mais r apido). Veja no exemplo a seguir a especializa ca o de swap para uma classe Tipo que tem um atributo x, o atributo que queremos trocar: Exemplo: // Especializa c~ ao de swap template<> void swap<Tipo>( Tipo A, Tipo B ) { swap(A.x,B.x); // Troca o conte udo de A.x por B.x }

36.4

Resumo do cap tulo

Apresentamos neste cap tulo uma introdu ca o aos objetos fun co es da STL. A seguir vimos as fun co es un arias (recebem um par ametro) e bin arias (recebem dois par ametros). Aprendemos a utilizar os objetos fun co es fornecidos pela STL, as fun co es aritm eticas, de compara ca o, e l ogicas. Vimos ainda uma se ca o com dicas avan cadas de STL, onde apresentamos alguns adaptadores fornecidos pela STL como o adaptador para fun ca o objeto bin2nd(), os adaptadores not1(), not2(), e men_fun(). Finalmente aprendemos a extender a STL apresentando um exemplo de especializa ca o para std::swap(). Nota: como a STL e muito ampla n ao podemos esgotar todos os seus t opicos neste livro. A dica e: consulte o manual disponibilizado em http://www.sgi.com/tech/stl/, para ampliar seus conhecimento da STL. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

36.5. EXERC ICIOS

631

36.5

Exerc cios

1. Adicione novas fun co es gen ericas na listagem 36.4. 2. Transforma a classe CTesteFuncoesGenericas da listagem 36.4 em uma classe template. 3. Note que a listagem 36.4 apresenta diversos m etodos incompletos, sua tarefa e completar esta listagem.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

632

36.5. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Refer encias Bibliogr acas


[Amadeo., 2003] Amadeo., S. (2003). Software Livre e Inclus ao Digital. CONRAD, S ao Paulo. [Anais, 2000] Anais (2000). Anais do 1 F orum Internacional de Software Livre 2000. UNISINOS, Porto Alegre. [Aris, 1978] Aris, R. (1978). Mathematical Modelling Techniques. dover. [Austern, 1998] Austern, M. H. (1998). Generic Programming and the STL: Using and Extending the C++ Standart Template Library. Addison-Wesley. [Bender, 1978] Bender, E. A. (1978). An Introduction to Mathematical Modeling. dover. [Bjarne, 1999] Bjarne, S. (1999). C++ The Programming Language, volume 1. John Wiley Sons, 3 edition. [Blaha and Rumbaugh, 2006] Blaha, M. and Rumbaugh, J. (2006). Modelagem e Projetos Baseados em Objetos com UML 2. Campus, Rio de Janeiro. [Boente, 2006] Boente, A. (2006). Constru ca o de Algoritmos. Saraiva. [Booch, 1986] Booch, G., editor (1986). Object-oriented development, volume 12 of IEEE Transactions on Software Engineering. [Booch et al., 2000] Booch, G., Rumbaugh, J., and Jacobson, I. (2000). UML - Guia do Usu ario. Edit. Campus, Rio de Janeiro. [Coad and Yourdon, 1993] Coad, P. and Yourdon, E. (1993). An alise Orientada a Objeto. Campus, S ao Paulo. [Comunidade-GNU, 1996] Comunidade-GNU (1996). http://www.gnu.org/philosophy/free-sw.pt.html. O que e o software livre?

[Comunidade-Software-Livre, 1996] Comunidade-Software-Livre (1996). Declarac a o de barcelona - desaos para amplia ca o e consolidad ca o do software livre. http://www.softwarelivre.org/forum2004/news/2297. [Cormen et al., 2002] Cormen, T. H., Charles E, L., Rivest, R. L., and Stein, C. (2002). Algoritmos. Campus. [da Silva Neto and Neto, 2005] da Silva Neto, A. J. and Neto, F. D. M. (2005). Problemas Inversos - Conceitos Fundamentais e Aplica co es. Editora UERJ. [Deitel and Deitel, 2002] Deitel, H. and Deitel, P. (2002). C++ HOW TO PROGRAM. PRENTICE HALL, Porto Alegre, 4 edition. 633

634

REFERENCIAS BIBLIOGRAFICAS

[Emerson Rios, 2004] Emerson Rios, T. R. (2004). Projeto e Engenharia de Software - Teste de Software. Alta Books. [Fowler and Scott, 2000] Fowler, M. and Scott, K. (2000). UML Essencial. Bookman, S ao Paulo. [Guedes, 2004] Guedes, G. T. A. (2004). UML Uma Abordagem Pr atica. novatec, S ao Paulo. [GuiaLivre, 2004] GuiaLivre (2004). Guia livre - refer encia de migra ca o para software livre do governo federal. Technical report, Governo Federal. http://www.governoeletronico.gov.br. [Holloway, 2006] Holloway, J. P. (2006). Introdu ca o a ` Programa ca o para Engenharia. LTC. [http://www.fsl.org, 2004] http://www.fsl.org (2004). Filosoa de Software Livre. [Johnson and Foote, 1998] Johnson, R. E. and Foote, B. (1998). Designing reusable classes. JOOP - Journal of Object-Oriented Programming, pages 2235. [Kernighan and Ritchie, 1988] Kernighan, B. W. and Ritchie, D. M. (1988). The C Programming Language, Second Edition. Prentice Hall. [Korson and Macgregor, 92] Korson, T. and Macgregor, J. D. (92). Technical criteria for the specication and evaluation of object oriented libraries. Software Engineering journal, pages 8594. AO RUP - Rational Unied Process. [Kruchten, 2003] Kruchten, P. (2003). INTRODUC AO Ci encia Moderna, S ao Paulo. [Lischner, 2003] Lischner, R. (2003). C++ in a Nutshell - A Language & Library Reference. Oreilly. [Martin and McClure, 1993] Martin, J. and McClure, C. (1993). CASE. MacGraw-Hill, S ao Paulo. T ecnicas Estruturadas e

[Meyers, 2005] Meyers, S. (2005). Eective C++ : 55 Specic Ways to Improve Your Programs and Designs. Addison-Wesley. [Parga, 2006] Parga, D. F. (2006). Introdu ca o a java. Revista inform, pages 1019. [Pressman, 2002] Pressman, R. S. (2002). Engenharia de Software. MCGraw Hill, Rio de Janeiro, 5 edition. [Queiroz, 2002] Queiroz, R. (2002). Porque usar software livre. RDL. [Rezende, 2002] Rezende, D. A. (2002). Engenharia de Software e Sistemas de Informa ca o. Brasport, Rio de Janeiro. [Rumbaugh et al., 1994] Rumbaugh, J., Blaha, M., Premerlani, W., Eddy, F., and Lorensen, W. (1994). Modelagem e Projetos Baseados em Objetos. Edit. Campus, Rio de Janeiro. [Solter and Kleper, 2005] Solter, N. A. and Kleper, S. J. (2005). Professional C++. Wrox. [Sonerviile, 1993] Sonerviile (1993). Engenharia de Software. MacGraw-Hill, S ao Paulo. [Stroustrup, 2005] Stroustrup, B. (2005). The design of c++0x. C/C++ Users Journal. [Sutter, 2006] Sutter, H. (2006). Programa ca o Avan cada em C++. Pearson - Mahron Books. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

REFERENCIAS BIBLIOGRAFICAS [Teles, 2004] Teles, V. (2004). Extreme Programming. Novatec, S ao Paulo. [Teles, 2006] Teles, V. (2006). Extreme programming. Revista inform, pages 4249.

635

[Vandevoorde and Josuttis, 2002] Vandevoorde, D. and Josuttis, N. M. (2002). C++ Templates: The Complete Guide. Addison Wesley Professional. [Wikipedia, 2007] Wikipedia (2007). wikipedia - http://www.wikipedia.org/. In Wikipedia. http://www.wikipedia.org/. [Winblad et al., 1993] Winblad, A. L. et al. (1993). Software Orientado a Objeto, volume 1. Makron Books, S ao Paulo.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

636

REFERENCIAS BIBLIOGRAFICAS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Parte IV

Ap endices

637

Ap endice A

Diretrizes de Pr e-Processador
Neste ap endice veremos as diretrizes de pr e-processador. As diretrizes de pr e-processador s ao orienta co es, instru co es que fornecemos para a compilac a o do programa (veja se ca o A.1). Uma diretriz de pr e-processador inicia-se com o s mbolo # e e utilizada para inclus ao de arquivos (se ca o A.2), compila ca o condicional (se ca o A.3), uso de macros (se ca o A.4) e instru co es de guarda (se ca o A.5).

A.1

Fase de pr e-processamento

a primeira fase da compila E ca o, verica as instru co es de compila ca o passadas com o sinal # (reveja 7.7). Primeiro verica as instru co es de guarda (se ca o A.5), a seguir s ao inclu dos os arquivos externos (se ca o A.2), depois s ao processadas as macros (se ca o A.4). Na fase de pr e-processamento, cada letra do arquivo de disco e mapeada para o padr ao Unicode (ISO/IEC 10646) e posteriormente para o conjunto de caracteres de execu ca o. O resultado da fase de pr e-processamento e uma seq u encia de s mbolos que chamamos de unidade de tradu ca o. A unidade de tradu ca o e independente de outros arquivos (veja Figura 7.1). Note ainda que cada arquivo do programa e compilado separadamente. No exemplo a seguir a unidade de tradu ca o vai incluir o arquivo <iostream>. Exemplo: // Arquivo Prog.cpp #include <iostream> int main() { std::cout < < "Oi tudo bem!";

return 0; }

Para gerar o arquivo de pr e-processamento digite: g++ -E Prog.cpp > Prog.ii . Note que o arquivo gerado e muito grande.

A.2

Inclus ao de arquivos

Usamos a diretriz #include para incluir arquivos externos. Utilize #include <nome-do-arquivo> para incluir arquivos da biblioteca, e aspas duplas #include "nome-do-arquivo" para incluir arquivos do diret orio atual. A diferen ca entre ambas e que a segunda instru ca o procura os arquivos no diret orio do usu ario e depois nos diret orios identicados na vari avel de ambiente PATH e do compilador (/usr/include). 639

640

CONDICIONAL A.3. COMPILAC AO

Prot otipo: // Para realizar a inclus ao de arquivos. #include <nome-do-arquivo> #include nome-do-arquivo #include caminho/para/o/arquivo/nome-do-arquivo Observe que usando aspas "" podemos passar o caminho completo do arquivo. Mas este proce mais simples setar o caminho da biblioteca na vari dimento e inadequado. E avel de ambiente PATH utilizando export PATH=$PATH:caminho/para/biblioteca, veja prot otipo a seguir. A vari avel PATH tamb em pode ser setada no arquivo oculto .bash prole, que ca localizado no diret orio raiz do usu ario (cd && gedit bash prole ). Prot otipo: # bash export PATH=$PATH:caminho/para/biblioteca/:caminho/para/arquivos/inclus ao # csh setenv PATH=$PATH:caminho/para/biblioteca/:caminho/para/arquivos/inclus ao

A.3

Compila c ao condicional

A compila ca o condicional permite que sejam colocadas no c odigo do programa instru co es de compila ca o que restringem as areas do arquivo a serem compiladas. Por exemplo, alguns arquivos podem ter nomes diferentes no Windows, no GNU/Linux, Unix ou no MacOS X. Com a compila ca o condicional, voc e pode vericar qual o sistema operacional e especicar os arquivos corretos, assim, podemos incluir instru co es que diferenciam plataformas. Veja a seguir as instru co es que podem ser utilizadas para compila ca o condicional.

A.3.1

#define

A linguagem C permite a deni ca o de vari aveis que s ao passadas ao compilador para a realiza ca o do processo de compila ca o. A instru ca o #define, e utilizada para denir uma vari avel de compila ca o. Veja prot otipo a seguir. Prot otipo: // Dene uma vari avel #dene var

A.3.2

#ifdef

Depois de denir uma vari avel podemos utilizar a instru ca o #ifdef. Se a vari avel foi denida o bloco e compilado. Prot otipo: #ifdef var ..bloco de c odigo.. #endif // Finaliza o ..bloco de c odigo.. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

CONDICIONAL A.3. COMPILAC AO

641

A.3.3

#ifndef

Da mesma forma que #ifdef podemos usar #ifndef, ou seja, se a vari avel n ao foi denida compile o bloco. Isto e usado em sistemas multiplataforma, por exemplo, se n ao estamos no Windows fa ca isto. Prot otipo: // Apaga deni ca o da vari avel var #ifndef var ..bloco de c odigo.. #endif // Finaliza o ..bloco de c odigo.., o ifndef

A.3.4

#undef

A instru ca o #undef, e utilizada para apagar uma deni ca o. Veja prot otipo a seguir. Prot otipo: #undef var // Apaga deni ca o da vari avel var

As instru co es #define tamb em permitem a deni ca o de vari aveis que ser ao substitu das em tempo de compila ca o, funcionando de modo semelhante ao search(vari avel)/replace(valor) de seu editor de texto. Prot otipo: // Trocar a vari avel var pelo valor #dene vari avel valor No exemplo a seguir, denimos tr es vari aveis de ambiente. Na etapa de pr e-processamento toda vez que o compilador encontrar a palavra string1, ir a substitu -la por "mensagem_1". Da mesma forma, toda vez que o compilador encontrar a palavra CM_FileSave, ir a substitu -la por 2515. Exemplo: #define string1 "mensagem_1" #define CM_FileSave 2515 #define dimensao_x_matriz 10 Dica: o uso de #define para cria ca o de constantes, como em #define PI 3.1415 e obsoleto. Use const double pi = 3.1415;. Veja se ca o 12.4.

A.3.5

#if

Veja a seguir o prot otipo para compila ca o condicional com #if. Se a express ao for verdadeira, o compilador compila o c odigo dentro do bloco e, se for falsa, pula o bloco. O termo express ao constante indica que a express ao deve ser avaliada em tempo de compila ca o (durante a compila ca o). Prot otipo: #if express ao constante ..bloco de c odigo.. #endif Reveja agora o exemplo apresentado na listagem 8.3. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

642

CONDICIONAL A.3. COMPILAC AO

A.3.6

#ifdef...else

Se a express ao constante for verdadeira, o compilador compila o bloco 1, se for falsa, compila o bloco 2. Veja exemplo na listagem A.1. Prot otipo: #ifdef express ao constante .. bloco de c odigo1 .. #else .. bloco de c odigo2 .. #endif Listing A.1: Pr e-processamento: Usando #ifdef..else.
1 2 3 4 5 6 7 8 9 10 11 # include < iostream > int main () { # ifdef DEBUG std :: cout << " Vers~ a o com vari a vel debug ativada " << std :: endl ; # else std :: cout << " Vers~ a o com vari a vel debug N ~ A O ativada " << std :: endl ; # endif return 0; } [ b u e n o @ s u p o r t e 3 Parte - VI ] $ g ++ if - else . cpp [ b u e n o @ s u p o r t e 3 Parte - VI ] $ ./ a . out Vers~ a o com vari a vel debug N ~ A O ativada [ b u e n o @ s u p o r t e 3 Parte - VI ] $ g ++ - DDEBUG if - else . cpp [ b u e n o @ s u p o r t e 3 Parte - VI ] $ ./ a . out Vers~ a o com vari a vel debug ativada

A.3.7

#if...else

Se a express ao constante for verdadeira, o compilador compila o bloco 1, se for falsa, compila o bloco 2. Veja exemplo na listagem A.2. Prot otipo: #if express ao constante ..bloclo de c odigo1 .. #else ..bloclo de c odigo2 .. #endif Listing A.2: Pr e-processamento: Usando #if..else.
1 2 3 4 5 6 7 8 9 10 11 12 # include < iostream > using namespace std ; int main () { # ifdef __Linux__ cout < < " oi GNU / Linux \ n " ; # else cout << " oi \ n " ; return 0; } # endif

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

A.4. MACROS
oi GNU / Linux

643

A.3.8

#if...#elif...#elif...#endif

A diretriz de processamento #if...elif e usada para m ultiplas verica co es. Funciona da mesma forma que if..else (veja se ca o D.2.2): Prot otipo: #if express ao constante1 ..bloclo de c odigo1 .. #elif express ao constante2 ..bloclo de c odigo2 .. #elif express ao constante3 ..bloclo de c odigo3 .. #endif Dica: os arquivos da biblioteca padr ao costumam incluir exemplos de uso das diretrizes de pr e-processador, sendo uma boa refer encia para estudo.

A.4

Macros

Na linguagem C, voc e pode utilizar macros, que s ao fun co es de pr e-processamento. Uma macro e implementada com uma diretiva #define. Veja o exemplo. Exemplo: // Defini c~ ao da macro #define soma(x,y) (x+y) int a = 4; int b = 5; // Uso da macro, resultado int z = (a + b); int z = soma(a,b); Na linguagem C++, as macros foram substitu das pelas fun co es inline, que s ao mais seguras por fazerem verica ca o de tipo (veja se ca o 13.10).

A.4.1

Macros pr e-denidas

A linguagem C++ tem um conjunto de macros pr e-denidas, veja lista abaixo. A listagem A.3 mostra o uso das macros pr e-denidas. LINE FILE DATE TIME STDC N umero da linha compilada. Nome do arquivo que esta sendo compilado. Data de compila ca o. Hora minuto e segundo. Se e compilador padr ao.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

644

A.5. INSTRUC OES DE GUARDA Listing A.3: Pr e-processamento: Usando macros pr e-denidas.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

# include < iostream > using namespace std ; int main () { cout << " Arquivo : " << " \ nLinha : " << " \ nData : " << " \ nHora : " << " \ nCompilado r : "

<< << << << <<

__FILE__ __LINE__ __DATE__ __TIME__ __STDC__ << endl ;

# ifdef __GNUCC__ cout << " Compilado r da GNU : " << __GNUCC__ << endl ; # elif __MSC_VER_ _ cout << " Compilado r da Microsoft : " << __MSC_VER _ _ << endl ; # endif } Arquivo : List -A -4 - Macros . cpp Linha : 8 Data : Feb 13 2007 Hora : 11:47:58 Compilado r : 1

Veja a seguir uma macro, a mesma recebe dois par ametros, a e b e chama uma fun ca o f, passando o maior valor max(a,b). #define F(a,b) f( (a) > (b) ? (a) : (b))

Agora, veja o que acontece quando usamos a macro de forma inadvertida. F(++a,++b) O resultado gerado pela macro e dado por: f( (++a) > (++b) ? (++a) : (++b)) Ou seja, a e b s ao incrementados duas vezes, o que n ao desejamos. Este tipo de erro e comum quando se usa as obsoletas macros de C. A dica e simples, elimine o uso de macros, use fun co es inline de C++ (se ca o 13.10). Veja a seguir a fun ca o inline que substitue com vantagens as macros. Exemplo: // Defini c~ ao template <typename T> inline T F(const T&a, const T&b) { f( a > b ? a:b;); } // Uso F(a,b);

A.5

Instru c oes de guarda

As instru co es de guarda foram apresentadas na se ca o 11.4. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

A.6. SENTENCAS PARA DIRETRIZES DE PRE-PROCESSADOR

645

A.6

Senten cas para diretrizes de pr e-processador

Evite utilizar macros; as fun co es inline do C++ realizam a mesma tarefa de forma mais inteligente. Substitua o uso de #define por const e enumera co es. Voc e pode identicar qual processador esta utilizando (verique o manual de seu compilador). _ _CNUCC_ _ Compilador da gnu. _ _MSC_VER_ _ Compilador da Microsoft (Microsoft visual C++).

A.7

Resumo do cap tulo

Neste ap endice aprendemos a utilizar as diretrizes de pr e-processador de C++. Vimos que s ao instru co es que se iniciam com # e que fornecem instru co es para a compila ca o do programa. Aprendemos ainda a utilizar compila ca o condicional, e que n ao devemos usar as antigas macros de C. Entendemos o uso das instru co es de guarda.

A.8

Exerc cios

1. Diga com suas palavras como funciona a etapa de pr e-processamento. 2. Diga o que ocorre com a palavra dimensao x matriz na etapa de pr e-processamento do c odigo abaixo. #define dimensao_x_matriz 10 3. Nas listagens em que utilizamos arquivos .h separados dos arquivos .cpp, elimine do arquivo .h as instru co es de guarda e tente compilar novamente o programa. Descreva o que acontece. 4. Modique a listagem A.1 acrescentando novos blocos ifdef..else. 5. Modique a listagem A.2 acrescentando novos blocos if..else. 6. Rode o programa A.3 em sua m aquina, verique a sa da obtida. 7. Na se ca o A.4 falamos de exemplos de macros que podem apresentar problemas. Monte um programa com os exemplos apresentados na se ca o e veja a sa da obtida.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

646

A.8. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice B

Conceitos Uteis Para Programa c ao em C


Neste ap endice veremos alguns conceitos u teis para programa ca o em C. O uso dos especicadores de classes de armazenamento (se c ao B.1), do especicador de linkagem (se ca o B.2), o uso de extern (se ca o B.2.1), dos modicadores de acesso (se ca o B.3). O escopo das vari aveis (se ca o B.4). Senten cas para classes de armazenamento, escopo e modicadores de acesso (se ca o B.5).

B.1

Especicador de classe de armazenamento - tempo de vida

A classe de armazenamento refere-se ao tempo de vida do objeto. A deni ca o da classe de armazenamento e o primeiro item da declara ca o de uma vari avel e instrui o compilador sobre o modo como a vari avel ser a armazenada. Existem tr es palavras-chave para denir a classe de armazenamento. As palavras-chave auto e register s ao utilizadas para vari aveis que s ao constru das, utilizadas e destru das automaticamente pelo compilador; static e utilizado para vari aveis que s o s ao destru das quando o programa e encerrado. Note que static tamb em e constru do e destru do automaticamente pelo compilador. Objetos criados com new e destru dos com delete, tem seu tempo de vida denido pelo programador. auto: e o m etodo default para armazenamento de vari aveis. Quando for encerrada a fun ca o ou bloco onde a vari avel foi declarada, esta ser a eliminada, isto e, destru da automaticamente. Exemplo: { auto int a = 3; // A vari avel a e criada } // A vari avel a e destru da register: um processador como um Intel-Pentium ou um AMD-Opteron, tem um bloco onde est ao os registradores. Cada registrador e utilizado, temporariamente, para realiza ca o de algum processamento, como uma soma. Assim, quando fazemos c = a + b; , a vari avel a e 647

648

B.2. ESPECIFICADOR DE LINKAGEM copiada para o registrador 1, e a vari avel b para o registrador 2. O resultado da soma e armazenado no registrador 3 e depois copiado para c. Quando utilizamos a palavra-chave register, estamos pedindo para o compilador colocar a vari avel em um registro, que tem processamento mais r apido. Quando se encerrar a fun ca o ou bloco onde foi declarada, a vari avel vai ser eliminada. Os compiladores mais modernos colocam nos registradores as vari aveis mais utilizadas. O tempo de vida e o mesmo de uma vari avel auto.

static: quanto utilizamos static a vari avel passa a existir a partir de sua deni ca o e dura toda a execu ca o do programa. Se n ao for denido um valor, assume o valor 0 (zero). Em um programa, os objetos est aticos s ao os primeiros a serem constru dos e os u ltimos a serem destru dos (se ca o 16.6.3). Todas as vari aveis globais t em classe de armazenamento est atica, isto e, existem por toda a vida do programa. Se dentro de uma fun ca o houver uma vari avel static, est a ser a criada quando o programa passar pela fun ca o pela primeira vez; na segunda passagem, a vari avel n ao e novamente criada. Um objeto ou membro de um objeto pode ser est atico, se for declarado explicitamente com static. A palavra-chave static tamb em indica que a linkagem e interna (se ca o B.2). Exemplo: int fun c~ ao() { auto int x; // O mesmo que int x; register int y; // Colocar no registro static char Titulo[] = "SAILAnaliseImagens"; // Deixar na mem oria return 0; }

B.2

Especicador de linkagem

Todo nome declarado e usado dene a necessidade de uma linkagem, isto e, de uma liga ca o entre o nome do objeto e o espa co de mem oria ocupado pelo objeto. Por exemplo, se declaramos Exemplo: extern int x; mas nunca usamos x, ent ao n ao teremos problema de linkagem. Mas se x for usado, o mesmo precisa estar denido em algum arquivo externo. Em C++ uma linkagem pode ser: Interna: como exemplo podemos citar atributos e m etodos de uma classe, vari aveis declaradas como static ou const. Externa: usa a palavra-chave extern, veja exemplo na se ca o B.2.1. Sem linkagem: como exemplo podemos citar vari aveis denidas dentro de um bloco ou fun ca o. Tamb em podemos especicar que a linkagem deve ser feita utilizando-se padr oes de outras linguagens, como C e pascal. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

B.2. ESPECIFICADOR DE LINKAGEM C:

649

voc e pode linkar programas em C com programas em C++. No exemplo abaixo informa que a fun ca o e uma fun ca o de C. Exemplo: extern "C" void cfuncao(); Outra maneira de fazer isto e criar um bloco de fun co es em C, veja exemplo: Exemplo: extern "C" { void cfuncao1(); void cfuncao2(); .. } pascal: se a fun ca o a ser chamada foi desenvolvida utilizando a linguagem de programa ca o pascal, voc e deve incluir na declarara ca o da fun ca o a palavra-chave pascal. Exemplo: int pascal fun c~ ao(par^ ametros); // Declara .. int pascal fun c~ ao(par^ ametros) // Define { }

B.2.1

Uso de extern

A utiliza ca o da palavra-chave extern permite a compila ca o separada dos diversos arquivos que comp oem um programa. Ou seja, voc e deve utilizar extern na declara ca o de uma fun ca o ou vari avel que e denida em outros arquivos. O arquivo com a declara ca o extern aceita a exist encia da fun ca o de modo que voc e pode compilar as fun co es separadamente. Exemplo: // No arquivo A: cria a vari avel x (declara e define) int x; // No arquivo B: informa que x j a existe (s o declara) extern int x; Com a declara ca o extern, o arquivo B aceita a exist encia da vari avel int x;, mas n ao aloca espa co de armazenamento para esta. Deste modo, voc e pode compilar os arquivos A e B separadamente. Veja nas listagens B.2 e B.3 exemplos de uso de static, extern e compila ca o separada. O exemplo das listagens B.2 e B.3 deixa claro a ordem em que os objetos est aticos s ao criados e destru dos. A classe Teste e criada apenas para enviar mensagens para tela. Primeiro s ao criados os objetos globais (denidos ou n ao com static), a seguir os objetos s ao criados de forma autom atica, dentro de main() (Arquivo A: T1 main., Arquivo A: static T2 global.) e do for (Arquivo A: T1 for.,Arquivo A: static T2 for.). Observe que T1 for e criado-destru do, e a seguir criado-destru do novamente. Ou seja, quando chega o m do bloco em que foram Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

650

B.2. ESPECIFICADOR DE LINKAGEM

criados, os objetos autom aticos s ao destru dos. Com a chamada a funcao1, o objeto (Arquivo e criado, como e est atico o mesmo e criado apenas uma vez, na sua primeira B: static T3 for) execu ca o. A funcao1() e encerrada, e a seguir a fun ca o main(). O objeto autom atico (Arquivo e destru do, e a seguir todos os outros objetos est aticos. Observe ainda que T2 A: T1 main.) foi criado duas vezes, e tem escopo de arquivo, n ao podendo ser utilizado no outro arquivo. No arquivo B usamos extern T1, de forma que podemos usar T1 (sem o criar novamente). Da mesma forma, a declara ca o extern void funcao1(); colocada no arquivo A, garantiu a chamada a fun ca o funcao1() sem que a mesma tivesse sido denida. Listing B.1: Classe Autixliar Cteste.
1 2 3 4 5 6 7 8 9 10 11 12 13 # include < iostream > # include < string > class CTeste { std :: string msg ; public : CTeste ( std :: string s ) : msg ( s ) { std :: cout << " Criou objeto ~ CTeste () { std :: cout << };

: " << msg << std :: endl ; };

" Destruiu objeto : " << msg << std :: endl ; };

Listing B.2: Fun ca o e escopo A.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 // Define classe de CTeste , usada para enviar m e n s a g e n s para tela # include " CTeste . h " // D e c l a r a que existe uma funcao1 , que e d e f i n i d a em outro a r q u i v o extern void funcao1 () ; // Cria objeto global CTeste T1 ( " Arquivo A : T1_global . " ) ; // Cria objeto est a tico , v i s v e l s o m e n t e neste a r q u i v o static CTeste T2 ( " Arquivo A : static T2_global . " ) ; int main () { std :: cout << " Inicio da fun ca ~ o main () . " << std :: endl ; // Cria objeto v i s v e l dentro de main () CTeste T1 ( " Arquivo A : T1_main . " ) ; // Cria objeto est a tico , v i s v e l s o m e n t e em main () static CTeste T2 ( " Arquivo A : static T2_main . " ) ; // Cria um bloco for for ( int i = 0; i < 2; i ++) { // Cria objeto v i s v e l dentro do for CTeste T1 ( " Arquivo A : T1_for . " ) ; // Cria objeto est a tico , v i s v e l s o m e n t e no for static CTeste T2 ( " Arquivo A : static T2_for . " ) ; } // D e s t r o e T1_for // Chama funcao1 , d e f i n i d a em outro a r q u i v o funcao1 () ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

B.2. ESPECIFICADOR DE LINKAGEM


35 36 37 std :: cout << " Fim da fun ca ~ o main () . " << std :: endl ; return 0; }

651

Listing B.3: Fun ca o e escopo B.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # include " CTeste . h " // J a existe um objeto T1 extern CTeste T1 ; // Cria v a r i a v e l est a tica , v i s v e l s o m e n t e neste arquivo , static CTeste T2 ( " Arquivo B : static T2_global . " ) ; // D e f i n i c~ a o da fun c~ ao funcao1 void funcao1 () { std :: cout << " In cio da fun ca ~ o funcao1 . " << std :: endl ; // Se tentar usar a linha abaixo , causa erro de linkagem , // pois T2 foi d e f i n i d o como sendo est a tico , // s o p o d e n d o ser usado no a r q u i v o em que foi d e f i n i d o . // cout << T3 . msg << endl for ( int i = 0; i < 3; i ++) { // Cria T3 na p r i m e i r a p a s s a g e m. static CTeste T3 ( " Arquivo B : static T3_for " ) ; } std :: cout << " Fim da fun ca ~ o funcao1 . " << std :: endl ; } Criou objeto : Arquivo A : Criou objeto : Arquivo A : Criou objeto : Arquivo B : Inicio da fun ca ~ o main . Criou objeto : Arquivo A : Criou objeto : Arquivo A : Criou objeto : Arquivo A : Criou objeto : Arquivo A : Destruiu objeto : Arquivo A : Criou objeto : Arquivo A : Destruiu objeto : Arquivo A : In cio da fun ca ~ o funcao1 . Criou objeto : Arquivo B : Fim da fun ca ~ o funcao1 . Fim da fun ca ~ o main () . Destruiu objeto : Arquivo A : Destruiu objeto : Arquivo B : Destruiu objeto : Arquivo A : Destruiu objeto : Arquivo A : Destruiu objeto : Arquivo B : Destruiu objeto : Arquivo A : Destruiu objeto : Arquivo A : T1_global . static T2_global . static T2_global . T1_main . static T2_main . T1_for . static T2_for . T1_for . T1_for . T1_for . static T3_for

T1_main . static T3_for static T2_for . static T2_main . static T2_global . static T2_global . T1_global .

Para compilar este exemplo: g++ -c escopo-b.cpp g++ -c escopo-a.cpp Para compilar e linkar: g++ List-B-2-escopo-a.cpp List-B-3-escopo-b.cpp Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

652 Para rodar: ./a.out

B.3. MODIFICADORES DE ACESSO

B.3

Modicadores de acesso

Vimos na se ca o 8.4 que as palavras-chaves static, extern, const, volatile e mutable s ao qualicadores. Os mesmos podem ser divididos em modicadores de acesso (const, volatile e mutable) e especicador de linkagem (static, extern). Os modicadores de acesso s ao palavras-chave utilizadas para modicar o tipo de acesso a determinada vari avel. const: uma vari avel const e uma vari avel constante, que nunca muda. Portanto, seus valores s ao atribu dos uma u nica vez. Vari aveis const n ao podem aparecer ` a esquerda do sinal de igualdade. A palavra-chave const foi criada para substituir as instru co es #define. A vantagem e que com const existe verica ca o de tipo, o que n ao ocorre com #define. No exemplo da listagem B.4, criamos dois objetos const, um global const double PI = 3.14159265358979; e outro local, const float PI = static_cast < float >(::PI);. observe na sa da que PI local <float>, s o preserva os 7 primeiros d gitos, ou seja, 3.141592. Listing B.4: Usando modicadores de acesso.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # include < iostream > # include < iomanip > // C r i a c~ a o de objeto c o n s t a n t e ( n~ a o pode mudar ) , // global ( v i s v e l em todo p r o g r a m a) const double PI = 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 ; int main () { // C r i a c~ a o de objeto c o n s t a n t e ( n~ a o pode mudar ) , // local ( v i s v e l dentro de main ) const float PI = static_cas t < float >(:: PI ) ; std :: cout << std :: s e t p r e c i s i o n (15) << " Conte u do de PI local < float > = " << PI << " \ n " << std :: s e t p r e c i s i o n (15) << " Conte u do de PI global < double > = " << :: PI << " \ n " ; return 0; } Conte u do de PI local < float > = 3 . 1 4 1 5 9 2 7 4 1 0 1 2 5 7 3 2 Conte u do de PI global < double > = 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9

volatile: vari aveis que podem ter seu valor alterado de modo inesperado, n ao detectado pelo compilador (impede o compilador de utilizar otimiza co es agressivas com esta vari avel). T em utilidade em dispositivos mapeadores de mem oria, multitarefa e threads. Veja listagem ??. Exemplo: volatile int tempo; // Uso de volatile const volatile int alfa;// Uso de const volatile Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

B.4. ESCOPO DAS VARIAVEIS

653

mutable: quando voc e quer permitir que um atributo de uma classe/estrutura possa ser modicado, mesmo que o objeto seja declarado como const. Exemplo: struct Funcionario { char nome[30]; mutable int contador; } // Cria objeto do tipo Funcionario com nome func, constante const Funcionario func = {"Pedro",0}; // Abaixo tenta modificar o objeto func que e const strcpy(func.nome,"jo~ ao da silva"); // Erro // Abaixo o acesso e permitido gra cas ao especificador mutable func.contador = 1; const e volatile: no exemplo anterior, alfa e uma constante, e como tem o volatile, o compilador n ao faz qualquer suposi ca o sobre os valores de alfa. Um programa externo pode mudar o valor de alfa.

B.4

Escopo das vari aveis

J a discutimos preliminarmente o conceito de escopo nas se co es 8.12 e 10.3. Um programa e dividido em n veis/escopos, para melhorar sua organiza ca o. Desta forma, quando declaramos uma vari avel em determinado ponto do programa, estamos fazendo com que essa vari avel possa ser acessada no n vel em que foi declarada e nos n veis seguintes. Ou seja, o escopo de uma vari avel dene onde ela pode ser utilizada. Existem dois tipos de escopo, com nome e sem nome. Um namespace e uma classe s ao exemplos de escopo com nomes. Um bloco, o corpo de uma fun ca o, e um namespace sem nome s ao exemplos de escopo sem nome. Veja a seguir alguns exemplos de escopo. Escopo local (de bloco): quando uma vari avel e declarada dentro de um bloco, ela pode ser acessada dentro desse bloco, a partir de sua declara ca o, e nos n veis mais baixos. No exemplo abaixo x pode ser acessado a partir de sua deni ca o, o que inclui o bloco 2. Exemplo: { // int x = 3; { // int r = 4; } // } // In cio bloco 1 In cio bloco 2 Fim bloco 2 Fim bloco 1

Escopo de fun c ao/m etodo: quando uma vari avel e declarada dentro de uma fun ca o, ela pode ser acessada dentro da fun ca o. Se a vari avel for declarada como static, ser a criada uma u nica vez, mantendo-se Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

654

B.5. SENTENCAS viva mesmo depois do encerramento da fun ca o. Se a vari avel n ao for static, deixar a de existir quando a fun ca o terminar.

Escopo de classe (C++): quando um objeto e declarado dentro de uma classe, como um atributo da classe. Se a especica ca o de acesso for private, o objeto poder a ser acessado somente na classe em que foi declarado. Se a especica ca o de acesso for protected, o objeto ser a vis vel na classe em que foi declarado e nas classes derivadas. Se a especica ca o de acesso for public, o objeto poder a ser acessado em todo o programa. Escopo de namespace: vimos no Cap tulo 10 - Namespace, o uso de namespace para criar um espa co de nomes e o uso de using para mudar o escopo. Escopo global: quando declaramos uma vari avel fora de todos os blocos, fun co es e classes, ent ao ela e uma vari avel global. Uma vari avel global pode ser acessada por todos os arquivos que comp oem o programa a partir de sua declara ca o. Escopo de arquivo (static): uma vari avel ou fun ca o static global s o e vista no arquivo em que foi declarada (uso obsoleto de static, programas modernos utilizam namespaces. Veja Cap tulo 10 - Namespace). Exemplo de vari aveis que s o s ao vistas no arquivo em que foram declaradas: Uma fun ca o inline declarada explicitamente. Uma vari avel const. Uma vari avel global est atica. Exemplo: // Vari avel est atica expl cita define o seu valor static int valor1 = 16; // Vari avel est atica impl cita assume o valor 0 static int valor2; // Fun c~ ao est atica, vis vel somente neste arquivo static int soma(int x, int y) { return x + y; }

B.5

Senten cas

Um objeto criado dentro de uma fun ca o ou bloco e eliminado quando a fun ca o ou o bloco termina, com exce ca o dos objetos est aticos, que s o s ao destru dos quando o programa termina. A fun ca o abort() aborta o programa sem destruir os objetos est aticos. Em C++, todo objeto const deve ser inicializado na sua declara ca o. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

B.6. RESUMO DO CAP ITULO Evite utilizar #define; utilize const de C++.

655

Uma declara ca o friend n ao adiciona a fun ca o ao escopo da classe (Cap tulo 20 - Friend). Qualquer uso de um nome deve ser n ao amb guo em seu escopo. Depois de analisada a n ao-ambig uidade e que ser a considerada a acessibilidade da vari avel. Quando dizemos que uma vari avel n ao deve ser amb gua em seu escopo, queremos dizer que o compilador, ao passar por uma vari avel, deve ter certeza de qual vari avel voc e quer acessar, n ao podendo car em d uvida. A ordem em que os especicadores s ao colocados n ao e importante, mas o padr ao e: Especicador de linkagem (static, extern), especicador de classe de armazenamento (auto, register, static), modicadores de acesso (const, volatile, mutable). Vari aveis extern tem liga ca o externa. Quando for acessar fun co es de outras linguagens, utilize o exemplo a seguir. Exemplo: extern "C++" retorno nomefun c~ ao(par^ ametros); extern "C" retorno nomefun c~ ao(par^ ametros); extern "FORTRAN" ...; // e n~ ao Fortran extern "Ada"...............; // e n~ ao ADA Note que se uma fun ca o f() tem uma linkagem em "C", ent ao um ponteiro para f() tamb em deve ter linkagem de "C".

B.6

Resumo do cap tulo

Neste ap endice aprendemos o uso dos especicadores de classes de armazenamento (auto, register e static). Do especicador de linkagem, que pode ser interna, externa ou sem linkagem. Aprendemos a usar a palavra-chave extern. Vimos que os modicadores de acesso de C++ s ao const, volatile e mutable. Aprendemos que o escopo das vari aveis pode ser: local (de bloco), de fun ca o/m etodo, de classe (C++), de namespace, de arquivo (static) ou global.

B.7

Exerc cios

1. Monte um exemplo que use as palavras-chaves: auto, register, static. 2. Monte um exemplo que use as palavras-chaves: const, volatile e mutable. 3. Quais os problemas do programa abaixo? Exemplo: int main() { int x = 3; int r = x + y; { int y = 4; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

656 } cout < < r < < < < x < < < < y ; } 4. Monte um exemplo que use o conceito de extern. 5. Porque o uso de extern em C++ e obsoleto? 6. Modique a listagem B.4. 7. Modique as listagens B.2 e B.3.

B.7. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice C

Operadores
Neste cap tulo apresentaremos quais os operadores de C/C++ e sua ordem de preced encia. Os operadores est ao divididos em: operadores aritm eticos (se ca o C.1.1), de atribui ca o (se ca o C.1.2), compostos (se ca o C.1.3), relacionais (se ca o C.1.4), l ogicos (se ca o C.1.5), de bits (se ca o C.1.6), condicional (se ca o C.1.7), incremento e decremento (se ca o C.1.8), v rgula (se ca o C.1.9), operador m odulo % (se ca o C.1.10), new (se ca o C.1.11), delete (se ca o C.1.12), typedef (se ca o C.1.13), sizeof (se ca o C.1.14), size_t (se ca o C.1.15), resolu ca o de escopo (se ca o C.1.16). 657

658

AOS OPERADORES C.1. INTRODUC AO

C.1

Introdu c ao aos operadores

Os operadores denidos pela linguagem C++ podem ser utilizados para realizar determinada opera ca o entre objetos. Todo operador tem uma preced endia. Operadores de preced encia alta s ao executados antes dos operadores de preced encia baixa. Apresentamos na Tabela C.1 a preced encia dos operadores. O operador de mais alta prioridade e o de resolu ca o de escopo (::), a seguir os par enteses () e depois os colchetes []. O operador de mais baixa prioridade e o operador v rgula(,). Nota: normalmente alteramos a ordem de preced encia de determinada opera ca o matem atica utilizando parenteses extras.

1 :: () [] . -> i++ i- typeid

Tabela C.1: Preced encia dos 2 3 4 dynamic cast ! delete static cast delete[] reinterpret cast (tipo) .* const cast sizeof ->* ++i & * - -i * / + new % new[] +

operadores. 5 6 != < < & and >> or < | ou <= && e > || ou >= ?: == =

7 += -= *= /= %= &= = |=

8 < <= > >= ,

C.1.1

Operadores aritm eticos (+,-,*,/,%)

Os operadores aritm eticos como +,-,*,/ s ao usuais em diversas linguagens de programa ca o. C acrescentou o operador m odulo (%), o qual retorna o resto de uma divis ao. Prot otipo + * / % Soma. Subtra ca o. Multiplica ca o. Divis ao. Resto da divis ao.

Veja a seguir um exemplo: Exemplo: #include <iostream> using namespace std; int main() { int A = 1, B = 2, C A = B + C; // A = 18 - C; // B = 4 *( A / C); //

= A A B

3; = 5 = 15 = 20 Andr e Duarte Bueno

Programa ca o Orientada a Objeto com C++

AOS OPERADORES C.1. INTRODUC AO A = B % C; return 0; } // A = 5

659

Dica: a exponencia ca o xy pode ser realizada com a fun ca o pow(x,y) do arquivo de cabe calho <cmath>. O uso de x^y ou x**y n ao e v alido em C++.

C.1.2

Operadores de atribui c ao (=)

No exemplo a seguir, o operador de atribui ca o e utilizado para atribuir o conte udo de B a A. Exemplo: A = B; A = B = C = D = 0;

C.1.3

Operadores compostos (+=, -=, *=, /=)

Os operadores compostos aumentam a eci encia dos programas, pois s o acessam o objeto uma u nica vez. Exemplo: A += B; A -= B; A /= B; A *= B; // // // // O O O O mesmo mesmo mesmo mesmo que que que que A A A A = = = = A A A A + / * B; B; B; B;

C.1.4

Operadores relacionais (>, >=, <, <=, ==, !=)

Os operadores relacionais s ao utilizados para comparar objetos. Veja a seguir seu prot otipo: Prot otipo > >= < <= == != maior. maior ou igual. menor. menor ou igual. igual. diferente.

Um exemplo de uso dos operadores de compara ca o e apresentado na listagem C.1. Listing C.1: Usando os operadores de compara ca o, incremento, decremento, e os operadores compostos.
1 2 3 4 5 6 7 8 9 # include < iostream > void compara ( int a , int b ) ; // Fun c~ ao

int main () { int a , b ; std :: cout << " Entre com dois numeros inteiros ( a espa c o b enter ) : " ; // O b s e r v e abaixo a l e i t u r a de duas v a r i a v e i s em uma unica linha .

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

660
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 // Isto deve ser e v i t a d o. std :: cin >> a >> b ; std :: cin . get () ; compara (a , b ) ; a += 5; compara (a , b ) ; b - -; compara (a , b ) ; a *= ++ b ; compara (a , b ) ; return 0; }

AOS OPERADORES C.1. INTRODUC AO

// Pega o enter // O p e r a d o r c o m p o s t o . // O p e r a d o r de d e c r e m e n t o . // O p e r a d o r de i n c r e m e n t o e c o m p o s t o .

void compara ( int a , int b ) { if ( a == b ) // O p e r a d o r de c o m p a r a c~ ao std :: cout << a << " == " << b << " \ t " ; if ( a != b ) std :: cout << a << " != " << b << " \ t " ; if ( a < b ) std :: cout << a << " < " << b << " \ t " ; if ( a > b ) std :: cout << a << " > " << b << " \ t " ; if ( a <= b ) std :: cout << a << " <= " << b << " \ t " ; if ( a >= b ) std :: cout << a << " >= " << b << " \ t " ; } Entre com dois numeros inteiros ( a espa c o b enter ) : 3 4 3 != 4 3 < 4 3 <= 4 8 != 4 8 > 4 8 >= 4 8 != 3 8 > 3 8 >= 3 32 != 4 32 > 4 32 >= 4

C.1.5

Operadores l ogicos (&&, ||, !, ==, !=)

Os operadores l ogicos s ao utilizados para testar determinadas condi co es. Prot otipo && and || or ! not e. e. ou. ou. nega ca o, inverte o resultado. nega ca o, inverte o resultado.

Na listagem C.2, se x for maior que y ou x maior que z, faz x = y + z; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

AOS OPERADORES C.1. INTRODUC AO Listing C.2: Usando os operadores l ogicos.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 # include < iostream > int main () { int x = 5; int y = 3;

661

int z = 4;

if ( x > y || x > z ) x = y + z; std :: cout << " x = " << x << std :: endl ; if ( x < y or x < z ) x = y + z; std :: cout << " x = " << x << std :: endl ; return 0; }

C.1.6

Operadores de bits (&, |)

Os operadores de bits s ao utilizados para testar determinadas condi co es. Prot otipo & bitand ^ xor | bitor >> << Opera ca o and para bits. Se os bits x e y s ao 1, ent ao retorna 1. Opera ca o and para bits. Opera ca o ou exclusiva. Se os bits x e y forem diferentes, retorna 1. Opera ca o ou exclusiva. Opera ca o ou inclusiva. Se os bits x e y s ao 0 retorna 0. Opera ca o ou inclusiva. Rotaciona bits para direita. Rotaciona bits para esquerda.

Veja exemplo de uso de operadores de bits na listagem C.3. Listing C.3: Usando os operadores de bits.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # include < iostream > using namespace std ; int main () { int n u m e r o I n t e i r o ; int mascara = 1 << 31; // Um l o o p i n g i n f i n i t o while ( true ) { cout << " \ nDigite um n u mero inteiro ( ctrl + c para encerrar ) : \ n " ; cin >> n u m e r o I n t e i r o ; cout << " N u mero = " << n u m e r o I n t e i r o << " , e sua r e p r e s e n t a c a ~ o em bits = " ; // P e r c o r r e os 32 bits for ( int i = 1; i <= 32; i ++) { // C o m p a r a n u mero com a m ascara char ch = ( n u m e r o I n t e i r o & mascara ) ? 1 : 0 ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

662
22 23 24 25 26 27 28 29 30 31

AOS OPERADORES C.1. INTRODUC AO


// Envia r e s u l t a d o para tela cout << ch ; // R o t a c i o n a o n u mero em 1 bit a e s q u e r d a n u m e r o I n t e i r o < <= 1; // Espa c o para s e p a r a r dados if ( i %8 == 0 && i != 32) cout << ;

} } return 0; } Digite 0 N u mero Digite 1 N u mero Digite 10 N u mero Digite um n u mero inteiro ( ctrl + c para encerrar ) : = 0 , e sua r e p r e s e n t a c a ~ o em bits = 00000000 00000000 00000000 00000000 um n u mero inteiro ( ctrl + c para encerrar ) : = 1 , e sua r e p r e s e n t a c a ~ o em bits = 00000000 00000000 00000000 00000001 um n u mero inteiro ( ctrl + c para encerrar ) : = 10 , e sua r e p r e s e n t a c a ~ o em bits = 00000000 00000000 00000000 00001010 um n u mero inteiro ( ctrl + c para encerrar ) :

C.1.7

Operador condicional (?)

O operador condicional eou nico operador tern ario do C++. Veja o prot otipo. Se a condi ca o a a express ao falsa. for verdadeira, executar a a express ao verdadeira, e se for falsa, executar Prot otipo: ao falsa); (condi ca o)? (express ao verdadeira): (express Exemplo: int maior = x > y ? x : y;

C.1.8

Operador incremento (++) e decremento (--)

Se voc e tem uma vari avel inteira e quer increment a-la de 1 (somar a 1), utilize o operador de incremento ++; para diminuir de 1, utilize o operador decremento --. Para obter: valor = valor + 1; , fa ca: ++valor;. Para obter: valor = valor - 1;, fa ca: --valor;. As opera co es de incremento/decremento podem ser do tipo postx ou prex, veja exemplo. A opera ca o postx (++y), utiliza o valor de y para calcular x e depois incrementa y. A opera ca o prex (++y), primeiro incrementa o valor de y e depois utiliza o valor de y para calcular z. Exemplo: int y = 5; // Define y = 5. int x = 5 + y++; // Faz x = 10 e depois y = 6. int z = 5 * ++y; // Faz y = 7 e depois z = 5*7 = 35. Um exemplo de uso do operador incremento e apresentado na listagem C.4. Listing C.4: Usando operador de incremento.
1 2 3 4 # include < iostream > using namespace std ; int main ()

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

AOS OPERADORES C.1. INTRODUC AO


5 6 7 8 9 10 11 12 13 14 15 { int contador = 0; cout << contador << endl << ( contador ++) << endl << contador << endl ; contador = 0; cout << contador << endl << (++ contador ) << endl << contador << endl ; return 0; } // E s c r e v e 0 na tela // E s c r e v e 0 e depois faz c o n t a d o r =1 // E s c r e v e 1 // E s c r e v e 0 // I n c r e m e n t a c o n t a d o r e e s c r e v e na tela // E s c r e v e 1

663

C.1.9

Operador v rgula (a,b)

O operador v rgula avalia duas express oes onde a sintaxe s o permite uma. Prot otipo: ao da direita) (express ao da esquerda),(express Exemplo: int x,y,z; for( int min = 0 , int max = 10 ; min < max ; min++ , { cout < < min < < " " < < max < < " "; }

max- )

Observe dentro do for a declara ca o de dois inteiros utilizando o separador v rgula: int min = 0 , int max = 10

C.1.10

Operador m odulo (%)

O operador m odulo (%) retorna o resto de uma divis ao. No prot otipo a seguir, o resultado e o resto da divis ao de a por b. Prot otipo: A%B Retorna o resto da divis ao de A por B.

Veja no exemplo a seguir a utiliza ca o da fun ca o rand() da biblioteca matem atica-padr ao de C e do operador m odulo. Exemplo: #include <cmath> int a = 7, b = 4; int x = a % b; // x = 3 e o resto da divis~ ao de a por b x = rand() % 6; // x e um valor rand^ omico entre 0 e 5 // N umero rand^ omico entre min e min + max int n = min + rand() % (max + 1 -min); Veja na listagem C.5 exemplo de uso do operador m odulo (%) e do operador tern ario (?). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

664

AOS OPERADORES C.1. INTRODUC AO Listing C.5: Usando operador m odulo % e operador tern ario ?

1 2 3 4 5 6 7 8 9 10 11 12 13

# include < iostream > int main () { int contador = 1; std :: cout << " 5%4 int x = 5; int y = 3; int z = x > y ? x std :: cout << " \ nx << " z = return 0; }

= " << (5 % 4) << std :: endl ;

: y; = 5, y = 3, z = x > y ? x : y ;" " << z << std :: endl ;

5%4=1 x =5 , y =3 , z = x > y ? x : y ; z =5

C.1.11

Operador new

Veja descri ca o do operador new na se ca o 15.3.1.

C.1.12

Operador delete

Veja descri ca o do operador delete na se ca o 15.3.2.

C.1.13

Operador typedef

Veja descri ca o do operador typedef na se ca o 9.5.1.

C.1.14

Operador sizeof

Veja a descri ca o do operador sizeof na se ca o 9.5.3. Veja na listagem ?? exemplo de uso de sizeof.

C.1.15

Operador size_t

Veja descri ca o do operador size_t na se ca o 9.5.2.

C.1.16

Operador de resolu c ao de escopo (::)

O operador de resolu ca o de escopo e utilizado para informar o compilador que queremos acessar a vari avel global. Se utilizarmos o operador de resolu ca o de escopo dentro de uma fun ca o, estaremos acessando a vari avel global externa a ` fun ca o. Veja o exemplo: Exemplo: int x = 70; int main() { int x = 56; int y = x; // y = 56 int z = ::x; // z = 70 pega o x externo a fun c~ ao main() Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

C.2. SENTENCAS PARA OPERADORES return 0; }

665

C.2

Senten cas para operadores

Performance: em testes de compara ca o, sempre teste em primeiro lugar as condi co es mais prov aveis. BUG: e um erro comum utilizar = para comparar dois valores, como na express ao if(x = 3); quando o correto e if(x == 3) um erro comum utilizar =! em vez de !=. E Para inverter um bool, utilize !. Se precisar, utilize par enteses extras para deixar o c odigo mais claro. N ao confunda um operador sobre bits (& e |) com operadores l ogicos (&& e ||). bool pode assumir true(!= 0) ou false(== 0); assim 1 e true, 5 e true, 0 e false.

C.3

Resumo do cap tulo

Neste ap endice aprendemos a usar o operadores de C++. Os operadores aritm eticos, de atribui ca o, compostos, relacionais, l ogicos, de bits, condicional, de incremento e decremento, v rgula, operador m odulo. Operadores de aloca ca o e dele ca o de mem oria (new e delete). O uso de typedef para criar apelidos, e o uso de sizeof e size_t. Finalmente, vimos o operador de resolu ca o de escopo.

C.4

Exerc cios

1. Dados os operadores (), new e ==, qual tem maior preced encia? 2. Monte um exemplo que utilize todos os operadores aritm eticos. 3. Explique a diferen ca entre o operador de atribui ca o e os operadores compostos. 4. Compilar e rodar o exemplo da listagem C.1, usando diferentes valores de a e b. Depois, modique o exemplo da listagem C.1. 5. Modique o exemplo da listagem C.2. 6. Modique o exemplo da listagem C.3. 7. Modique o exemplo da listagem C.4. 8. Modique o exemplo da listagem C.5. 9. Modique o exemplo da listagem ??.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

666

C.4. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice D

Estruturas de Controle
Apresenta-se neste ap endice uma introdu ca o ` as estruturas de controle (se ca o D.1). Veremos as estruturas condicionais (se ca o D.2) e as estruturas de repeti ca o (se ca o D.3). No nal do cap tulo s ao listados alguns programas que mostram o uso pr atico das estruturas de controle.

D.1

Introdu c ao ` as estruturas de controle

Um programa sem estruturas de controle e um programa sequ encial, em que uma linha e executada ap os a outra. De um modo geral as linguagens de programa ca o oferecem dois tipos de estruturas de controle, ` as condicionais e as de repeti ca o. Ambas podem ser utilizadas para alterar a sequ encia de execu ca o do programa. Nas estruturas condicionais a sequ encia de execu ca o e alterada em fun ca o de decis oes que s ao tomadas durante a execu ca o do programa. J a as estruturas de repeti ca o s ao utilizadas para realiza ca o de repeti co es (la cos/loopings) de um determinado bloco de c odigo. As estruturas de controle de C++ s ao: Estruturas condicionais if (veja se ca o D.2.1), if..else (veja se ca o D.2.2), if..else..if..else (veja se ca o D.2.3), switch..case (veja se ca o D.2.4), operador? (veja se ca o D.2.5). Estruturas de repeti ca o for (veja se ca o D.3.1), while (veja se ca o D.3.2), do..while (veja se ca o D.3.3), break (veja se ca o D.3.4), continue (veja se ca o D.3.5). Bem, antes de come car vale a pena lembrar que uma express ao e verdadeira se retorna um n umero diferente de 0 (ou true), e e falsa se retorna 0 (ou false). 667

668

D.2. ESTRUTURAS CONDICIONAIS

D.2

Estruturas condicionais

Nas estruturas condicionais a sequ encia de execu ca o e alterada em fun ca o de decis oes que s ao tomadas durante a execu ca o do programa.

D.2.1

if

Um instru ca o if e utilizada para garantir que determinada a ca o s o ser a executada se a express ao condicional for verdadeira. No prot otipo a seguir, se a express ao for verdadeira vai executar a pr oximo linha (ou bloco). Prot otipo: if(express ao condicional) a ca o; Prot otipo: if(express ao condicional) { a ca o1; a ca o2;...a ca oN; } Exemplo: int x = 0, y = 1; if( x > y ) cout < < x > y. ;

D.2.2

if.....else

Uma estrutura de controle do tipo if..else e utilizada quando a a ca o a ser executada depende de uma condi ca o. Veja no prot otipo a seguir que numa estrutura de controle do tipo if..else, se a express ao for verdadeira vai executar a a c~ ao1, se for falsa vai executar a a c~ ao2. No exemplo, como x n ao e maior ou igual a y, vai imprimir x < y. Prot otipo: if(express ao condicional) a ca o1; else a ca o2; Exemplo: int x = 0; int y = 1; if( x >= y ) { cout < < "x >= y"< < endl; } else { cout < < "x < y"< < endl; } Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

D.2. ESTRUTURAS CONDICIONAIS

669

D.2.3

if......else if......else if......else

Outra estrutura de controle condicional, if..else..if..., e utilizada quando a a ca o a ser executada al em de depender de uma condi ca o espec ca, esta relacionada as demais condi co es e a co es. O uso de if..else..if..else, produz um c odigo r apido. Sempre coloque no in cio da sequ encia de if..else os tens com maior probabilidade de ocorr encia. O primeiro if que for verdadeiro vai ser executado, os demais s ao pulados. Cada else esta associado ao if imediatamente acima. Prot otipo: if(express ao condicional1) ...a ca o1...; else if (express ao condicional2) a ca o2; ... else if (express ao condicional n) a ca o n; No exemplo a seguir se a idade e menor do que 12 ent ao a sa da ser a crian ca. Se a idade e maior que 12 e menor do que 18 ent ao a sa da ser a adolescente. Se a idade for maior que 18 a sa da ser a adulto. Exemplo: if( idade < 12 ) cout < < "crian ca"; else if ( idade < 18 ) cout < < "adolescente"; else cout < < "adulto";

D.2.4

switch....case

A instru ca o switch case e utilizada quando se deseja fazer uma sele ca o entre uma s erie de semelhante a uma sequ op co es. E encia if..else. Se nenhuma op ca o satisfazer a condi ca o vai realizar a instru ca o default. Veja prot otipo a seguir. Note que resposta deve ser inteiro ou ser convertido para inteiro. Observe que o m de uma instru ca o case: n ao e automaticamente delimitado pelo in cio do pr oximo case, precisamos incluir a palavra-chave break. Prot otipo: switch (resposta) { case a: intru co es1; break; case b: intru co es2; break; default: instru ca o default; }

// Se resposta == a // Realiza instru co es 1 // Encerra o switch // Se resposta == b // Realiza instru co es 2 // Encerra o switch // Opcional (sempre a u ltima)

A listagem D.1 mostra o uso de switch. Veremos o uso de for na se ca o D.3.1. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

670

D.2. ESTRUTURAS CONDICIONAIS Listing D.1: Usando switch.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

# include < vector > # include < iostream > # include < iomanip > # include < string > using namespace std ; int main () { vector < string > time ; time . push_back ( string time . push_back ( string time . push_back ( string time . push_back ( string

( " Palmeiras " ) ) ; ( " Corintians " ) ) ; ( " S~ a o Paulo " ) ) ; ( " Santos " ) ) ;

cout << " Para encerrar , digite o caractere de fim de arquivo .\ n " << " No Windows / DOS ( ctrl + z ) no GNU / Linux , Unix ( ctrl + d ) :\ n " << " --> Qual o seu time do cora ca ~ o < - -:\ n " ; for ( int i = 0; i < time . size () ; i ++) cout << setw (20) << time [ i ] << " ( " << setw (2) << i << " ) : " << endl ; int resp ; while ( cin >> resp ) { cin . get () ; string osite ( " O site de seu time est a em : \ n " ) ; switch ( resp ) { case 0: cout << " Parab e ns , voc^ e escolheu um t e t r a c a m p e a ~ o Brasileiro . " << osite << " http :// www . palmeiras . com . br / " << endl ; break ; case 1: cout << " Parab e ns , voc^ e escolheu um tricampe~ a o Brasileiro . " << osite << " http :// www . corinthia n s . com . br / " << endl ; break ; case 2: cout << " Parab e ns , voc^ e escolheu um tricampe~ a o Brasileiro " << osite << " http :// www . spfc . com . br / " << endl ; break ; case 3: cout << " Parab e ns , voc^ e escolheu um campe~ a o Brasileiro . " << osite << " http :// www . s a n t o s f u t e b o l c l u b e . com . br / " << endl ; break ; default : cout << " Entrou na op ca ~ o default do switch , ou seja , voc^ e entrou " << " com uma op ca ~ o errada , repita a opera ca ~ o . " << endl ; break ; // Break o p c i o n a l } } return 0; } Para encerrar , digite o caracter de fim de arquivo . No windows / DOS ( ctrl + z ) no unix / linux / mac ( ctrl + d ) : --> Qual o seu time do cora ca ~ o < - -:

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

D.3. ESTRUTURAS DE REPETIC AO


Palmeiras ( 0) : Corintians ( 1) : S~ a o Paulo ( 2) : Santos ( 3) : 0 Parab e ns , voc^ e escolheu um tetra - campe~ a o Brasileiro . O site de seu time esta em : http :// www . palmeiras . com . br /

671

D.2.5

express~ ao_condicional?

a c~ ao_verdadeira :

a c~ ao_falsa;

O operador condicional ? eou nico operador tern ario do C++, o mesmo foi descrito na se ca o C.1.7.

D.3

Estruturas de repeti c ao

Nas estruturas de repeti ca o um determinado bloco de c odigo e repetido um determinado n umero de vezes. As estruturas de repeti ca o s ao utilizadas para realiza ca o la cos/loopings. O objetivo das estruturas de controle e possibilitar o controle e as tomadas de decis oes nos programas.

D.3.1

for ( in cializa c~ ao ; condi c~ ao ; a c~ ao2 ) a c~ ao1;

O for e uma estrutura de controle de repeti ca o utilizado para a realiza ca o de la cos (loopings ). O prot otipo a seguir ilustra a forma de uso do for. O primeiro tem e a inicializa ca o da vari avel de controle do la co. O segundo tem e a condi ca o utilizada para continuar no la co. Se a condi ca o for falsa o la co e encerrado. O terceiro tem, a a c~ ao1 e a opera ca o que vai ser executada a cada la co. J a a a c~ ao2, e utilizada, geralmente, para modicar a vari avel de controle. Prot otipo: for( inicializa ca o; condi ca o; a ca o2 ) a ca o1; No exemplo abaixo, cria uma vari avel cont do tipo int e inicializa com o valor 3. A seguir testa se cont e menor que 20. Depois do teste, entra dentro do bloco e executa a linha (cout < < "\nO valor de cont e agora = " < < cont;). Depois de realizada a execu ca o do bloco, a a c~ ao2 e executada, isto e, cont++. Exemplo: for ( int cont = 3; cont < 20; cont++ ) { cout < < "\nO valor de cont e agora = " < < cont ; } cout < < \nfor encerrado < < endl; Veja abaixo a seq uencia de execu ca o: int cont = 3; cont < 20 ? cout < < "\nO valor de cont e agora = " < < cont; cont++; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

672

D.3. ESTRUTURAS DE REPETIC AO cont < 20 ? cout < < "\nO valor de cont e agora = " < < cont; cont ++; cont < 20 ? cout < < "\nO valor de cont e agora = " < < cont; cont++; .... // Quando cont = = 20 o for e encerrado. cout < < \nfor encerrado < < endl;

Reveja agora as listagens 8.4 e 8.5.

D.3.2

while (condi c~ ao) {a c~ ao;};

Enquanto a condi ca o for verdadeira executa a a ca o. O comando while pode ser usado no lugar de for, veja o prot otipo e exemplo a seguir. Prot otipo: while ( condi ca o ) { a ca o; }; Exemplo: // O for abaixo, for( inicio ; condi c~ ao ; a c~ ao2 ) { a c~ ao1; } // Pode ser realizado usando while desta forma inicio; while( condi c~ ao ) { a c~ ao1; a c~ ao2; } Veja exemplos de uso de while nas listagens 8.6 e D.2. Listing D.2: Usando while.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include < iostream > using std :: cout ; using std :: endl ; int main () { int y , x = 1 , total = 0; while ( x <= 5) { y = x * x; cout << x << " \ t " << y << endl ; total += y ; ++ x ; } cout << " Total = " << total << endl ; return 0; }

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

D.3. ESTRUTURAS DE REPETIC AO


1 1 2 4 3 9 4 16 5 25 Total = 55

673

D.3.3

do {a c~ ao} while (condi c~ ao);

O comando do while, realiza a a ca o e somente depois testa a condi ca o. Desta forma a a ca o e executada pelo menos uma vez. Veja a seguir o prot otipo e na listagem D.3 um exemplo. Prot otipo: do { a ca o; } while ( express ao condicional ); Listing D.3: Usando do..while.
1 2 3 4 5 6 7 8 9 10 11 12 13 # include < iostream > int main () { int i = 1; do { // Sempre r e a l i z a o l o o p i n g pelo menos 1 vez . std :: cout << i << " " ; } while (++ i <= 10) ; std :: cout << std :: endl ; return 0; } 1 2 3 4 5 6 7 8 9 10

D.3.4

break

Um break pode ser usado dentro de um for, em um while, do...while, ou switch. Quando um break e encontrado, o bloco e encerrado. No prot otipo a seguir, se a condi ca o2 for verdadeira a a c~ ao2 n ao ser a executada, e o for e encerrado. Prot otipo: for( inicio; condi ca o ; a ca o3 ) { a ca o1; if( condi ca o2 ) break; a ca o2; } Veja a seguir um exemplo. Exemplo: for( int i = 0; i < 10 ; i++ ) { Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

674 cout < < "valor de i = " < < i < < endl; if( i == 5 ) break; cout < < "Passou pelo break" < < endl; }

D.3. ESTRUTURAS DE REPETIC AO

D.3.5

continue

O controle continue (usado em for, while, do..while), faz com que o programa pule as pr oximas linhas e prossiga na express ao que controla o la co. Isto e, quando continue e executado todos os pr oximos passos s ao pulados e o pr oximo la co e executado. Se assemelha a um comando goto. No prot otipo a seguir, se a condi ca o for verdadeira, a a c~ ao2 n ao e executada, o pr oximo passo a ser executado e a a c~ ao3 e a seguir a condi ca o. Prot otipo: for( inicio; condi ca o; a ca o3 ) { a ca o1; if( condi ca o ) continue; a ca o2; } Veja exemplo de uso de break e continue na listagem D.4. Listing D.4: Usando break, continue, do..while, e switch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 # include < iostream > using namespace std ; void T e s t a n d o _ b r e a k () ; void T e s t a n d o _ c o n t i n u e () ; int main () { char resp ; do { cout << " Testar o break ( b ) ou o continue ( c ) , ( q ) para sair : " ; cin . get ( resp ) ; cin . get () ; switch ( resp ) { case b : case B : T e s t a n d o _ b r e a k () ; break ; case c : case C : T e s t a n d o _ c o n t i n u e () ; break ; case q : case Q : cout << " Tchau . " << endl ; break ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

D.4. SENTENCAS PARA ESTRUTURAS DE CONTROLE


32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

675

default : cout << " Op ca ~ o inv a lida : " << endl ; } } while ( resp != q && resp != Q ) ; return 0; } void T e s t a n d o _ b r e a k () { for ( int x = 1; x <= 10; x ++ ) { if ( x == 5) break ; // E n c e r r a o l o o p i n g quando x ==5 cout << x << ; } cout << " \ nQuando x ==5 , executa o break e sai do looping . " << endl ; } void T e s t a n d o _ c o n t i n u e () { for ( int x = 1; x <= 20; x += 1 ) { if ( x == 5) continue ; // Pula para p r o x i m o passo do l o o p i n g quando x ==5 cout << x << " ; " ; } cout << " \ nUm continue continua o looping , mas pula todas as linhas abaixo . " << " \ nObserve acima que n~ a o imprimiu o n u mero 5. " << endl ; } Testar o break ( b ) ou o continue ( c ) , ( q ) para sair : b 1 2 3 4 Quando x ==5 , executa o break e sai do looping . Testar o break ( b ) ou o continue ( c ) , ( q ) para sair : c 1;2;3;4;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20; Um continue continua o looping , mas pula todas as linhas abaixo . Observe acima que n~ a o imprimiu o n u mero 5. Testar o break ( b ) ou o continue ( c ) , ( q ) para sair : q Tchau .

D.4

Senten cas para estruturas de controle

As estruturas de controle s ao utilizadas em la cos (loopings ), na realiza ca o de contagens, na escolha entre diferentes blocos de instru co es. Os objetos declarados dentro do for s o s ao vis veis dentro do for. Evite o uso de do...while();. Enquanto break encerra o la co, continue continua sem executar as linhas que est ao abaixo.

D.5

Resumo do cap tulo

Neste ap endice aprendemos a usar as estruturas de controle de C++. As estruturas condicionais, if, if..else, if..else..if..else, switch..case, e o operador ?. Vimos ainda as Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

676 estruturas de repeti ca o, for, while, do..while, break, e continue.

D.6. EXERC ICIOS

D.6

Exerc cios

1. Comece modicando os exemplos das listagens deste cap tulo. 2. Na listagem D.1 acrescente dados do seu time de cora ca o. 3. Na listagem D.1 elimine os break e veja o que acontece. 4. Na listagem 8.4 mude os valores iniciais e nais do la co e veja o que acontece. 5. Modique a listagem 8.5. Fa ca a mesma coisa usando dentro do primeiro for um while. 6. Modique a listagem 8.6 acrescentando uma mensagem de erro e um break caso o valor da potencia ultrapasse o limite suportado para um int. 7. Na listagem D.2 modique os valores iniciais de x, e a condi ca o de sa da do while. Pense em acrescentar dentro do while um for. 8. Na listagem D.3 modique o valor inicial de i e a condi ca o de sa da. Pe ca para o usu ario entrar com estes dados. 9. Monte um pequeno programa de cadastro de alunos de um col egio. O programa deve: (a) ter fun co es para adicionar/eliminar novos alunos. (b) ter uma fun ca o de entrada que deve solicitar os seguintes dados: Nome do aluno, idade, n umero de registro no col egio, coecienteDeRendimento. (c) ter duas fun co es de sa da. A primeira deve mostrar na tela a lista de alunos em ordem crescente usando a idade como par ametro classicador. A segunda fun ca o deve usar o n umero de registro como par ametro classicador. (d) a sele ca o do tipo de fun ca o a ser executada deve ser feita utilizando-se um switch. 10. Para o programa acima descrito monte uma fun ca o que recebe dois alunos como par ametros. A fun ca o deve imprimir na tela os dados do aluno que tem o maior coecienteDeRendimento. Esta fun ca o ser a utilizada para efeitos de classica ca o dos alunos quando os mesmos solicitarem alguma bolsa de aux lio. 11. Para o programa acima descrito monte uma fun ca o que mostra na tela a lista de alunos aprovados (notaM edia >= 6) e a lista de alunos reprovados (notaM edia < 6). Nota: voc e encontra na refer encia [Holloway, 2006], diversos exemplos de algoritmos em C++, e nas refer encias [Cormen et al., 2002, Boente, 2006] exemplos gen ericos de algoritmos.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice E

Fun c oes - Uso Avan cado


Veremos neste ap endice uma complementa ca o dos conceitos vistos no Cap tulo 13 - M etodos. Iniciamos apresentando a fun ca o main() e a entrada na linha de comando (se ca o E.1). A seguir discutimos o processamento dos par ametros de main() com getopt() (se ca o E.2). Veremos ainda as fun co es recursivas, (se ca o E.3) e o uso de elipse ... em fun co es (se ca o E.4). Finalmente veremos algumas senten cas para fun co es (se ca o E.5).

E.1

A fun c ao main() e a entrada na linha de comando

A fun ca o principal de um programa e chamada main(). Quando um programa e executado na linha de comando do DOS, Unix, GNU/Linux, Mac OS X, Windows, o sistema operacional chama a fun ca o main() do programa e passa para o programa dois argumentos: o texto da linha de comando e o n umero de strings da linha de comando. Assim, voc e pode utilizar a linha de comando para entrada de informa co es para seu programa. Veja a seguir o prot otipo da fun ca o main(). O par ametro argc e o n umero de elementos da linha de comando e argv[] o vetor para as strings digitadas na linha de comando. Prot otipo: int main(int argc, const char *argv[]) {...... return 0;} No exemplo a seguir, o programa recebe um vetor com as strings {cp, funcoes.lyx, funcoes.lyx~} e o n umero de argumentos da linha de comando que e 3. Exemplo: // Na linha de comando do GNU/Linux digitou-se: cp funcoes.lyx funcoes.lyx~ // O programa interpreta o seguinte: // argc = 3 // argv[0] = "cp" // argv[1] = "funcoes.lyx" // argv[2] = "funcoes.lyx~" Veja na listagem E.1 exemplo de uso de entrada na linha de comando. Listing E.1: Fun ca o main() e a entrada na linha de comando.
1 2 # include < iostream > using namespace std ;

677

678
3 4 5 6 7 8 9 10 11

E.2. PROCESSANDO PARAMETROS DE MAIN() COM GETOPT()

int main ( int argc , char ** argv ) { cout << " argc = " << argc << endl ; int cont = argc ; while ( cont - -) cout << " argv [ " << cont << " ]= " << argv [ cont ] << endl ; return 0; } [ b u e n o @ s u p o r t e 3 Parte - VI ] $ ./ a . out opcao1 opcao2 opcao3 argc =4 argv [3]= opcao3 argv [2]= opcao2 argv [1]= opcao1 argv [0]=./ a . out

E.2

Processando par ametros de main() com getopt()

A fun ca o getopt(), declarada no arquivo de cabe calho /usr/include/unistd.h, fornece um mecanismo simples para processar a linha de comando. Veja a seguir o prot otipo da fun ca o getopt(). Como existem casos e necessidades especiais, tamb em foram denidas um conjunto de vari aveis globais que s ao utilizadas por getopt(): Prot otipo: extern char *optarg; // Ponteiro para pr oxima string extern int optind; // Indice para pr oximo argumento extern int opterr; // Flag de erro extern int optopt; // Caracter inv alido const char* optstring; // Lista de par ametros v alidos int getopt ( int argc, char* argv[], const char* optstring ); A fun ca o getopt() recebe os par ametros argc e argv[], e uma string de C (const char* optstring ) com a lista de par ametros v alidos (ex: -abc:d). Se o par ametro e v alido o mesmo e retornado. Se o par ametro e inv alido o retorno e o caracter ? e optopt e setado com o caracter inv alido. Se o par ametro requer um valor adicional (ex: -c arq.dat) e o mesmo n ao e fornecido, retorna :. Se n ao existem mais par ametros retorna -1. Em alguns sistemas, quando um par ametro n ao e v alido, uma mensagem de erro e enviada para sa da de erro. O exemplo da listagem E.2 mostra o uso de getopt(). Observe que a cada chamada getopt() processa uma nova op ca o. O uso de : depois de c indica que c recebe um argumento string, a mesma e recuperada com optarg. Listing E.2: Processando par ametros de main() com getopt().
1 2 3 4 5 6 7 8 9 10 # include < unistd .h > # include < iostream > using namespace std ; int main ( int argc , char * argv []) { int opt ; // E n q u a n t o o r e t o r n o da fun c~ a o getopt () for d i f e r e n t e de -1 // p r o c e s s a linha de c o m a n d o while (( opt = getopt ( argc , argv , " abc : d " ) ) != -1)

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

E.3. FUNC OES RECURSIVAS


11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 { switch ( opt ) { case a : cout << break ; case b : cout << break ; case c : cout << << break ; case d : cout << break ; case ? : cout << break ; case : : cout << break ; }

679

" Op ca ~ o = " << static_cast < char >( opt ) << endl ;

" Op ca ~ o = " << static_cast < char >( opt ) << endl ; // inclui a r g u m e n t o adicional , uso de optarg " Op ca ~ o = " << static_cast < char >( opt ) " Argumento = " << optarg << endl ;

" Op ca ~ o = " << static_cast < char >( opt )

<< endl ;

// Indica op c~ ao inv alida " Op ca ~ o Inv a lida = " << static_cast < char >( optopt ) << endl ; // Indica falta de a r g u m e n t o s " Falta de argumentos . " << endl ;

} // Lista de a r g u m e n t o s errados , m o v i d o s para o fim de argv for (; optind < argc ; optind ++) cout << " Op ca ~ o inv a lida argv [ " << optind << " ]= " << argv [ optind ] << endl ; // R e s t a n t e do p r o g r a m a ... return 0; } bash -3.00 $ ./ a . out - a Op ca ~o = a bash -3.00 $ ./ a . out - abc Op ca ~o = a Op ca ~o = b ./ a . out : option requires an argument -- c Op ca ~ o Inv a lida = c bash -3.00 $ ./ a . out - abc arg . dat Op ca ~o = a Op ca ~o = b Op ca ~ o = c Argumento = arg . dat bash -3.00 $ ./ a . out - ab -c arg . dat -f Op ca ~o = a Op ca ~o = b Op ca ~ o = c Argumento = arg . dat ./ a . out : invalid option -- f Op ca ~ o Inv a lida = f

E.3

Fun c oes recursivas

Uma fun ca o recursiva e uma fun ca o que chama a s mesma. Veja a seguir um exemplo de fun ca o recursiva. A mesma e utilizada para calcular o n umero de Fibonaci. Observe que dentro do else a fun ca o e chamada de forma recursiva. Exemplo: // N umeros de Fibonaci long fibonaci(long n) Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

680

E.4. USO DE ELIPSE ... EM FUNC OES { if(n==0 || n==1) return n; else return fibonaci(n-1) + fibonaci(n-2); // Observe a recurs~ ao }

Observe que em fun co es recursivas existe um excesso de chamadas de fun co es, o que diminui a performance do sistema. O exemplo da listagem E.3 apresenta uma fun ca o recursiva que calcula o fatorial de um n umero. Listing E.3: Fun ca o recursiva: c alculo do fatorial.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 # include < iostream > # include < iomanip > using namespace std ; long int fatorial ( long int ) ; // D e c l a r a c~ a o da fun c~ ao

int main () { long int min ; cout << " Entre com o valor m nimo ( min ) : " ; cin >> min ; long int max ; cout << " Entre com o valor m a ximo ( max ) : " ; cin >> max ; cin . get () ; // Pega o enter for ( long int i = min ; i <= max ; i ++) cout << setw (2) << i << " ! = " << fatorial ( i ) << endl ; return 0; } // D e f i n i c~ a o da fun c~ a o ( lembre - se , f a t o r i a l 5 = 5 * 4 * 3 * 2 * 1 ) long int fatorial ( long int n ) { if ( n <= 1) // Se for menor ou igual a 1 r e t o r n a 1 ( f i n a l i z a ) return 1; else // Se for >1 chama fun c~ ao fatorial novamente ( recurs~ a o) return n * fatorial ( n - 1) ; } Entre com o valor m nimo ( min ) : 5 Entre com o valor m a ximo ( max ) : 9 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880

E.4

Uso de elipse ... em fun c oes

A elipse refere-se a tr es pontos como par ametro de uma fun ca o. Uma elipse numa lista de par ametros signica que a fun ca o pode receber mais par ametros. Um exemplo de fun ca o que Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

E.5. SENTENCAS PARA FUNC OES

681

utiliza elipses e a printf() (de C), que pode receber um n umero variado de par ametros. Para maiores informa co es, veja a fun ca o printf() e o help de seu ambiente de desenvolvimento. Veja na listagem E.4 exemplo de uso de elipse. Observe que a fun ca o va_start inicializa a retirada de vari aveis da pilha, a fun ca o va_arg retira uma vari avel da pilha, especicando o tamanho em bytes da vari avel (o que e feito passando o double), e a fun ca o va_end naliza a retirada de dados da pilha. Isto signica que a utiliza ca o de elipse altera o estado da pilha e sua utiliza ca o deve ser evitada, ou utilizada somente ap os a fun ca o ter sido extensivamente testada. Listing E.4: Usando elipses (...) : fun ca o m edia.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 # include < cstdarg > # include < iostream > # include < cmath > // D e c l a r a c~ a o da fun c~ a o Media double Media ( int n ,...) ; // n e o n u mero de e l e m e n t o s int main () { double media ; int n =4; double i =1 , j =2 , k =3 , l =4; std :: cout << " M e dia = " << Media (n ,i ,j ,k , l ) ; return 0; } // D e f i n i c~ a o da fun c~ a o Media () , o b s e r v e o uso de elipse ... double Media ( int n ,...) { double total = 0; va_list variavel ; // Cria lista v a r i avel va_start ( variavel , n ) ; // I n i c i a l i z a lista v a r i avel for ( int j = 1 ; j <= n ; j ++ ) { double valor = va_arg ( variavel , double ) ; std :: cout << " valor lido = " << valor << std :: endl ; total += valor ; } va_end ( variavel ) ; // E n c e r r a lista return total / n ; } valor valor valor valor M e dia lido = lido = lido = lido = = 2.5 1 2 3 4

E.5

Senten cas para fun c oes

Objetos grandes devem ser passados por refer encia ou por ponteiros. O nome de uma fun ca o e um ponteiro para fun ca o com endere co constante, denido na compila ca o. Em C++ podemos declarar a fun ca o assim: void NomedaFuncao(); // C++ void NomedaFuncao(void); // C Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

682

E.6. RESUMO DO CAP ITULO

Quando utilizamos uma matriz como argumento de uma fun ca o, os valores s ao passados por refer encia e n ao por c opia. Se a matriz estiver dentro de uma estrutura, ela ser a passada por c opia. Como as fun co es de C++ denidas em um arquivo podem ser utilizadas em outro arquivo, as mesmas tem uma liga ca o extern por default. Performance: par ametros passados por refer encia aumentam a eci encia, pois os valores n ao s ao copiados. Na fun ca o main(), o retorno do valor 0 informa ao sistema operacional que o programa foi nalizado com exito. Qualquer valor diferente de zero indica um erro. Dentro da fun ca o main(), inclua um mecanismo simples de tratamento de exce co es. Veja Cap tulo 26 - Exce co es. Quando main() e encerrada com return(); ou exit(); os objetos est aticos s ao destru dos na ordem inversa em que foram constru dos. Seguran ca: se voc e quer ter certeza de que o par ametro n ao ser a alterado, deve pass a-lo como refer encia constante. Veja o exemplo a seguir. O especicador const informa que a vari avel e constante e n ao pode ser alterada dentro da fun ca o. Deste modo, a fun ca o pode acessar a vari avel, mas n ao pode modic a-la. Exemplo: fun c~ ao(const tipo& vari avel);

E.6

Resumo do cap tulo

Neste ap endice aprendemos a utilizar a fun ca o main() e a entrada na linha de comando. Aprendemos que main() e a fun ca o de entrada em um programa em C/C++ e que seus par ametros podem ser processados com getopt(). Vimos ainda as fun co es recursivas, e o uso de elipse ... em fun co es.

E.7

Exerc cios

1. Modique a listagem 8.11 de forma que a lista de n umeros aleat orios seja salva em disco. 2. Use o nd de seu computador para localizar a biblioteca cstdlib (no gnu/linux ca em /usr/include/c++/vers ao do compilador). Veja o arquivo <cstdlib> e localize a declara ca o das fun co es srand() e rand(). 3. Modique a listagem E.1, fa ca com que a mesma receba uma lista de n umeros inteiros e mostre na tela os valores recebidos e a sua m edia aritm etica. 4. Modique o exemplo da listagem E.2, de forma que a op ca o passada seja utilizada para executar uma fun ca o interna. Por exemplo, m ir a calcular a m edia dos elementos recebidos, s ir a calcular o desvio padr ao, i os valores dever ao ser passados pelo usu ario. 5. Modique a listagem E.3, alertando o usu ario quando o n umero for muito grande. 6. Modique o exemplo da listagem E.4, acrescentando o c alculo do desvio padr ao e a possibilidade de entrada dos dados. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

E.7. EXERC ICIOS 7. Modique a listagem 8.8 de forma que o usu ario entre com o valor do expoente.

683

8. Modique a listagem 8.11 acrescentando o uso de outras fun co es das bibliotecas de C. 9. Implementar fun ca o para c alculo do n umero de Fibonaci (veja se ca o E.3).

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

684

E.7. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice F

Ponteiros - Uso Avan cado


Os ponteiros foram vistos no Cap tulo 15 - Utiliza ca o de Ponteiros e Refer encias. Veremos neste ap endice conceitos adicionais sobre ponteiros. Opera co es com ponteiros (+/-) (se ca o F.1). Ponteiro void* (se ca o F.2). Ponteiro para ponteiro (se ca o F.3). Convers ao de ponteiros (se ca o F.4). Utilizando auto_ptr (se ca o F.5). Ponteiro de fun ca o (se ca o F.6). Ponteiros para m etodos e atributos da classe (se ca o F.7). Ponteiros em hierarquias (se ca o F.8).

F.1

Opera c oes com ponteiros (+/-)

Opera co es que podem ser realizadas com ponteiros: A subtra ca o de dois ponteiros retorna o n umero de elementos entre os dois ponteiros. Exemplo: int array = {0,1,2,3,4}; int* ptr1 = &array[0]; int* ptr2 = &array[4]; No exemplo abaixo, o n umero n e o n umero de objetos entre ptr1 e ptr2 int n = ptr2 - ptr1; cout < < "N umero de objetos entre ptr2 e ptr1 = " < < n < <

endl;

Podemos comparar ponteiros com os operadores relacionais (> , >=, <, <= , = =, !=): 685

686

F.2. PONTEIRO VOID* Exemplo: if(ptr == ptr2) cout < < "ptr2 e ptr1 apontam para o mesmo objeto." < <

endl;

Podemos incrementar (ptr++) e decrementar (ptr--) um ponteiro. No exemplo a seguir, se ptr aponta para o elemento 0 de um vetor, ptr++, faz com que passe a apontar para o elemento 1 do vetor. O valor num erico do incremento e denido pelo valor retornado por sizeof: Exemplo: cout < < "O ptr1++; cout < < "O cout < < "O ptr2--; cout < < "O

ponteiro ptr1 aponta para " < < // Incrementa ptr ponteiro ptr1 aponta para " < < ponteiro ptr2 aponta para " < < // Decrementa ptr ponteiro ptr2 aponta para " < <

*ptr1 < < endl; *ptr1 < < endl; *ptr2 < < endl; *ptr2 < < endl;

Podemos somar ou subtrair um ponteiro de um inteiro. No exemplo abaixo, 3 signica 3 vari aveis ` a frente, e n ao 3 bytes. ptr1 = ptr + 3; cout < < "O ponteiro ptr1 aponta para " < < *ptr1 < < endl;

F.2

Ponteiro void*

Um ponteiro void* e um ponteiro de prop osito geral, que aponta para qualquer tipo de objeto e e usualmente utilizado como par ametro de fun co es de prop osito geral. Para ser desreferenciado, um ponteiro void deve ser convertido para um tipo conhecido em tempo de compila ca o, pois um ponteiro void* n ao tem a informa ca o do tipo do objeto para o qual est a apontando. Se um ponteiro e do tipo int*, o objeto apontado tem o tamanho de um inteiro, assim o compilador sabe quantos bytes deve ler a partir do endere co especicado pelo ponteiro. Quando um ponteiro e do tipo void*, o compilador s o sabe a posi ca o para a qual ele aponta, mas n ao sabe a quantidade de bytes que deve ser lida (ou escrita). Veja no exemplo a seguir que tenta colocar 7 em i, mas ocorre um erro, pois void n ao necess pode utilizar o operador desreferencia ca o *. E ario formatar o ponteiro void*, denindo o tamanho da mem oria que vai ser acessada. Exemplo: // ptr_void e um ponteiro para qualquer coisa. void* ptr_void; // Ponteiro para int int * ptr_int; // Cria objeto do tipo int, com nome i e valor 5 int i = 5; // Endere co do objeto i e armazenado em ptr_int ptr_int = & i; // Endere co do objeto i e armazenado em ptr_void ptr_void = & i; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

F.3. PONTEIRO PARA PONTEIRO // Coloca o valor 5 em i *ptr_int = 5; // Tenta colocar 7 em i usando ptr_void (ocorre um erro) *ptr_void = 7; // ok, converte ptr_void para int* e depois desrefer^ encia. *(int*) ptr_void = 7; // C *(static_cast<int*> (ptr_void) = 7; // C++

687

F.3

Ponteiro para ponteiro

Um ponteiro e utilizado para refer encia indireta a um determinado objeto, armazenando o endere co do objeto. Um ponteiro tamb em e um objeto. Logo, um ponteiro pode apontar para outro ponteiro. Veja o exemplo. Listing F.1: Ponteiro de ponteiro.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 # include < iostream > using namespace std ; int main () { int variavel = 33; int * ptr1 ; int ** ptr2 ; int *** ptr3 ; // P o n t e i r o com e n d e r e camento indireto simples // P o n t e i r o com e n d e r e c a m e n t o i n d i r e t o duplo // P o n t e i r o com e n d e r e c a m e n t o i n d i r e t o triplo

ptr1 =& variavel ; // Coloca e n d e r e c o da v a r i a v e l em ptr1 , // ou seja , ptr1 aponta para v a r i avel ptr2 = & ptr1 ; // ptr2 aponta para ptr1

ptr3 = & ptr2 ; // ptr3 aponta para ptr2 cout << " vari a vel = " << variavel << endl ; * ptr1 = 5; // A r m a z e n a o valor 5 em v a r i a v e l ( usando ptr1 ) cout << " vari a vel = " << variavel << endl ; ** ptr2 = 7; // A r m a z e n a o valor 7 em v a r i a v e l ( usando ptr2 ) cout << " vari a vel = " << variavel << endl ; *** ptr3 = 14; // A r m a z e n a o valor 14 em v a r i a v e l ( usando ptr3 ) cout << " vari a vel = " << variavel << endl ; return 0; } vari a vel vari a vel vari a vel vari a vel = = = = 33 5 7 14

Vamos relatar este u ltimo caso ***ptr3 = 14; utilizando novamente a met afora do carteiro. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

688

DE PONTEIROS F.4. CONVERSAO

O pobre do carteiro tem muito trabalho. Ele pega o n umero 14 e vai at e a casa de ptr3. Chegando l a, recebe ordem para ir at e a casa de ptr2; j a cansado, chega at e a casa de ptr2 e, para sua surpresa, recebe ordem para ir at e ptr1. Chateado e com fome, vai at e a casa de ptr1;. Para sua desgra ca, recebe ordem para ir at e a casa da vari avel; o pobre coitado leva o n umero 14 at e a casa da vari avel e, como n ao e de ferro, descansa. Em resumo: Quando voc e faz Tipo *ptr; est a criando um ponteiro para o Tipo. Quando voc e utiliza ptr1= &algo;, est a armazenando o endere co da vari avel no ponteiro. Quando voc e utiliza int **ptr2= &ptr1;, est a criando um ponteiro de ponteiro com nome ptr2, e armazenando o endere co de ptr1 em ptr2. Quando voc e utiliza int ***ptr3 = &ptr2;, o ponteiro de ponteiro de ponteiro ptr3 vai apontar para a mesma vari avel que ptr2. Quando voc e utiliza ptr=& x; *ptr=55;, est a armazenando o valor 55 na vari avel apontada por ptr, no caso a vari avel x.

F.4

Convers ao de ponteiros

A Tabela F.1 mostra a convers ao de ponteiros. Na primeira linha, um Tipo e convertido em uma refer encia para o tipo (Tipo&). A compreens ao dessa Tabela e importante. Leia cada linha com cuidado. Tabela F.1: Convers ao de ponteiros. Para Descri ca o Tipo& de Tipo para refer encia Tipo de refer encia para Tipo Tipo * converte um vetor const para um ponteiro Tipo(*)(argumentos) de fun ca o para ponteiro de fun ca o const Tipo de Tipo para const Tipo volatile Tipo de Tipo para volatile Tipo const Tipo* de Tipo* para const Tipo* volatile Tipo* de Tipo* para volatile Tipo*

De Tipo Tipo& Tipo[] Tipo(argumentos) Tipo Tipo Tipo* Tipo*

F.5

Utilizando auto_ptr

Como descrito no Cap tulo 26 - Exce co es, se voc e tem um objeto din amico (por ex.: int* ptr = new int[30];) e ocorre uma exce ca o, voc e deve fornecer mecanismos para apagar os objetos din amicos. Esta pode ser uma situa ca o complicada. O auto_ptr e uma classe ponteiro que tem uma rela ca o ntima com a RTTI (tabela de informa co es em tempo de execu ca o), de forma que se ocorrer uma exce ca o ap os a aloca ca o de um objeto din amico, este se auto-deleta. Ou seja, ao sair de escopo um ponteiro auto_ptr, automaticamente chama o destrutor do objeto. A classe auto_ptr e denida no arquivo de cabe calho <memory>. Veja o exemplo da listagem F.2. Observe que o mais f acil de usar e o mais vers atil e o <vector> da STL. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

F.5. UTILIZANDO AUTO_PTR

689

Note na sa da a presen ca de valores negativos. Isto ocorre porque quando constru mos um vetor, o primeiro objeto e constru do usando construtor default, e os demais usando o construtor de c opia. Ou seja, para eliminar os valores negativos e necess ario implementar o construtor de c opia. Listing F.2: Comparando o uso de vetores est aticos de C, din amicos de C++, com auto_ptr de C++ e <vector> da stl.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 # include < iostream > # include < memory > # include < vector > using namespace std ; class CTipo { public : int t ; static int cont ; CTipo () { cont ++; cout << " Construtor do objeto , cont = " << cont << endl ; } ~ CTipo () { cout << " Destrutor do objeto , cont = " << cont << endl ; cont - -; } }; int CTipo :: cont = 0; int main () { cout << " ----- vetor est a tico de C : " << endl ; { CTipo v_static [2]; // Cria vetor e s t a t i c o com 2 e l e m e n t o s } // D e s t r o i vetor ao sair de escopo cout << " ----- vetor din^ a mico em C ++ sem STL : " << endl ; { CTipo * v_dinamico = new CTipo [3]; // ..... U t i l i z a o vetor ... delete [] v_dinamico ; // P r e c i s a do delete [] } // Usando auto_ptr , a u t o _ p t r n~ a o deve a p o n t a r para um vetor . cout << " ----- Objeto din^ a mico em C ++ com auto_ptr : " << endl ; { auto_ptr < CTipo > v_autoptr ( new CTipo ) ; v_autoptr - > t = 77; // ..... U T i l i z a o vetor ... cout << " t = " << v_autoptr - > t << endl ; } // a p a g a d o a u t o m a t i c a m e n t e cout << " ----- vetor din^ a mico em C ++ com STL : " << { vector < CTipo > v_stl (4 , CTipo () ) ; // for ( int i = 0; i < v_stl . size () ; i ++) { v_stl [ i ]. t = i ; cout << i << " = " << v_stl [ i ]. t << endl ; } } // D e s t r o i objeto endl ; din^ E amico

ao sair de escopo

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

690
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

F.5. UTILIZANDO AUTO_PTR

cout << " ----- vetor de ponteiros em C ++ com STL : " << endl ; { vector < CTipo * > v_stl (5) ; // Cria vetor de p o n t e i r o s for ( int i = 0; i < v_stl . size () ; i ++) { v_stl [ i ] = new CTipo () ; // Cria objeto v_stl [ i ] - > t = i ; // Usa objeto cout << " i = " << i << " t = " << v_stl [ i ] - > t << endl ; } for ( int i = 0; i < v_stl . size () ; i ++) delete v_stl [ i ]; // Deleta o b j e t o s } return 0; }

----- vetor est a tico de C : Construto r do objeto , cont = 1 Construto r do objeto , cont = 2 Destrutor do objeto , cont = 2 Destrutor do objeto , cont = 1 ----- vetor din^ a mico em C ++ sem STL : Construto r do objeto , cont = 1 Construto r do objeto , cont = 2 Construto r do objeto , cont = 3 Destrutor do objeto , cont = 3 Destrutor do objeto , cont = 2 Destrutor do objeto , cont = 1 ----- Objeto din^ a mico em C ++ com auto_ptr : Construto r do objeto , cont = 1 t = 77 Destrutor do objeto , cont = 1 ----- vetor din^ a mico em C ++ com STL : Construto r do objeto , cont = 1 Destrutor do objeto , cont = 1 0 = 0 1 = 1 2 = 2 3 = 3 Destrutor do objeto , cont = 0 Destrutor do objeto , cont = -1 Destrutor do objeto , cont = -2 Destrutor do objeto , cont = -3 ----- vetor de ponteiros em C ++ com STL : Construto r do objeto , cont = 1 i = 0 t = 0 Construto r do objeto , cont = 2 i = 1 t = 1 Construto r do objeto , cont = 3 i = 2 t = 2 Construto r do objeto , cont = 4 i = 3 t = 3 Construto r do objeto , cont = 5 i = 4 t = 4 Destrutor do objeto , cont = 5 Destrutor do objeto , cont = 4 Destrutor do objeto , cont = 3 Destrutor do objeto , cont = 2 Destrutor do objeto , cont = 1

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

F.6. PONTEIRO DE FUNC AO Problemas com auto_ptr

691

Observe que dois objetos auto_ptr n ao podem apontar para o mesmo objeto, por isso, o construtor de c opia e o operador de c opia de auto_ptr tem um comportamento estranho. Exemplo: // Cria objeto int apontado por aptr1 void auto_ptr<int> aptr1(new int()); // Abaixo faz aptr2 apontar para o objeto int e aptr1 para NULL!! auto_ptr<int> aptr2(aptr1); Desta forma, quando aptr2 sair de escopo o objeto criado e deletado, e quanto aptr1 sair de escopo nada acontece, evitando-se a destrui ca o repetida do objeto criado. Observe que esta solu ca o elimina a destrui ca o dupla do objeto criado, mas aptr1 e aptr2 n ao tem o comportamento esperado. Por este motivo aconselha-se a substitui ca o do uso de auto_ptr por shared_ptr da biblioteca boost++ (veja se ca o ??). Dica: substitua o uso de auto_ptr por shared_ptr da biblioteca boost++, veja se ca o ??.

F.6

Ponteiro de fun c ao

Voc e pode criar um ponteiro para uma fun ca o e usar o ponteiro para chamar a fun ca o. A listagem F.3 mostra um exemplo. Listing F.3: Usando ponteiro de fun ca o.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # include < iostream > using namespace std ; double cubo ( double x ) ; // D e c l a r a c~ a o da fun c~ ao int main () { // Define tipo ptr_funcao , um p o n t e i r o de fun c~ ao // que tem como p a r a m e t r o um double e como r e t o r n o um double . typedef double (* ptr_funcao ) ( double x ) ; // A r m a z e n a o e n d e r e c o da fun c~ a o no p o n t e i r o ptr_funcao ptr = cubo ; // U t i l i z a o p o n t e i r o de fun c~ a o para e x e c u t a r a fun c~ a o cubo . double x = 3; cout << " resultado = " << ptr ( x ) << endl ; return 0; } // D e f i n i c~ a o da fun c~ ao double cubo ( double x ) { return x * x * x ; } resultado = 27

O exemplo a seguir, adaptado de [Lischner, 2003], mostra outros poss veis usos de ponteiros para fun co es. Seja a fun ca o f(), que retorna um int* e recebe um int*. int* f(int*); Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

692

F.7. PONTEIROS PARA METODOS E ATRIBUTOS DA CLASSE

e a fun ca o G(), que retorna um int* e recebe um ponteiro para f(), ptr_f, e um int. int* G(int*(*ptr_f)(int*), int); Para criar um array com 10 ponteiros de fun ca o para fun ca o G() podemos usar: int* (*vptr_G[10])(int*(*)(int*), int); Note que a sintaxe do exemplo acima e confusa para usu arios iniciantes. Uma alternativa seria usar a sequ encia abaixo. Primeiro usa typedef para declarar um apelido para int* typedef int* ptrInt; A seguir, usa typedef para declarar um apelido para o ponteiro de fun ca o que retorna um ponteiro para int e recebe como par ametro um ponteiro para int. typedef ptrInt (*ptr_f)(ptrInt); Finamente, cria um array com 10 ponteiros de fun ca o para G(). ptrInt (*vptr_G[10]) (ptr_f,int);

F.7

Ponteiros para m etodos e atributos da classe

Este e um t tulo de n vel 3, isto signica que s o deve ser lido por usu ario experiente. Em determinados casos, muito especiais (raros), voc e pode querer ter um ponteiro para um atributo ou m etodo de uma classe. Esta se ca o mostra, por meio de um exemplo, como voc e deve proceder. Exemplo: class A { static int x; // Atributo void Mx(); // M etodo } // Criando ponteiro para m etodo fx() da classe A void(A::*ptrMx)() = & A::Mx(); // Ponteiro para atributo x da classe A int A::*ptr_x = & A::x; cout < < (*ptr_x) < < endl; Veja exemplo na listagem F.4. Observe a forma como o ponteiro e criado e usado. Note que o como o m etodo e virtual e o objeto usado e do tipo derivado, o m etodo executado e o m etodo da classe derivada. Listing F.4: Ponteiro para m etodos da classe.
1 2 3 4 5 6 7 # include < iostream > class Base { public : Base ( int i ) : x_ ( i ) {} virtual ~ Base () {}

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

F.8. PONTEIROS EM HIERARQUIAS


8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 virtual void Metodo () { std :: cout << " Base :: Metodo () \ n " ; } private : int x_ ; }; class Derivada : public Base { public : Derivada ( int i ) : Base ( i ) {} virtual void Metodo () { std :: cout << " Derivada :: Metodo () \ n " ; } }; int main () { Base * obj_b = new Derivada (42) ; void ( Base ::* ptrMetodo ) () = & Base :: Metodo ; ( obj_b - >* ptrMetodo ) () ; // E x e c u t a D e r i v a d a :: Metodo () } Derivada :: Metodo ()

693

F.8

Ponteiros em hierarquias

Quando usamos ponteiros em uma hierarquia, o endere co apontado pode variar, um oset (deslocamento) pode ocorrer em tempo de execu ca o, veja listagem F.5. Listing F.5: Ponteiro em hierarquias e oset.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # include < iostream > using namespace std ; class Base {}; class Derivada : public Base {}; int main () { Derivada d ; Base * pb = & d ; Derivada * pd = & d ; if ( pb == pd ) cout << " pb = " << pb << " pd = " << pd << " pb == pd " << endl ; else cout << " pb != pd " << endl ; return 0; } pb =0 x 7 f f f a e b 9 4 0 9 f pd =0 x 7 f f f a e b 9 4 0 9 f pb == pd

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

694

F.9. SENTENCAS PARA PONTEIROS

Na listagem F.6 apresenta-se a utiliza ca o do operador de endere co e sizeof. Observe na sa da que nome aponta para o vetor, mostrando a sa da "LDSC - Laborat orio Desenvolvimento Software Cient fico" . O conte udo de *nome e o caracter L e o endere co de nome um endere co de mem oria. Como o conte udo de *nome e o caracter n, quando convertemos para int, obtemos o valor 76. Observe ainda que sizeof(&nome) e 8, ou seja o ponteiro nome consome 8 bytes. J a o sizeof de nome e 57, indicando que consumimos 57 caracteres (56 caracteres mais o caracter terminador \0). Nota: observe que estes valores variam de plataforma para plataforma, estes resultados s ao obtidos em um GNU/Linux/Fedora 6 com uma SUN-Ultra40 (processadores AMD-Opteron de 64 bits). Listing F.6: Usando operador de endere co (&) e sizeof().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # include < iostream > using namespace std ; int main () { char nome [] = " LDSC - Laborat o r i o D e s e n v o l v i m e n t o Software Cient fico " ; cout << " nome = " << nome ; cout << " \ n * nome = " << * nome ; cout << " \ n & nome = " << & nome ; cout << " \ n & nome [0] = " << & nome [0]; cout << " \ n nome [0] = " << nome [0]; cout << " \ n ( int ) * nome = " << ( int ) * nome ; cout << " \ n sizeof (& nome ) = " << sizeof (& nome ) ; cout << " \ n sizeof ( nome ) = " << sizeof ( nome ) << endl ; return 0; } nome = LDSC - Laborat o ri o D e s e n v o l v i m e n t o Software Cient fico * nome = L & nome = 0 x 7 f f f 9 9 9 f b d f 0 & nome [0] = LDSC - Laborat o ri o D e s e n v o l v i m e n t o Software Cient fico nome [0] = L ( int ) * nome = 76 sizeof (& nome ) = 8 sizeof ( nome ) = 57

F.9

Senten cas para ponteiros

O ponteiro void* n ao permite o uso do operador de localiza ca o(*) e endere camento(&). O conte udo de void* s o pode ser acessado depois da deni ca o do tipo de objeto para o qual o ponteiro aponta. Um ponteiro void* pode ser igualado a outros ponteiros e vice-versa. Observe a utiliza ca o da mesma palavra-chave para diferentes prop ositos: para lista de argumentos, void = nenhum argumento; para retorno de fun ca o, void = nenhum retorno; para ponteiros, void = ponteiro para qualquer tipo de objeto. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

F.10. RESUMO DO CAP ITULO

695

Um ponteiro qualquer (desde que n ao seja const e volatile) pode ser convertido para void*. Um ponteiro pode ser convertido em qualquer tipo integral que seja sucientemente grande para cont e-lo. Um ponteiro de um objeto de tamanho n pode ser convertido para ponteiro do objeto de tamanho m, se n > m. Sempre inicializar os ponteiros ( ptr = NULL; ). Sempre destruir os objetos alocados com new com delete. Um ponteiro para uma classe-derivada pode ser convertido em ponteiro para a classe-base. 3 Um ponteiro para um objeto B (de uma classe-base) pode ser convertido em ponteiro para o objeto D (de uma classe-derivada) se a convers ao for direta e n ao amb gua, e se B n ao e classe-base virtual. 3 Uma refer encia a uma classe pode ser convertida em uma refer encia a uma classe-base acess vel.

F.10

Resumo do cap tulo

Neste ap endice aprendemos conceitos adicionais sobre ponteiros, como a soma e a subtra ca o de ponteiros. O uso do ponteiro void*, e de ponteiro para ponteiro. Como fazer para converter ponteiros. Exemplo de uso de auto_ptr. Como criar e usar um ponteiro de fun ca o, e ponteiros para m etodos e atributos da classe. Finalmente vimos o uso de ponteiros em hierarquias.

F.11

Exerc cios

1. Na se ca o F.1 apresentamos um exemplo. Transforme o mesmo em listagem, teste, e depois fa ca modica co es e aperfei coamentos. 2. Monte um exemplo com ponteiro void (se ca o F.2). 3. Monte um exemplo que utilize os conceitos apresentados na se ca o F.3. 4. Monte um exemplo com convers ao de ponteiros (se ca o F.4). 5. Modique a listagem F.3, acrescentando novas fun co es. 6. Modique a listagem F.6, acrescentando o uso de sizeof() para tipos padr oes da linguagem. (a) Ex: sizeof (int). 7. Na listagem F.2 acrescentar o construtor de c opia. 8. No exemplo de uso de <vector> din amico da STL, o construtor est a criando o objeto uma u nica vez (visto que s o e executado uma vez), mas est a deletando o objeto quatro vezes. Como proceder para corrigir este problema? Tente implementar na classe Tipo o construtor de c opia.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

696

F.11. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice G

Estruturas, Uni oes, e Enumera c oes


Veremos neste ap endice o uso de estruturas (se ca o G.1), uni oes (se ca o G.2), e enumera co es (se ca o G.3).

G.1

Estruturas - struct

Vimos no Cap tulo 11 - Classes, a utiliza ca o de classes para criar o conceito de objeto com seus atributos e m etodos. A linguagem C utiliza a palavra-chave struct para criar entidades que s ao utilizadas para armazenar somente vari aveis (sem fun co es). Assim, uma estrutura permite reunir um conjunto de vari aveis, dentro de uma entidade u nica. Uma struct e um conjunto de vari aveis ou objetos reunidos. Os objetos que comp oem a struct podem ser de diferentes tipos. C++ estendeu as structs de C e estas podem ser utilizadas para incluir fun co es. A dica e utilizar a palavra chave struct apenas para reunir atributos (de acordo com sua deni ca o inicial) e deixar para as classes a reuni ao de atributos e m etodos.

G.1.1

Prot otipo para declarar e denir estruturas

O prot otipo para deni ca o de uma estrutura inicia-se com a palavra-chave struct e, a seguir, o nome da estrutura e o bloco com a deni ca o dos atributos que fazem parte da estrutura. N ao se esque ca do ponto e v rgula ap os o nal do bloco. Prot otipo: struct SNomeEstrutura { avel1; Tipo 1 vari avel2; Tipo 2 vari ... aveln; Tipo n vari }; 697

698

G.1. ESTRUTURAS - STRUCT

Depois de denida uma estrutura, o seu nome passa a ser um tipo do usu ario, ou seja, a estrutura pode ser utilizada da mesma forma que qualquer outro tipo de C++. Veja a seguir como criar e utilizar uma struct de C. Criando um objeto de uma estrutura Pode-se criar um objeto de uma estrutura do mesmo modo que se cria um objeto qualquer de C. Veja a seguir o prot otipo e um exemplo. Prot otipo: SNomeEstrutura nomeObjeto; // Cria um objeto SNomeEstrutura v[n]; // Pode-se criar um vetor de estruturas. Exemplo: SPonto { int x,y; } int main() { SPonto p1 = {}; // x = y = 0 SPonto p2 = {3, 2}; // x = 3; y = 2; } Acessando atributos de uma estrutura Para acessar um atributo de uma estrutura, utiliza-se o operador ponto (.) se esta for est atica, e o operador seta (->) se esta for din amica. Prot otipo: SNomeEstrutura nomeObjeto; nomeObjeto.atributo; Prot otipo: SNomeEstrutura* ptr; ptr = new SNomeEstrutura; ptr ->atributo; delete ptr; Reveja agora o exemplo da listagem 9.4.

G.1.2

Estruturas e fun c oes

Pode-se passar uma estrutura por c opia, por refer encia ou por ponteiro para uma fun ca o. Veja o exemplo. Exemplo: Tipo Fun c~ ao( SNomeEstrutura obj1); // Por c opia Tipo Fun c~ ao( SNomeEstrutura & obj2); // Por refer^ encia Tipo Fun c~ ao( SNomeEstrutura * obj2); // Por ponteiro Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

G.1. ESTRUTURAS - STRUCT

699

G.1.3

Estruturas aninhadas

Quando temos uma estrutura dentro de outra temos uma estrutura aninhada. Veja exemplo de uso de estruturas aninhadas na listagem G.1. Listing G.1: Usando estruturas aninhadas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # include < iostream > # include < string > using namespace std ; // Define uma e s t r u t u r a S P e s s o a struct SPessoa { public : string nome ; int idade ; // Define uma e s t r u t u r a a n i n h a d a // a e s t r u t u r a S F a m i l i a dentro de S P e s s o a struct SFamilia { string sobrenome ; int n u m e r o I r m a o s ; } SFamilia ; }; int main () { // Cria objeto do tipo Pessoa SPessoa Joao ; Joao . nome = " Jo~ ao " ; Joao . idade = 21; Joao . SFamilia . n u m e r o I r m a o s = 3; Joao . SFamilia . sobrenome = " da Silva " ; cout << Joao . nome << " " << Joao . SFamilia . sobrenome << " \ n " << Joao . idade << " anos " << endl << " tem " << Joao . SFamilia . n u m e r o I r m a o s << " irmaos " << endl ; return 0; } Jo~ a o da Silva 21 anos tem 3 irmaos

G.1.4

Senten cas para estruturas

Uni oes e estruturas dentro de classes s ao sempre public. Inicialmente n ao era permitida a inclus ao de fun co es dentro da estrutura; hoje, uma struct aceita fun co es. Se quiser colocar fun co es dentro da estrutura, utilize classes. Uma struct X n ao pode conter uma inst ancia de si mesma (mas pode ter um ponteiro para X). Por default, os elementos de uma struct s ao p ublicos (public:); para classes, o default e privado (private:). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

700

G.2. UNIOES - UNION

O sizeof de uma estrutura pode ser maior que a soma do sizeof de seus elementos. Isto provoca pequenos desperd cios de mem oria, que podem ser reduzidos colocando-se no in cio da estrutura os objetos maiores e, a seguir, os menores (por ordem de tamanho). Veja se ca o 15.7. Ao contr ario de C++, em C uma estrutura n ao dene um tipo do usu ario. Para criarmos um objeto da estrutura usamos a palavra-chave typedef. Exemplo: struct SNome {int x}; SNome objeto_do_tipo_SNome; // C++ struct SNome objeto_do_tipo_SNome; // C

G.2

Uni oes - union

Uma uni ao (union) permite a um conjunto de objetos ocupar o mesmo local na mem oria. Observe que somente um objeto pode ser utilizado por vez. Uma uni ao pode ser considerada uma estrutura onde todos os objetos t em deslocamento zero e cujo tamanho e suciente para conter o seu maior membro. Ou seja, o espa co ocupado por uma union e correspondente ao do maior objeto denido. Depois de denida uma union, o seu nome passa a ser um tipo do usu ario. Como uma union pode armazenar objetos de diferentes tipos, ela n ao pode armazenar uma classe com construtor, com destruidor ou operador de c opia. O motivo e simples: se uma union tiver um int e um CPonto (listagem 13.5), quando a union sair de escopo, dever a destruir o objeto int ou o objeto CPonto?. Veja se co es 11.5.5 e 11.5.6. Uni oes n ao suportam heran ca, mas podem ter construtores. Segundo [Lischner, 2003], uma uni ao e semelhante a uma estrutura, mas com as seguintes restri co es. N ao deve ter uma classe-base, e n ao pode ser uma classe-base. N ao deve ter m etodos virtuais nem membros est aticos. Membros de dados n ao podem ser refer encias. Todos os seus membros de dados devem ser triviais (veja se c ao 11.5.6). As classes triviais descritas na se ca o 11.5.6, s ao importantes porque uni oes s o podem ter membros triviais.

G.2.1

Prot otipo para declarar e denir uni oes

Veja a seguir o prot otipo de uma union. Prot otipo: union UNomeUniao { Tipo1 v1; Tipo2 v2; Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

G.3. ENUMERAC OES - ENUM }; // Para criar um objeto da uni ao fa ca: UNomeUniao obj; // Para armazenar valores na uni ao: Tipo1 x; obj.v1 = x; // Para acessar os atributos da uni ao fa ca: Tipo1 y = obj.v1;

701

Veja a seguir exemplo de uso de uma union. Observe que a union armazena dois objetos, um int e um double. Logo, a union ter a o tamanho de um double. Exemplo: union UData { int x; double y; } UData obj1; obj1.x = 5; UData obj2; obj2.y = 5.0 + obj1.x ; Observe que podemos colocar dois objetos denidos pelo usu ario dentro de uma union, mas s o podemos utilizar um de cada vez. Em alguns casos, um objeto pode ter o mesmo objetivo geral, mas seria interessante poder ter dois nomes. No exemplo a seguir, dois objetos do tipo double s ao declarados dentro da importante union. Assim, podemos utilizar dois nomes para o mesmo endere co de mem oria. E lembrar que o mesmo tamb em pode ser feito com refer encias. Exemplo: union UPropriedade { double condut^ ancia; double raioHidraulico; }; Voc e pode criar uni oes sem um nome, pois deste modo as vari aveis denidas dentro da union podem ser acessadas diretamente, sem a utiliza ca o do ponto (.). A esta uni ao damos o nome de uni ao an onima. Obviamente, como os nomes denidos dentro dessa uni ao podem ser utilizados diretamente no escopo em que foram declarados, vari aveis com o mesmo nome causar ao ambig uidade.

G.3

Enumera c oes - enum

Uma enumera ca o e uma seq u encia de valores que tem como objetivo enumerar algum processo. Uma enumera ca o e um tipo discreto, denido pelo usu ario e um tipo do usu ario. Os valores podem ser denidos pelo programador (como em seg=2) ou serem denidos automaticamente pelo sistema.

G.3.1

Prot otipo para declarar e denir enumera c oes

No prot otipo a seguir v1 , v2 , v3 ,..., vn , s ao os valores, ENome e o nome da enumera ca o. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

702 Prot otipo: enum ENome { v1, v2, v3,...,vn }; Veja no exemplo a seguir como declarar uma enumera ca o.

G.3. ENUMERAC OES - ENUM

Exemplo: enum EDia { dom, seg, ter, qua, qui, sex, sab }; Onde EDia e o nome da enumera ca o e dom = 1, seg = 2, ter = 3, qua = 4, qui = 5, sex = 6, sab = 7, os valores da enumera ca o. Observe que os valores de cada elemento da enumera ca o s ao incrementados de 1. Veja no exemplo a seguir outros exemplos de enumera co es. Exemplo: enum ECor {r = 1 , g = 2 , b = 3 }; Exemplo: enum EResposta {nao = 0, sim = 1 , sei = 3 , nunca = 4};

talves = 2 , nao-

Veja no exemplo da listagem G.2 a cria ca o e uso de um objeto do tipo EDia com nome d. O programa pergunta que dia e hoje (n umero do m es e dia da semana). A seguir cria um objeto do tipo da enumera ca o e usa o mesmo para imprimir um calend ario para os pr oximos 30 dias. Listing G.2: Usando enumera co es: Um calend ario.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # include < iostream > # include < string > # include < iomanip > using namespace std ; // Cria uma e n u m e r a c~ a o com o nome EDia enum EDia { dom =1 , seg , ter , qua , qui , sex , sab }; // Abaixo s o b r e c a r r e g a o o p e r a d o r ++ EDia & operator ++( EDia & d , int ) { if ( d == sab ) { d = dom ; return d ; } else { int x = static_cast < int >( d ); x ++; d = static_cast < EDia >( x ); return d ; } } int main () { cout << " Que dia do m^ es e hoje ( n u mero ): " ; int x ; cin >> x ; cin . get (); cout << " Que dia da semana e hoje ( dom =1 , seg =2 , ter =3 ,.. , sab =7): " ; int y ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

G.3. ENUMERAC OES - ENUM


35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 cin >> y ; cin . get (); EDia d ( static_cast < EDia >( y ) ); cout << " Calend a rio para os pr o ximos 31 dias :\ n " << " Dom Seg Ter Qua Qui Sex Sab " << endl ; for ( int i = 1 ; i < y ; i ++ ) cout << setw (5) << " " ; for ( int i = x , j = x ; i < ( x + 31); i ++ , j ++) { cout << setw (5) << j ; d ++; if ( d == dom ) cout << endl ; // Muda linha if ( j > 30) // Impede mais de 31 dias j = 0; } cout << " \ a \ a " << endl ; return 0; } Que dia do m^ es e hoje ( n u mero ) :19 Que dia da semana e hoje ( dom =1 , seg =2 , ter =3 ,.. , sab =7) :3 Calend a rio para os pr o ximos 31 dias : Dom Seg Ter Qua Qui Sex Sab 19 20 21 22 23 24 25 26 27 28 29 30 31 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

703

Voc e pode criar uma enumera ca o sem um nome, neste caso os atributos internos podem ser acessados diretamente. Veja listagem G.3. Listing G.3: Usando enumera ca o anonima.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 # include < iostream > using namespace std ; // C r i a n d o uma e n u m e r a c~ ao an^ onima enum { jan = 1 , fev , mar , abr , mai , jun , jul , ago , set , out , nov , dez }; int main () { for ( int i = 1; i <= 12; i ++) { cout << " \ nmes = " << i << " = " ; switch ( i ) { case jan : case fev : case mar : case abr : case mai : case jun : case jul : case ago : case set : case out : case nov : case dez :

cout cout cout cout cout cout cout cout cout cout cout cout

<< << << << << << << << << << << <<

" " " " " " " " " " " "

janeiro " ; fevereiro " ; mar co "; abril " ; maio " ; junho " ; julho " ; agosto " ; setembro " ; outubro " ; novembro " ; dezembo " ;

break ; break ; break ; break ; break ; break ; break ; break ; break ; break ; break ; break ;

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

704
27 28 29 30 31 }; } cout << endl ; return 0; } mes mes mes mes mes mes mes mes mes mes mes mes = = = = = = = = = = = = janeiro fevereiro mar co abril maio junho julho agosto setembro outubro novembro dezembo

G.3. ENUMERAC OES - ENUM

G.3.2

Senten cas para enumera c oes

Por default uma enumera ca o inicia-se com 0. Em opera co es aritm eticas, os elementos de uma enumera ca o s ao convertidos automaticamente para int. Mas um inteiro n ao e automaticamente convertido para enumera ca o, neste caso precisamos usar um static_cast<> (veja se ca o 25.6). Os elementos de uma enumera ca o (ex.: {dom = 1, seg, ter, qua, qui, sex, sab}) s ao constantes e n ao podem ser alterados. Uma enumera ca o e um tipo u nico, um tipo do usu ario, e pode ser utilizada para criar objetos do tipo da enumera ca o, o que inclui atributos est aticos. Veja o exemplo. Exemplo: class T { public: enum EColor { black = 0, white = 1 }; static EColor sc; }; T::Ecolor T::sc = white; int main() { T::EColor c; ... return 0; } Uma enumera ca o permite sobrecarga de operador. Voc e pode usar enumera co es para armazenar n umeros inteiros, mas lembre-se, voc e n ao pode obter o endere co de uma enumera ca o. Uma enumera ca o declarada dentro de uma classe, coloca os membros da enumera ca o no escopo da classe. Veja exemplo a seguir. Note que podemos declarar a enumera ca o dentro da classe Base, podemos declarar e denir o valor de um objeto ECor est atico dentro da classe Botao, ou somente declarar dentro de Dialogo e denir posteriormente. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

G.4. RESUMO DO CAP ITULO Exemplo: class Base { public: enum ECor {preto, branco, vermelho, verde, azul}; }; class Botao : public Base { const ECor cor = verde; }; class Dialogo : public Base { static const ECor cor ; }; Base::ECor Dialogo::cor = Base::azul;

705

G.4

Resumo do cap tulo

Neste ap endice aprendemos em mais detalhes como usar as estruturas de C. Aprendemos que uma struct e um conjunto de vari aveis ou objetos reunidos. Falamos que embora C++ atual permita que uma estrutura tenha m etodos, devemos incluir m etodos apenas nas classes. Ou seja, as estruturas devem ter apenas atributos (dados/vari aveis). Vimos que as uni oes podem ser utilizadas da mesma forma que as estruturas, mas que somente uma vari avel deve ser utilizada por vez. Aprendemos que o espa co de mem oria ocupado pela estrutura e o do seu maior objeto. Finalmente, aprendemos que uma enumera ca o e uma seq u encia de valores que tem como objetivo enumerar algum processo.

G.5

Exerc cios

1. O exemplo da listagem G.2 tem problemas. O aluno deve tentar corrigir os problemas. Por exemplo, acrescentar verica ca o do nal do mes 30 ou 31 dias? Melhorar a l ogica do algoritmo. 2. Para os exerc cios que zemos anteriormente, classes CPonto, CCirculo, CElipse, CAluno, CFuncion ario, etc, verique se o sizeof() da classe e igual a soma do sizeof() dos seus atributos.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

706

G.5. EXERC ICIOS

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice H

Vetores e Matrizes - Arrays


Veremos neste ap endice o uso de vetores e matrizes - Arrays. Iniciamos apresentando uma introdu ca o aos vetores e matrizes de C (se ca o H.1), a seguir veremos Como criar e usar vetores unidimensionais (se ca o H.2), Como criar e usar matrizes bidimensionais (se ca o H.3). Exemplo de uso de vetores e matrizes (arrays) (se ca o H.4).

H.1

Introdu c ao aos vetores e matrizes de C

Um vetor ou array no estilo de C e um bloco de mem oria alocado para armazenamento de objetos cont guos e do mesmo Tipo. O tamanho (ou size) de um array deve ser conhecido em tempo de compila ca o. Veja a seguir o prot otipo para criar arrays no estilo de C. Prot otipo: // Unidimensional Tipo nome [ dimens ao ] ; // Bidimensional Tipo nome [ dimens ao1 ] [ dimens ao2 ] ; // Tridimensional Tipo nome [ dimens ao1 ] [ dimens ao2 ] [ dimens ao3 ] ; // Ndimensional Tipo nome [ dimens ao1 ] [ dimens ao2 ] [ dimens ao3 ] ... [dimens aoN];

H.2

Como criar e usar vetores unidimensionais

No exemplo a seguir criamos um vetor unidimensional com 10 elementos. Observe que os valores do vetor s ao indenidos. Exemplo: int v0[10] ; Se o array for est atico, todos os valores s ao inicializados com 0. No exemplo a seguir criamos um vetor unidimensional est atico com 5 elementos iguais a 0. 707

708 Exemplo: static int v1[5] ;

H.3. COMO CRIAR E USAR MATRIZES BIDIMENSIONAIS

No exemplo abaixo, criamos um vetor unidimensional v2 com 4 elementos. A seguir inicializamos seus valores um a um. Exemplo: int v2[4]; v2[0] = 11, v2[1] = 22, v2[2] = 0, v2[3] = 0.0; No exemplo abaixo criamos os vetores v3 e v4. Os mesmos s ao inicializados na cria ca o usando {}. Exemplo: int v3[5] int v4[4] = { 11, 22, 33, 44, 55 }; = { 11, 22 };

A dimens ao do array pode ser omitida se o compilador puder calcular a dimens ao. No exemplo a seguir o vetor v5 vai ter 3 elementos, isto e, v5[0] = 0, v5[1] = 11, v5[2] = 22. Exemplo: int v5[] = { 0, 11, 22 }; Podemos inicilizar todos os elementos com zero. Exemplo: int v6[5] = { };

H.3

Como criar e usar matrizes bidimensionais

Um array ndimensional tamb em pode ser criado, no exemplo a seguir criamos um array bidimensional. Observe a forma como podemos criar a matriz identidade. Exemplo: int matriz[4][3] = { {0,1,2} {3,4,5} {6,7,8} {9,10,11} }; int imagem[4][3] = { { 0, 1, 2 } { 3, 4, 5 } { 6, 7, 8 } { 9,10,11 } }; int matrizIdentidade3x3[3][3] = { {1} {0,1} {0,0,1} };

H.4

Exemplo de uso de vetores e matrizes

O programa da listagem H.1 realiza a binariza ca o de imagens, isto e, a convers ao de imagens em tons de cinza em imagens bin arias. O mesmo usa arrays (vetores e matrizes) com aloca ca o din amica e enumera co es. A sa da do programa e ilustrada nas imagens da Figura H.1. Em (a) a imagem de origem em tons de cinza, em (c) o gr aco do histograma de n veis de cinza e em (b) a imagem binarizada. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

H.4. EXEMPLO DE USO DE VETORES E MATRIZES

709

Como pr e-requisitos o programa precisa do arquivo "pstream.h" dispon vel no endere co http://pstreams.sourceforge.net/ e anexado nas listagens do livro. O mesmo e utilizado em nosso programa para obter acesso direto ao programa gnuplot utilizando streans. Um objeto opstream esta no namespace redi. Um objeto redi::opstream e usado para enviar sequ encias de comandos para programas externos. O programa usa ainda o programa externo display para visualizar as imagens. Os programas gnuplot e display est ao dispon veis na maioria das distribui co es GNU/Linux. Como o programa trabalha com imagens, selecionamos os formatos .pgm (para imagens em tons de cinza) e .pbm (para imagens em preto e branco). Estes formatos trabalham com dados em ASCII. Veja a seguir como s ao os formato .pgm e .pbm.
// Formato dos arquivos PBM ( Nome . pbm ) P1 ny nx dados // Formato dos arquivos PGM ( Nome . pgm ) P2 ny nx nCores dados

Um arquivo .pgm pode ser gerado usando o programa import ou o programa convert (ambos programas de terminal). O programa import e usado para capturar uma tela (exemplo: abra um terminal e digite: import nomeImagem.pgm , a seguir selecione a regi ao da imagem a ser capturada), o programa convert e usado para converter arquivos de imagens (exemplo: convert nomeImagem.jpg nomeImagem.pgm ). Inclui nas listagens do livro a imagem imagemExterna.pgm. Os arquivos de imagens (incluindo o formato .pgm e .pbm) podem ser visualizados com o programa display ou outro visualizador qualquer. Denidos os pr e-requisitos e o Tipo do arquivo de imagem, vamos a descri ca o do programa. O programa inicia solicitando o nome da imagem a ser aberta, no formato pgm, um formato ASCII f acil de manipular. L e os dados de cabe calho do arquivo de disco, como formato e dimens oes da imagem. A seguir aloca dinamicamente uma imagem 2D e seta seus valores com os dados do arquivo de disco. Para mostrar a imagem usa-se o programa display, acessado diretamente utilizando-se a fun ca o system("nomeDoComando"); Um vetor histograma e criado e zerado. O histograma e calculado em um for duplo, que varre toda imagem e para cada p xel da imagem acumula seu valor no histograma. O gr aco do histograma e mostrado usando-se o programa externo gnuplot. A seguir o programa solicita ao usu ario o valor de corte (n vel de cinza) e realiza a binariza ca o. A imagem binarizada e salva em disco. A fun ca o Write() e usada para salvar a imagem em disco. A mesma recebe o nome da imagem, um ponteiro para imagem, suas dimens oes, al em do formato da imagem. O formato pode ser PBM ou PGM, conforme denido na enumera ca o. A fun ca o AlocaMatriz2D() e usada para alocar dinamicamente uma matriz com duas dimens oes. DesalocaMatriz2D() e usada para desalocar a matriz. Listing H.1: Usando arrays: Um programa de binariza ca o.
1 2 3 4 5 6 # include < string > # include < fstream > # include < iostream > # include < cstdlib > # include " pstream . h " using namespace std ;

// D i s p o n v e l em http :// p s t r e a m s . s o u r c e f o r g e . net /

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

710
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

H.4. EXEMPLO DE USO DE VETORES E MATRIZES

// Cria e n u m e r a c~ ao enum { PBM , // = 1 PGM // = 2 }; // Salva imagem em disco bool Write ( string nomeImagem , int ** imagem , int nx , int ny , int formato = PGM ); // Aloca d i n a m i c a m e n t e m a t r i z 2 D int ** A l o c a M a t r i z 2 D ( int nx , int ny ); // D e s a l o c a d i n a m i c a m e n t e matriz 2 D bool D e s a l o c a M a t r i z 2 D ( int **& dat , int nx , int ny ); int main ( int argc , char * argv []) { int nx = 680; int ny = 480; int nCores = 256; int ** imagem = NULL ; string formato ; string nomeImagem ; cout << " Entre com o nome do arquivo de disco com a imagem ( formato pbm ou pgm ): " ; getline ( cin , nomeImagem ); // L^ e dados do a r q u i v o de disco ( formato , nx , ny , nCores ) // c_str () c o n v e r t e string de C ++ para C ifstream fin ( nomeImagem . c_str () ); if ( fin . fail ()) { cerr << " Falha abertura arquivo : " ; exit (0); } fin >> formato ; // P1 ou P2 fin >> nx ; fin >> ny ; if ( formato == " P2 " ) // PGM fin >> nCores ; imagem = A l o c a M a t r i z 2 D ( nx , ny ); // Aloca a matriz imagem // L^ e os dados da imagem do a r q u i v o de disco for ( int i = 0 ; i < nx ; i ++ ) for ( int j = 0 ; j < ny ; j ++ ) fin >> imagem [ i ][ j ]; // E x e c u t a c o m a n d o que mostra a imagem usando o p r o g r a m a d i s p l a y string comando = " display " + nomeImagem + " & " ; system ( comando . c_str ()); // e x e c u t a c o m a n d o do shell // Cria h i s t o g r a m a int * vhistogra ma = NULL ; vhistogra m a = new int [ nCores ]; if ( vhistogra ma == NULL ) { cerr << " Falha aloca ca ~ o histograma : " ; exit (0); } // Zera o h i s t o g r a m a for ( int i = 0; i < nCores ; i ++ )

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

H.4. EXEMPLO DE USO DE VETORES E MATRIZES


69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 vhistogra m a [ i ] = 0; // Varre a imagem e c a l c u l a h i s t o g r a m a for ( int i = 0 ; i < nx ; i ++ ) for ( int j = 0; j < ny ; j ++ ) vhistogram a [ imagem [ i ][ j ] ]++; // Salva o h i s t o g r a m a em disco ofstream a r q u i v o H i s t o g r a m a ( " histograma . dat " ); for ( int i = 0 ; i < nCores ; i ++ ) { a r q u i v o H i s t o g r a m a << vhistogram a [ i ] << endl ; } a r q u i v o H i s t o g r a m a . close (); // Cria objeto do tipo opstream , que esta no n a m e s p a c e redi . // o objeto com o nome gnuplot , vai e x e c u t a r o p r o g r a m a " g n u p l o t " redi :: opstream gnuplot ( " gnuplot " ); // Envia s e q u ^ e n c i a de c o m a n d o s d i r e t a m e n t e para o g n u p l o t // usando o objeto g n u p l o t gnuplot << " plot histogram a . dat title Histograma de n veis de cinza << " with linespoint " << endl ; // S o l i c i t a o valor de corte int valorCorte ; cout << " Entre com o valor de corte : " << endl ; cin >> valorCorte ; cin . get (); // B i n a r i z a imagem for ( int i = 0 ; i < nx ; i ++) for ( int j = 0 ; j < ny ; j ++) if ( imagem [ i ][ j ] < valorCorte ) imagem [ i ][ j ] = 1; else imagem [ i ][ j ] = 0;

711

"

// Salva imagem b i n a r i z a d a Write ( string ( " i m a g e m E x t e r n a B i n a r i z a d a " ) , imagem , system ( " display i m a g e m E x t e r n a B i n a r i z a d a . pbm & " ); return 0; }

nx ,

ny , PBM );

// Salva imagem em disco bool Write ( string nomeImagem , int ** imagem , int nx , int ny , int formato ) { ofstream fout ; switch ( formato ) { case PGM : // Salva imagem no f o r m a t o pgm fout . open ( ( nomeImagem + " . pgm " ). c_str () ); if ( fout . fail ()) return 0; fout << " P2 " << endl ; fout << nx << " " << ny << " " << sizeof ( int ) << endl ; break ; case PBM : // Salva imagem no f o r m a t o pbm fout . open ( ( nomeImagem + " . pbm " ). c_str () );

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

712
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

H.4. EXEMPLO DE USO DE VETORES E MATRIZES


if ( fout . fail ()) return 0; fout << " P1 " << endl ; fout << nx << " " << ny << endl ; break ; }

// Salva dados de cor em disco for ( int i = 0 ; i < nx ; i ++) { for ( int j = 0; j < ny ; j ++ ) fout << imagem [ i ][ j ] << ; fout << endl ; } fout . close (); return 1; } // Aloca d i n a m i c a m e n t e m a t r i z 2 D int ** A l o c a M a t r i z 2 D ( int nx , int ny ) { int i ; // int ** dat = NULL ; // Cria p o n t e i r o nulo dat = new int *[ nx ]; // Passo 1: aloca eixo x if ( dat ) // se alocou dat c o r r e t a m e n t e { for ( i = 0; i < nx ; i ++) // zera todos os p o n t e i r o s dat [ i ] dat [ i ] = NULL ; // porque se a a l o c a c a o der errado for ( i = 0; i < nx ; i ++) // vai chamar d e s a l o c a { dat [ i ] = new int [ ny ]; // Passo 2: aloca linhas y if ( dat [ i ] == NULL ) // Se a linha nao foi a l o c a d a { // chama D e s a l o c a Para evitar D e s a l o c a M a t r i z 2 D ( dat , nx , ny ); // v a z a m e n t o de m e m o r i a return 0; } } // O que nao foi a l o c a d o esta com NULL e return dat ; // pode ser d e l e t a d o } } // D e s a l o c a d i n a m i c a m e n t e matriz 2 D bool D e s a l o c a M a t r i z 2 D ( int **& dat , int nx , int ny ) { if ( dat != NULL ) { for ( int i = 0; i < nx ; i ++) if ( dat [ i ]) delete [] dat [ i ]; // Passo 1: apaga linhas y delete [] dat ; dat = NULL ; return 1; } return 0; } // Passo 2: apaga eixo x

Veja na Figura H.1 as sa das geradas pelo programa de binariza ca o da listagem H.1. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

H.5. RESUMO DO CAP ITULO

713

H.5

Resumo do cap tulo

Neste cap tulo aprendemos a criar e usar vetores e matrizes - arrays - no estilo de C. Embora C++ apresente o container <vector> (apresentado no Cap tulo 32 - Os Containers Sequ enciais <vector>, <list>, <deque>), e as diversas fun co es gen ericas (vistas no Cap tulo 35 - Programa ca o Gen erica) o uso de vetores e matrizes no estilo de C se justica em fun ca o da necessidade de maior performance. Adicionalmente, aprender a usar vetores e matrizes no estilo de C se justica em fun ca o da necessidade de se adaptar c odigos legados - c odigos antigos - utilizados em diversos programas de engenharia. O Cap tulo ?? - A biblioteca Blitz++, apresenta a biblioteca de matrizes Blitz++, a mesma alia caracter sticas de boa performance e facilidade de uso.

H.6

Exerc cios

1. Mude o programa da listagem H.1 de forma que o nome da imagem possa ser passado atrav es da linha de comando (veja se ca o E.1).

2. Substitua o uso de display por elementos da biblioteca Magick++ (veja se ca o ??).

3. Crie uma m ascara (uma matriz 3x3), dena seus valores como sendo 1. Crie uma imagem do tamanho da imagem original, zerada. A seguir percorra toda imagem e aplique um ltro de passa-baixa sobre a imagem. Isto e, algo parecido com:

Exemplo: int masc[3][3]={{1,1,1}{1,1,1}{1,1,1}}; for i // Varre a imagem for j. for k // Varre a m ascara for l imagemFiltrada[i][j] += imagem[i][j]*masc[k][l];

Nota: o c odigo da listagem acima esta incorreto, e parte do trabalho do aluno montar o algoritmo correto para aplicar o ltro. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

714

H.6. EXERC ICIOS

Figura H.1: As sa das do programa de binariza ca o.

(a) Imagem em tons de cinza

(b) Imagem binarizada

(c) O histograma da imagem em tons de cinza

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice I

Gloss ario
Abstra c ao: processo de criar uma superclasse pela extra ca o de qualidades comuns ou caracter sticas gerais de uma ou mais classes ou objetos espec cos. A c ao: usada em modelagem din amica, se refere a opera ca o instant anea associada a um evento. Agente: veja objeto ativo. Agrega c ao: forma especial de associa ca o entre o todo e suas partes, no qual o todo e composto de partes. Agregado xo: quando o n umero de partes e denido. Agregado recursivo: quando o objeto pode conter a si pr oprio. Agregado vari avel: quando o n umero de partes e indenido. Algoritmo: conjunto de etapas ordenadas de forma espec ca, utilizadas para solucionar um problema, tal como uma f ormula matem atica ou uma s erie de instru co es de um programa. Ambiente de janelas: interface gr aca com janelas m ultiplas na tela de um computador. Ambiente windows: veja ambiente de janelas. Amigo: classes amigas permitem o compartilhamento de m etodos e atributos. An alise orientada a objeto: an alise dos requisitos de um sistema em termos de objetos reais. Realizada sem considerar os requisitos de implementa ca o. Ancestral imediato: aquele que e identicado na declara ca o do objeto. Arquitetura: estrutura geral de um sistema, incluindo a sua divis ao em subsistemas e suas aloca co es para tarefas e processadores. Assinatura: para um atributo, o tipo do atributo, para uma opera ca o (m etodo ou fun ca o), o nome da opera ca o, seus par ametros e o tipo de retorno. Associa c ao derivada: denida em termos de outras associa co es. Associa c ao qualicada: associa ca o que relaciona duas classes e um qualicador. Associa c ao tern aria: associa ca o entre tr es classes. 715

716 Associa c ao: relacionamento entre duas ou mais classes descrevendo um grupo de liga co es com estruturas e sem anticas comuns. Atividade (em modelagem din amica): opera ca o que leva tempo para terminar. Est a relacionada a estados e representa acontecimentos do mundo real. Atributo de classe: atributo que existe na classe e n ao nos objetos. Todos os objetos da classe t em acesso ao atributo de classe, mas este eu nico. Ator: objeto ativo que pode gerar eventos. Atributo: uma propriedade ou caracter stica de um objeto. Atributo de evento: dados transportados por um evento. Atributo de associa c ao: atributo que existe em fun ca o de uma associa ca o entre dois objetos. Atributo derivado: atributo que e calculado a partir de outros atributos. Banco de dados: uma cole ca o de dados armazenados e gerenciados eletronicamente. Biblioteca de classes: uma cole ca o de classes gen ericas que podem ser adaptadas para uma aplica ca o particular. Caixa-preta: met afora utilizada em engenharia para descrever um dispositivo em que os componentes internos s ao desconhecidos pelo usu ario. Os objetos s ao como caixas-pretas em que seus funcionamentos internos cam ocultos aos usu arios e programadores. Cancelar: denir um m etodo em uma classe-derivada que substitui o m etodo ancestral. Caracter stica: e uma palavra gen erica para atributos e m etodos. Cen ario (em modelagem din amica): seq u encia de eventos que ocorre durante uma determinada execu ca o do sistema. Classes: sin onimo de tipos de objeto (f abrica de objetos). Classe abstrata: classe que n ao pode gerar objetos. Classe concreta: classe que pode gerar objetos. Classe-base: classe que tem classes herdeiras (tem uma ou mais classes lhas). Classe-derivada: classe herdeira (tem um ou mais pais). Classe-lho: o mesmo que classe-derivada. Classe-pai: o mesmo que classe-base. CORBA: Common Object Request Broker Arquiteture. CREW: Concurrent Read, Exclusive Write. CRCW: Concurrent Read, Concurrent Write. C odigo aberto: express ao utilizada para indicar que voc e pode ver o c odigo-fonte do programa. Entretanto, nada pode ser dito a respeito das condi co es sob as quais o c odigofonte se encontra. Existem programas de c odigo aberto que n ao s ao livres, pois o usu ario, dependendo da licen ca, pode ser proibido de alterar e publicar o c odigo. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

717 C odigo reentrante: c odigo usado em bibliotecas compartilhadas. O mesmo c odigo pode ser usado por diferentes programas ao mesmo tempo (n ao usa internamente vari aveis est aticas). Coer encia: propriedade de uma entidade, como uma classe, uma opera ca o ou m odulo, tal que ela se organize em um plano consistente e todas as suas partes se ajustem no sentido de um objetivo comum. Cole c ao de lixo: rotina de gerenciamento de mem oria que pesquisa a mem oria por segmentos de programa, dados ou objetos que n ao se encontram mais ativos, e recupera o espa co n ao utilizado. Compilador: programa que traduz uma linguagem de programa ca o para a linguagem de m aquina. Concorr encia: a capacidade de programas orientados a objeto de se comunicarem em multitarefa. Concorrente: duas ou mais tarefas, atividades ou eventos cujas execu co es podem se sobrep or no tempo. Condi c ao: usada em modelagem din amica, se refere a fun ca o booleana de valores de objetos v alidos durante um intervalo de tempo. Construtor: m etodo especial que e utilizado para inicializar todos os atributos de um objeto. Consulta: e uma opera ca o (m etodo) que, quando executada n ao altera o objeto. Dados persistentes: dados que continuam existindo mesmo ap os encerrada a execu ca o de um programa. Debuger: programa que permite ao usu ario corrigir erros de software por interm edio do exame e altera ca o do conte udo da mem oria, e iniciar ou parar a execu ca o em um local predeterminado ou breakpoint. Serve para localizar e alterar erros de l ogica de um programa ou para corre co es em um programa. Depurador: veja Debuger. Delega c ao: mecanismo de implementa ca o no qual um objeto, em resposta a uma opera ca o nele pr oprio, repassa a opera ca o para outro objeto. Projeto orientado a objeto: tradu ca o da estrutura l ogica de um sistema em uma estrutura f sica composta de objetos de software. Destrutor: libera os objetos dinamicamente alocados e destr oi o objeto. Podem ser expl citos ou impl citos; se expl citos (declarados), podem liberar outros tipos de dados e realizar outras fun co es. Diagrama de seq u encia: diagrama que mostra o remetente e o receptor (eventos e mensagens). Diagrama de atividade: diagrama que mostra o movimento de dados e seu processamento manual ou por computador. Diagrama de objetos: representa ca o gr aca de objetos mostrando os relacionamentos, atributos e opera co es. Diagrama que mostra o relacionamento de objetos entre si. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

718 Dicion ario de dados: par agrafo que descreve uma classe, seus atributos, m etodos e associac o es. Discord ancia de nome: conito que pode ocorrer em hereditariedade m ultipla quando o mesmo m etodo ou atributo de inst ancia for herdado de m ultiplas classes. DCS: Decomposition, communication, and synchrinization. Encapsulamento: casamento do c odigo com os dados dentro de uma unidade de objeto. Isto representa a modularidade aplicada aos dados. O encapsulamento torna invis veis os dados para o usu ario, embora os m etodos permane cam vis veis. Escala: o relacionamento entre tr es elementos e chamado escala. Escalabilidade: possibilidade de alterar as congura co es do sistema de acordo com as necessidades. Especializa c ao: a cria ca o de classes-derivadas (subclasses) a partir de uma classe-base (ou superclasse) por meio do renamento da classe-base. EREW: Exclusive Read, Exclusive Write. ERCW: Exclusive Read, Concurrent Write. Estado: valores dos atributos e liga co es de um objeto em um determinado momento. Evento: usado em modelagem din amica, se refere a algo que acontece instantaneamente. Expansibilidade: expandir um programa sem ter em m aos o c odigo-fonte. Extens ao (em generaliza ca o): o acr escimo de novas caracter sticas por meio de uma subclasse. Extensibilidade: habilidade de um programa ou sistema em ser facilmente alterado para que possa tratar novas classes de entrada. Folha: mecanismo de subdivis ao de um modelo de objetos em uma s erie de p aginas. Framework: uma biblioteca de classe anadaespecialmente para uma determinada categoria de aplica ca o. M etodo virtual: m etodo especial chamado por interm edio de uma refer encia de classe b asica ou indicador, carregado dinamicamente em tempo de execu ca o. GNU: acr onimo para GNU n ao e Unix. GNU e o nome de um sistema operacional completo e compat vel com Unix escrito a partir de 1983, por Richard Stallman e in umeros hackers da comunidade de software livre espalhados pela Internet. O GNU e um sistema totalmente livre, ou seja, ele fornece as quatro liberdades b asicas do software livre: a liberdade de uso, modica ca o, c opia e publica ca o de vers oes modicadas. Atualmente o sistema GNU e largamente utilizado, especialmente na sua variante GNU/Linux. GNU/Linux: sistema operacional GNU totalmente livre que utiliza o Linux como kernel. GNU/Linux e a variante mais conhecida do sistema GNU. O sistema GNU original ` as vezes e referenciado como GNU/Hurd para maior clareza. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

719 GPL: licen ca de software livre mais utilizada no mundo. Caracteriza-se por ser uma licen ca com Copy-left, ou seja, qualquer trabalho derivado de qualquer parte de um software livre licenciado sob GPL obrigatoriamente deve permanecer livre. A GPL pode ser obtida em http://www.gnu.org/licenses/gpl.html. Gerenciamento de mem oria: a maneira pela qual o computador trata a sua mem oria. Inclui prote ca o de mem oria e quaisquer outras t ecnicas de mem oria virtual. Gr acos orientados a objeto: programas que t em a fun ca o de desenhar e que s ao apresentados ao usu ario sob a forma de objetos na tela. Heran ca: a propriedade de todos os tipos de objetos que permite a um tipo ser denido como herdando todas os atributos e m etodos contidos no pai. Handle: vari avel utilizada pelo sistema operacional para identicar um objeto. Heran ca m ultipla: permite a um objeto herdar m etodos e atributos de mais de um pai. Heran ca repetida: quando um objeto e descendente de outro por mais de um caminho. Hereditariedade: mecanismo usado para compartilhar m etodos e tipos de dados automaticamente entre classes, subclasses e objetos. N ao e encontrado em sistemas de procedures. Permite programar apenas as diferen cas de classes previamente denidas. Hierarquia: descri ca o de um sistema que conta com uma estrutura constru da em n veis diferentes. Os n veis mais altos controlam os mais baixos. Hierarquia de objetos (estrutura): diagrama que mostra o relacionamento dos objetos. Icone: representa ca o gr aca de um objeto. Identidade do objeto: algo sobre o objeto que permanece invari avel entre todas as possibilidades de modica ca o de seu estado. Pode ser usado para indicar um objeto. Informa c ao escondida/oculta: recurso de programa ca o pelo qual a informa ca o dentro de um m odulo permanece privada a ele. Estrat egia de design que visa a maximizar a modularidade ocultando o maior n umero poss vel de informa co es dentro dos componentes de um design. Inst ancia: objeto que faz parte de uma classe. Instancia c ao: processo de cria ca o de inst ancias a partir de classes. Invariante: declara ca o sobre alguma condi ca o ou relacionamento que deve ser sempre verdadeiro. Janela: area de visualiza ca o separada em uma tela de exibi ca o fornecida pelo software. Os ambientes gr acos dos sistemas operacionais podem mostrar janelas m ultiplas na tela, permitindo que o usu ario mantenha v arios programas aplicativos ativados e vis veis ao mesmo tempo. Os programas aplicativos individuais tamb em contam com janelas m ultiplas, oferecendo capacidade de visualiza ca o para mais de um documento, planilha ou arquivo de dados. Kernel : parte fundamental de um programa como um sistema operacional, residente todo o tempo em mem oria. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

720 Largura de banda: n umero de canos por onde os dados uem. Quanto maior a largura de banda, maior a velocidade com que os dados uem do processador para a mem oria e para os dispositivos (placa de rede, monitor). Lat encia: tempo perdido com a comunica ca o entre os diversos dispositivos. Linux: clone livre do kernel do Unix, escrito a partir do zero por Linus Torvalds, com a ajuda de um grupo de programadores espalhado pela Internet. Ele objetiva estar em conformidade com o POSIX e com a Single Unix Specication. Ap os mostrar-se mais est avel e simples que o HURD (kernel original do GNU), o Linux foi inclu do no sistema GNU tornando-o pronto para conquistar o mercado com a variante GNU/Linux. Liga c ao: processo de organizar um programa para solucionar todas as conex oes entre seus componentes. Estaticamente, as liga co es s ao denidas na compila ca o. Dinamicamente, a liga ca o ocorre quando o programa est a rodando. Liga c ao a posteriori (din amica): um m etodo que permite chamar outros m etodos cujo endere co n ao e conhecido em tempo de compila ca o/linkedi ca o. O endere co s o e conhecido durante a execu ca o. Liga c ao a priori/anterior: m etodo tradicional de compila ca o pelo qual os endere cos dos m etodos e fun co es s ao determinados na etapa de linkagem. Liga c ao est atica: veja liga ca o a priori. Linguagem concorrente: linguagem que permite a execu ca o simult anea de objetos m ultiplos, geralmente com arquitetura de hardware paralela. Linguagem n ao procedural: linguagem de programa ca o que gera a l ogica para o programa diretamente a partir da descri ca o do problema pelo usu ario, em vez de um conjunto de procedures baseadas em l ogica de programa ca o tradicional. Linguagem orientada a objeto: linguagem de computador que suporta objetos, classes, m etodos, mensagens e hereditariedade. As caracter sticas secund arias podem incluir hereditariedade m ultipla, liga ca o din amica e polimorsmo. Linguagem procedural: linguagem de programa ca o como COBOL, FORTRAN, BASIC, C e Pascal, baseada na utiliza ca o de ordem particular de a co es e que tem conhecimento das opera co es de processamento de dados e t ecnicas de programa ca o. Manuten c ao: capacidade de um programa ou sistema para transformar reparos de bugs e aumentar a funcionalidade a m de satisfazer ` as necessidades do usu ario. MIMD: Multiple Instruction Stream, Multiple Data Stream. Cada processador atua de forma independente. Implementado utilizando cluster. Mem oria compartilhada: em m aquinas com mais de um processador - SMP, a mem oria costuma ser compartilhada (os processadores podem acessar a mesma mem oria). Multitasking: o conceito de multitasking gerenciado pelo sistemas operacional (ex: GNU/Linux), possibilitando que m ultiplas tarefas sejam executadas simultaneamente atrav es da divis ao do tempo do(s) processador (es). Se voc e tem n tarefas em um sistema o ideal e ter n processadores no mesmo sistema ou utilizar um cluster que lhe ofere ca n processadores. O Sistema operacional controla a troca dos processos dando a cada um deles uma por ca o de tempo. Quando o tempo do processo encerra, o SO salva os dados do processo que esta sendo executado e passa a execu ca o para o pr oximo processo. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

721 Multi tasking operating system: sistema operacional que roda mais de uma tarefa de cada vez. Cada tarefa utiliza o processador por um determinado tempo. Multi tasking operating system em sistemas multiprocessados: o sistema operacional e multitarefa e o computador tem mais de um processador. Ex.: Sun-Solaris rodando em uma esta ca o de trabalho SUN-Enterprise E450. Multisession: um sistema operacional multisession admite que mais de um usu ario esteja logado, rodando mais de uma se ca o (ex: GNU/Linux). Multiprocessing: um sistema operacional que possibilita a execu ca o de mais de um processo por se ca o. Multithreading: um sistema operacional que possibilita que um processo tenha mais de uma thread. Mensagem: solicita ca o enviada a um objeto para alterar seu estado ou retornar um valor. A mesma mensagem pode ser enviada para objetos diferentes porque eles simplesmente informam a um objeto o que fazer. Os m etodos denidos dentro de um objeto receptor determinam como ser a executada a solicita ca o. Veja m etodo/polimorsmo. Metaclasse: classe que descreve outras classes. Metadados: s ao dados que descrevem outros dados. Por exemplo, uma deni ca o de uma classe. M etodo: um m etodo e uma fun ca o que e denida como pertencendo a um tipo de objeto. Implementa a resposta quando uma mensagem e enviada a um objeto. Os m etodos determinam como um objeto responder a a uma mensagem. Veja mensagens. M etodo de implementa c ao (estilo): m etodo que realiza o processamento de dados sem realizar qualquer tomada de decis oes. M etodo est atico: implementado usando a liga ca o a priori. M etodo pol tico: m etodo que realiza o processamento de tomadas de decis oes. N ao realiza processamento de dados. M etodo virtual: implementado usando a liga ca o a posteriori. Metodologia: em engenharia de software, e o processo de produ ca o organizada de um programa, utilizando t ecnicas e conven co es conhecidas. Movimento pelo software livre: movimento surgido na d ecada de 1970 em conseq u encia da crescente press ao recebida para a ado ca o de softwares propriet arios e assinaturas de tratados de n ao-divulga ca o. O movimento intensicou-se a partir da d ecada de 1980 com o projeto GNU que libertava os usu arios dos sistemas UNIX propriet arios. O GNU consolidou-se na d ecada de 1990 como um sistema completo e funcional, atingindo uma qualidade t ecnica compar avel aos melhores sistemas operacionais propriet arios. Modelo funcional: descri ca o dos aspectos de um sistema que transforma valores utilizando fun co es, mapeamentos, restri co es e depend encias funcionais. Modularidade: a constru ca o de um programa em m odulos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

722 Multiplicidade: n umero de inst ancias de uma classe que podem relacionar-se a uma u nica inst ancia de outra classe. MPP: massive parallel processing (um computador com v arios processadores). Objeto: elemento prim ario em um programa orientado a objeto. Objetos s ao entidades que encapsulam dentro de si pr oprios os dados que descrevem o objeto e as instru co es para operar esses dados. Objeto ativo: um objeto que monitora eventos ocorrendo em uma aplica ca o e assume a a ca o ` vezes chamado de agente. por si pr oprio. As Objeto passivo: objeto que atua somente por solicita ca o. Objeto polim orco: o descendente herda a forma do ancestral (m etodos), mas pode redenir os m etodos assumindo outras formas (polimorsmo). Open source initiative: grupo desmembrado do movimento pelo software livre em 1998, que rejeita a luta pela liberdade no uso do software. Seu objetivo e disseminar a id eia de que c odigo-fonte dispon vel e com modica ca o permitida gera melhores programas. Apesar de n ao endossar o esp rito de liberdade, esse grupo costuma recomendar o uso da licen ca GPL. Opera c ao abstrata: opera ca o declarada, mas n ao implementada. Opera c ao de classe: opera ca o que e realizada pela classe e n ao pelas inst ancias desta. S o pode manipular os atributos de classe. Opera c ao: fun ca o ou m etodo que pode ser aplicado por um objeto. Orientado por objeto: termo para pr atica de programa ca o ou compiladores que agrupam elementos individuais de programa ca o em hierarquias de classes, permitindo que objetos do programa compartilhem o acesso a dados e procedimentos sem redeni ca o. POSIX: Portable Operation System Interface - IEEE-STD 1003.1-2001. Pai-lho: maneira de expressar a rela ca o entre classes e subclasses. As classes-lho ou subclasses herdam os m etodos e atributos de inst ancia da classe-pai. Por meio da hereditariedade m ultipla, um lho pode ter diversos pais. Papel: uma extremidade de uma associa ca o. Paradigma: Extra do de http://pt.wikipedia.org/wiki/Paradigma. Paradigma e a repre um pressuposto los senta ca o do padr ao de modelos a serem seguidos. E oco matriz, ou seja, uma teoria, um conhecimento que origina o estudo de um campo cient co; uma realiza ca o cient ca com m etodos e valores que s ao concebidos como modelo; uma refer encia inicial como base de modelo para estudos e pesquisas. Na losoa grega, paradigma era considerado a u encia de um pensamento, pois atrav es de v arios pensamentos do mesmo assunto e que se concluia a id eia, seja ela intelectual ou material, depois dela realizada surgiam outras id eias at e chegar a uma conclus ao nal. Paradigmas h bridos: linguagens h bridas como o C++, que fazem uso de t ecnicas de programa ca o OOP e estruturada. Pilha: a rvore bin aria completa em que os nodos cont em chaves de pesquisa organizadas em ordem descendente. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

723 Polimorsmo: propriedade de compartilhar uma a ca o simples. Cada classe-derivada implementa os m etodos de forma apropriada as suas necessidades. Habilidade de a mesma mensagem ser interpretada de maneiras diferentes quando recebida por objetos diferentes. Por exemplo, a impress ao de uma mensagem, quando enviada a uma gura ou diagrama, aciona um m etodo ou implementa ca o diferente daquele que a mesma mensagem de impress ao envia a um documento. Pr e-processador: programa de software que executa procedimentos preliminares na entrada de dados antes da execu ca o do programa principal. Por exemplo, o c odigo-fonte C++ e comumente pr e-processado e traduzido para o c odigo-fonte C antes de ser compilado. Privado: os m etodos e atributos pertencentes a uma classe s ao privados por default. Os elementos privados s o podem ser acessados por m etodos que perten cam ` a classe, desde que esta n ao seja descendente (s o acessado pela classe). Processamento distribu do: sistema de computadores ligados por uma rede de comunica co es com cada sistema gerenciando sua pr opria carga local e a rede suportando o sistema como um todo. Processo: alguma coisa que transforma valores de dados. Programa: conjunto de instru co es que informam ao computador o que fazer. Um programa e escrito em uma linguagem de programa ca o e e convertido em linguagem de m aquina por meio de softwares chamados montadores e compiladores. Programa c ao estruturada: losoa de programa ca o voltada ao gerenciamento de complexidade por meio da formaliza ca o e padroniza ca o da metodologia de programa ca o. A programa ca o estruturada e caracterizada pela sua apresenta ca o top-down. Programa c ao orientada ao objeto: metodologia usada para a cria ca o de programas por interm edio da utiliza ca o de objetos auto-sucientes com dados e o comportamento encapsulados e que atuam por meio de solicita ca o e interagem com outros, enviando e devolvendo mensagens. Programa c ao top-down: metodologia que cria um programa modular de estrutura hier arquica. Primeiro, o desenhista projeta, codica e testa um m odulo que representa a estrutura do programa e depois continua da mesma maneira criando m odulos de n vel mais baixo, que representam suas subfun co es. Programa c ao visual: categoria gen erica de aplicativos que executam programa ca o gr aca e seus efeitos visuais ao usu ario. Por exemplo, em pacotes de desenho os objetos podem ser desenhados, aumentados e at e modicados por meio de manipula co es diretas da imagem na tela e n ao pela altera ca o de dados num ericos em uma tabela de dimens oes. Protegido: podem ser acessados pela classe e pelas classes derivadas. Protocolo: conjunto de mensagens as quais o objeto pode responder. P ublico: os m etodos declarados como public podem ser acessados pela classe, classe derivadas, e por aplica co es (dentro de main(), por exemplo). Qualicador: atributo de um objeto que faz a distin ca o entre o conjunto de objetos na extremidade muitos de uma associa ca o. Recurs ao: habilidade de uma sub-rotina ou m odulo de programa em chamar a si mesmo. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

724 Redeni c ao: propriedade das classes derivadas de modicar os m etodos da classe-pai. Assim, duas classes-irm as (lhas do mesmo pai) podem ter m etodos com o mesmo nome, mas com realiza co es diferentes. Restri c ao: usado em generaliza co es, se refere a limita ca o que uma subclasse coloca no valor de um atributo contido em uma superclasse. Robusto: um software robusto n ao e facilmente destru do por erros em seus pressupostos. Conta com verica co es internas que objetivam eliminar bugs. Simula c ao: representa ca o matem atica da intera ca o de objetos do mundo real. Software livre: software que garante ao usu ario plenas liberdades de uso, modica ca o, c opia e publica ca o de vers oes modicadas. A deni ca o de software livre pode ser encontrada em http://www.gnu.org/philosophy/free-sw.html. Sobrecarga de operador: deni ca o da forma como o operador atua sobre os atributos da classe. Subclasse: renamento de uma classe em uma outra mais especializada (classe-derivada ou lho). Superclasse: em uma hierarquia, uma classe mais gen erica que armazena atributos e m etodos que podem ser herdados por outras classes. Algumas vezes tratada como classe-base ou pai. SMP: single multiple processor (com mem oria compartilhada). SIMD: Single Instruction Stream, Multiple Data. Todos os processadores executam a mesma opera ca o ao mesmo tempo. Muito utilizado no processamento de vetores e matrizes, f acil de implementar. Implementado utilizando swar ou smp. SPMD: Single Program, Multiple Data. Todos os processadores rodam o mesmo programa. Implementado utilizando cluster. Single tasking operating system: sistema operacional que roda somente uma tarefa de cada vez. Ex.: DOS. Tabelas dos m etodos virtuais (VMT): tabela que aparece no segmento de dados de cada tipo de objeto virtual. A VMT cont em o tamanho do objeto (tamanho do registro) e os ponteiros para os m etodos. this: ponteiro para o objeto denido implicitamente. Usado para resolver conitos de nomes dentro de um m etodo da classe. Tipica c ao: propriedade de uma linguagem de distinguir com clareza os tipos denidos. A tipica ca o forte (C++) ajuda a desenvolver softwares mais robustos. Tipo ancestral: todo tipo herdado por qualquer outro tipo de objeto. Tipo de dados abstratos: conjunto de estruturas de dados (tipos de dados) denido em termos de recursos de estruturas e de opera co es executadas sobre elas. Na POO, os tipos de objetos s ao tipos de dados abstratos. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

725 Troca de mensagens: Sistema pelo qual o processamento e distribu do pelas v arias m aquinas do cluster. Os dados s ao enviados de uma m aquina para outra, processados e devolvidos. As bibliotecas para troca de mensagem mais utilizadas s ao o MPI e o PVM. Unix: sistema operacional multiusu ario e multitarefa que trata os dados que foram designados a ele at e aparecer um novo valor ou o programa terminar sua execu ca o. Vari avel de inst ancia: dado contido em um objeto que descreve propriedades do objeto que a possui. Vari avel global: vari avel acess vel a todos os m odulos de um programa. Vari avel: uma estrutura em mem oria que trata os dados que foram designados a ela at e aparecer um novo valor ou o programa terminar a sua execu ca o. Virtual: ambiente simulado ou conceitual. Realidade virtual, por exemplo, e uma realizada simulada. Windows: veja janela. WBS: Work Breakdown Structure.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

726

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice J

Links Para Sites em C++


Apresenta-se a seguir uma lista de links relacionados a programa ca o em C++, e aos diversos temas apresentados neste livro.

J.1

Bookmark

O bookmark que utilizo para acessar diversos sites de programa ca o, incluindo os links apresentados neste cap tulo est a disponibilizado em: http://www.lenep.uenf.br/~bueno/bookmarks-prog.html Uma c opia do mesmo e distribu da juntamente com as listagens de programas deste livro. Nota: e importante lembrar que sites de internet mudam constantemente, de forma que alguns links podem n ao estar mais dispon veis.

J.2

HOWTO - Como fazer

Veremos a seguir uma lista de HOWTOs relacionados direta ou indiretamente com programa ca o em C++, desenvolvimento de software livre, software multiplataforma, cluster de computadores e programa ca o paralela. C++ Programming HOWTO. C++ Beautiful HOWTO. CVS RCS HOWTO (document for Linux Source Code Control System). GCC HOWTO. Program Library HOWTO. Kernel HOWTO (kernel do GNU/Linux). Beowulf HOWTO. Parallel Processing HOWTO. Serial Programming HOWTO. 727

728 Glibc 2 HOWTO. Software Release Practice HOWTO. Bash Prog Intro HOWTO. BASH Programming Introduction HOWTO. C editing with VIM HOWTO. Emacs Beginner HOWTO. Esses HOWTOs podem ser obtidos nos sites: http://www.tldp.org/HOWTO/HOWTO-INDEX/howtos.html,

J.3. SITES UML

http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/ps/.

J.3

Sites UML

UML no Brasil: http://www.uml.com.br Object management group : http://www.omg.org Refer encia r apida: http://www.rational.com/uml/resources/quick/ UML Tutorial in 7 days : http://odl-skopje.etf.ukim.edu.mk/UML-Help/ Softwares de modelagem: http://www.microgold.com http://www.rational.com/products/rose http://www.visual-paradigm.com http://www.gnome.org/gnome-office/dia.shtm http://bouml.free.fr/ Programa ca o Orientada para Objeto em C++ no Ambiente Windows: http://www.fea.usp.br/Fia/livros/95/liv95-ProgOrientC++.html Object-Oriented Technologies Ltd : http://www.realobj.demon.co.uk/ Welcome to OOPs world : http://oop.rosweb.ru/ Bibliograa: http://liinwww.ira.uka.de/bibliography/Object/index.html Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

J.4. SITES C++

729

J.4
J.4.1

Sites C++
Ambientes de desenvolvimento

Kdevelop, ambiente multiplataforma e multilinguagem, completo, com uso da biblioteca QT ou KDE: kdevelop http: // www. kdevelop. org/ Bloodshed Dev-C++ (Windows, GNU/Linux): http://www.bloodshed.net/dev/devcpp.html The Source-Navigator IDE, (GNU/Linux, Unix): http://sources.redhat.com/sourcenav/ Kylix, ambiente com uso da biblioteca VCL (Visual Class Library ) (GNU/Linux, Unix, Windows): http://www.borland.com/kylix/index.html Code Warrior Metroworks, ambiente com uso da biblioteca code warrior : http://www.metrowerks.com Qt - designer, desenho de interfaces gr acas usando a biblioteca Qt (Windows, GNU/Linux, Unix, Mac): http://www.trolltech.com Veja uma pequena reportagem sobre o Qtdesigner na Revista do Linux, edi ca o 31: http://www.revistadolinux.com.br/ed/031/assinantes/programacao.php3 glade, desenho de interfaces gr acas usando a biblioteca gtk++ (GNU/Linux, Unix): http://glade.gnome.org/ GTK+ - The GIMP Toolkit : http://www.gtk.org/ Source-Navigator(TM) : http://sources.redhat.com/sourcenav/ Anjuta [DevStudio] : http://www.anjuta.org/ Eclipse: http://www.eclipse.org/

J.4.2

Compiladores

Intel: http://www.intel.com/software/products/compilers/ Borland: http://www.borland.com/cbuilder Metroworks: http://www.metrowerks.com/ Microsoft Visual C++: http://msdn2.microsoft.com/en-us/visualc/default.aspx Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

730

J.4. SITES C++

J.4.3

Exemplos

Voc e pode baixar um conjunto de exemplos de programas em C++ em: www.deitel.com ftp://ftp.cs.rpi.edu/pub/stl http://www.tempest-sw.com/cpp Outros exemplos no site da disciplina de programa ca o pr atica: https://www.lenep.uenf.br/~bueno/DisciplinaProgramacaoPratica/

J.4.4

Tutoriais

Uma lista completa de tutoriais pode ser encontrada em: http://www.mysteries-megasite.com/linux/tutorials.html Tutorial de C++ para programadores de C: http://www.4p8.com/eric.brasseur/cppcen.html GTK: http://www.gtk.org/tutorial/ NIST Course on C++ Programming for Scientists : http://math.nist.gov/~RPozo/c++class/ Diversos: http://www.freetutorials.com/ http://www.mysteries-megasite.com/linux/tutorials.html http://www.cplusplus.com/doc/tutorial/ http://www.intap.net/~drw/cpp/index.htm

J.4.5

FAQ

http://help-site.com/c.m/prog/lang/cpp/ http://www.jamesd.demon.co.uk/csc/faq.html

J.4.6

Usu arios avan cados de C++

Voc e encontra em http://www.gotw.ca/publications/, diversas dicas de links do autor Herb Sutter. De um modo geral s ao dicas avan cadas. Dicas de gerenciamento de mem oria: http://www.arnaut.eti.br/op/CPPFL16.htm. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

J.5. SITES STL - STANDART TEMPLATE LIBRARY

731

J.5

Sites STL - Standart Template Library

Comite Ansi C++: http://www.open-std.org/jtc1/sc22/WG21/ Guia STL da GNU: http://gcc.gnu.org/onlinedocs/libstdc++/documentation.html Guia STL: http://www.sgi.com/tech/stl/ Phil Ottewells STL Tutorial : http://www.yrl.co.uk/~phil/stl/stl.htmlx Standard C++ Library User Guide and Tutorial : http://www.roguewave.com/support/docs/stdug/index.cfm STL Quick Reference: http://yotam.freehosting.net/stl/stl.html

J.6
J.6.1

Sites Programa c ao multiplataforma (GNU/Linux)


Software Livre

GNU: http://www.gnu.org ftp://ftp.matrix.com.br/pub/gnu/ Open-source : http://www.opensource.org Reposit orio de programas livres: http://www.sourceforge.net Software Livre - Unicamp (Nou-Rau): http://www.dicas-l.unicamp.br http://www.rau-tu.unicamp.br/nou-rau/softwarelivre/ http://www.softwarelivre.unicamp.br/sl http://www.rau-tu.unicamp.br/ http://www.rau-tu.unicamp.br/linux/ Site com refer encias para comandos do shell: http://www.ss64.com/index.html Linux pdfs: http://users.urbi.com.br/ricardomartins/Linux/ Id eias/Discuss oes: http://www.dicas-l.com.br/brod/ Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

732

MULTIPLATAFORMA (GNU/LINUX) J.6. SITES PROGRAMAC AO

J.6.2

Portabilidade

Guia de Portabilidade: http://www.angelfire.com/country/aldev0/cpphowto/cpp_PortabilityGuide.html

J.6.3

Software multiplataforma

GCC Home Page - GNU Project - Free Software Foundation (FSF) : http://gcc.gnu.org/ Mirror da GNU : ftp://ftp.matrix.com.br/pub/gnu/ autoconf : http://www.gnu.org/software/autoconf/ automake : http://www.gnu.org/software/automake/ libtool : http://www.gnu.org/software/libtool/ GNU Autoconf, Automake and Libtool : http://sources.redhat.com/autobook/ GNU Coding Standards (FSF) : http://www.gnu.org/prep/standards_toc.html Autoconf, Automake, and Libtool: C Language Portability : http://sources.redhat.com/autobook/autobook/autobook_111.html LUV talk: An introduction to Linux/Unix programming : http://www.luv.asn.au/overheads/prog/

J.6.4

Auditoria e proler

Programas de auditoria e prolers valgrind : http://valgrind.org/ callgrind : http://spi.cern.ch/extsoft/packages.php?pkg=callgrind oprole : http://oprofile.sourceforge.net/ kcachegrind : http://kcachegrind.sourceforge.net/cgi-bin/show.cgi Manual do gprof : http://www.delorie.com/gnu/docs/binutils/gprof_toc.html Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

PARALELA J.7. SITES CLUSTER E PROGRAMAC AO

733

J.6.5

CVS

A casa do cvs: http://www.cvshome.org/ Interface gr aca para o cvs: http://www.cvsgui.org/download.html http://www.lincvs.org Interface gr aca para o cvs no GNU/LINUX: http://cervisia.sourceforge.net/

J.6.6

Documenta c ao

Doxygen: http://www.stack.nl/~dimitri/doxygen/index.html DocBook - Linux Productivity Magazine : http://www.troubleshooters.com/lpm/200210/200210.htm DocBook with Ly X: http://bgu.chez.tiscali.fr/doc/db4lyx/ emacs - reportagem: http://bazar.conectiva.com.br/~godoy/emacs/psgml/ sgml - reportagem: http://bazar.conectiva.com.br/~godoy/sgml/docbook/porque/ Welcome to GraphViz : http://www.graphviz.org/ Graphviz - Diagramas UML: http://www.research.att.com/sw/tools/graphviz/refs.html

J.7

Sites Cluster e Programa c ao Paralela

PVM - Parallel Virtual Machine http://www.epm.ornl.gov/pvm/pvm_home.html. LAM/MPI (Local Area Multicomputer / Message Passing Interface http://www.mpi.nd.edu/lam OOMPI : http://www.osl.iu.edu/research/oompi/ Threads http://www.humanfactor.com/pthreads/ Beowulf : http://www.beowulf.org Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

734

J.8. SITES BIBLIOTECAS http://beowulf-underground.org beowulf-request@cesdis.gsfc.nasa.gov http://beowulf.gsfc.nasa.gov/software/software.html http://www.cacr.caltech.edu/beowulf/tutorial/building.html

Extreme Linux Software from Red Hat : http://www.redhat.com/extreme,http://www.extremelinux.org Jaceks Beowulf-utils : ftp://ftp.sci.usq.edu.au/pub/jacek/beowulf-utils bWatch - cluster monitoring tool : http://www.sci.usq.edu.au/staff/jacek/bWatch UTC - Tutorial de Unied Parallel C http://anahy.org/Tools/UnifiedParallelC/index.html, http://upc.gwu.edu/ Informa co es gerais sobre cluster: http://www.buyya.com/cluster

J.8
J.8.1

Sites Bibliotecas
Bibliotecas e ferramentas
http://www.trumphurst.com/cpplibs1.html http://www.thefreecountry.com/developercity/freelib.html

Lista de bibliotecas:

Biblioteca Common c++: http://www.voxilla.org/projects/projape.html boost: http://www.boost.org/ blitz++: http://oonumerics.org/blitz/ Ferramentas de C++: http://development.freeservers.com redhat.com|Cygwin: http://www.redhat.com/software/tools/cygwin/ Qt: http://trolltech.com.br/. http://doc.trolltech.com/4.2/index.html Bibliotecas matem aticas e cient cas da GNU: http://www.files-library.com/library/gnu-scientific-library.html http://gfemlib.sourceforge.net/ http://sscilib.sourceforge.net/ Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

J.9. SITES GRUPOS

735

J.8.2

Programa c ao cient ca

SAL - Numerical Analysis - Miscellaneous Software : http://lem.ch.unito.it/linux/B/0/ SourceForge.net: Project Info - Common C++ Libraries : http://sourceforge.net/projects/cplusplus/ Biblioteca matpack++: http://www.matpack.de/ HPC++: http://www.extreme.indiana.edu/hpc++/index.html Blitz++ Home Page : http://oonumerics.org/blitz/ The Graph Template Library (GTL) : http://www.infosun.fmi.uni-passau.de/GTL/ sl++ project : http://ldeniau.home.cern.ch/ldeniau/html/sl++.html PLAPACK: http://www.cs.utexas.edu/users/plapack/ Numerical Recipes Home Page : http://www.nr.com/ Iterative Methods Library in C++ : http://math.nist.gov/iml++/ The Object-Oriented Numerics Page : http://oonumerics.org/oon/#libraries GNU Scientic Library : http://www.gnu.org/directory/GNU/GNUsl.html Signal Processing Using C++ Classes : http://spuc.sourceforge.net/ The Programming Sharehouse : http://development.freeservers.com/

J.9

Sites Grupos

Grupo de discuss ao de C++: comp.lang.c++, alt.comp.lang.learn.c-c++ Diversas listas de discuss ao de software livre est ao disponibilizadas em: http://listas.softwarelivre.org/ Grupo de GNU/Linux na UFSC: http://www.softwarelivre.ufsc.br Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

736 http://www.engnux.ufsc.br/ Yahoo! Groups : linux-prog : http://groups.yahoo.com/group/linux-prog/

J.10. SITES REVISTAS

J.10

Sites Revistas

http://www.revistadolinux.com.br/ http://www.gazetadolinux.com/contenido_gaceta/html_revistas http://ldp.pop-rn.rnp.br/LDP/LG/ http://www.uol.com.br/olinux/ http://www.linux-magazine.com.br/ http://www.revistapcecia.com.br/

J.11
. . .

Livros de C++

J.12

Fedora

http://www.fedora.org.br/ http://forum.fedoraforum.org/ http://fedora.redhat.com/docs/install-guide/fc6/.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice K

Arquivos de Cabe calho


Apresentaremos neste ap endice uma lista de arquivos de cabe calho e sua descri ca o.

K.1

Introdu c ao aos arquivos de cabe calho

A linguagem C/C++ possui um conjunto extenso de arquivos denominados arquivos de cabe calho. Estes arquivos incluem as fun co es e classes da biblioteca padr ao de C e C++. Em sistemas GNU/Linux estes arquivos est ao localizados em /usr/include/ (arquivos de cabe calho de C) e /usr/include/c++/vers aoCompilador/ (arquivos de cabe calho de C++). Nos ambientes de desenvolvimento do Windows, os arquivos de cabe calho costumam ser instalados no mesmo diret orio do compilador. Veremos a seguir os arquivos de cabe calho relacionados a: STL (veja se ca o K.4). Objetos fun co es e algoritmos gen ericos (veja se ca o K.4.2). Tratamento de erro, exce co es (veja se ca o K.5). Matem aticos, num ericos (veja se ca o K.4.3). Utilit arios (veja se ca o K.6). Entrada e sa da (streams) (veja se ca o K.2). Strings de C++ (veja se ca o K.3). Bibliotecas de C (veja se ca o K.7). Unix, GNU/Linux (veja se ca o K.8).

K.2

Entrada e sa da (streams)

<locale> Classe para considera ca o de localidades (aspectos regionais, culturais) (se ca o 22.9.2). <streambuf> Buers para streams (Cap tulo 22). <ios> Classe-base para hierarquia de streams (se ca o 22.3). 737

738 <iomanip> Manipuladores (se ca o 22.4). <istream> Classe gabarito para entrada de dados (se ca o 22.7). <ostream> Classe gabarito para sa da de dados (se ca o 22.5).

K.3. STRINGS DE C++

<iostream> Entrada e sa da com streams (Cap tulo 22, se co es 22.7 e 22.5). <sstream> Classes para manipula ca o de strings/streams em conjunto (se ca o 22.8). <fstream> Entrada e sa da com arquivos de disco (se ca o 23.2). <iosfwd> Recursos de E/S. "pstream.h" O arquivo de cabe calho pstream.h descrito na se ca o 23.5.4 (n ao e um arquivo padr ao). O mesmo e inclu do junto com as listagem do livro. Tamb em pode ser obtido em http://pstreams.sourceforge.net.

K.3

Strings de C++

<string> A classe string (Cap tulo 24).

K.4
K.4.1
<list> <deque> <stack> <queue> <map> <set>

STL
Containers da STL
Listas duplamente encadeadas (se ca o 32.2). Fila de duas pontas (se ca o 32.3). Pilha do tipo LIFO, primeiro que entra e o ultimo que sai (se ca o 33.1). Fila do tipo FIFO, primeiro que entra e o primeiro que sai (se ca o 33.2). Par associativo chave-valor, inclue as classes <map> (se ca o 34.4) e <multimap> (34.5). Conjunto de chaves, inclue as classes <set> (se ca o 34.2) e <multiset> (se ca o 34.3).

<vector> Vetor unidimensional (se ca o 32.1).

<bitset> Vetor de valores booleanos (se ca o 30.3). <iterator> Iteradores (se ca o 31.3). <valarray> Classes de vetores de alto desempenho (a dica e usar a biblioteca Blitz++,). Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

K.5. TRATAMENTO DE ERRO, EXCEC OES

739

K.4.2

Objetos fun c oes e algoritmos gen ericos

<utility> Operadores e pares. <functional> Objetos fun co es (Cap tulo 36). <algorithm> Algoritmos gen ericos, fun co es gen ericas (Cap tulo 35). <numeric> Opera co es gen ericas (Cap tulo 35).

K.4.3

Matem aticos, num ericos

<limits> Deni ca o de limites num ericos (Cap tulo 9.1, veja exemplo na listagem 9.3). <complex> Classe dos n umeros complexos (se ca o 30.2). <valarray> Classes de vetores de alto desempenho. <numeric> Opera co es gen ericas (se ca o 35.3).

K.5

Tratamento de erro, exce c oes

<exception> Tratamento de exce co es, classes de exce ca o (Cap tulo 26). <stdexcept> Exce co es-padr ao (Cap tulo 26).

K.6
<new>

Utilit arios
Aloca ca o din amica de mem oria (se ca o 15.3.1). Aloca ca o de mem oria e containers.

<memory> <typeinfo> Identica ca o de tipos em tempo de execu ca o.

K.7

Bibliotecas de C

Observe que em vers oes antigas de C, estes arquivos de cabe calho n ao tinham a letra inicial c e inclu am uma extens ao .h. Por exemplo, o arquivo de cabe calho <ctime> se chamava <time.h>. Nota: e nesta se ca o colocamos apenas uma breve descri ca o da fun ca o. Para maiores detalhes importante lembrar que algumas classes de bibliotecas consulte os manuais e sites de C. E externas, como Blitz++, substituem com vantagens estas fun co es. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

740

K.7. BIBLIOTECAS DE C

K.7.1

<cstdlib>
Aborta o processor currente e retorna c odigo de erro. Retorna o valor absoluto de um n umero inteiro passado como par ametro. Converte string para double. Converte string para int. Converte string para long. Pesquisa binaria. calloc() Aloca um array de mem oria. div() *ecvt() exit() *fcvt() free() *gcvt() *itoa() labs() ldiv() Divide dois n umeros inteiros. Converte n umeros oating point para string. Termina o processo. Converte n umeros oating point para string. Desaloca memoria alocada dinamicamente. Converte n umeros oating point para string. Converte n umero inteiro para string. Retourna valor absoluto de par ametro long int. Divide dois n umeros long int.

<cstdlib> Fun co es padr oes de C. Veja http://www.cplusplus.com/ref/. abort() abs() atof() atoi() atol() bsearch()

atexit() Especica a fun ca o a ser executada quando exit() e chamada.

getenv() Obt em string do meio ambiente.

*lfind() Pesquisa linear. *lsearch() Pesquisa linear. *ltoa() *max() *min() *putenv() Cria ou modica vari avel de ambiente. qsort() rand() realloc() Realoca bloco de mem oria. srand() Inicializa gerador de n umeros rand omicos. strtod() Converte string para double. strtol() Converte string para long int. strtoul() Converte string para unsigned long int. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno Ordena ca o usando algoritmo tipo quicksort. Gera n umero randomico. Converte n umero long int para string. Retorna o maior valor de dois parametros. Retorna o menor valor de dois parametros. malloc() Aloca bloco de mem oria.

K.7. BIBLIOTECAS DE C *swab() *ultoa() Converte unsigned long int para string. Troca bytes.

741

system() Executa comando.

K.7.2

<cstdio>

<cstdio> Fun co es de entrada e sa da de C. Veja http://www.cplusplus.com/ref/. clearerr() Reseta o indicador de erros. fclose() Fecha a stream. feof() Checa se End Of File ocorreu. ferror() Checa por erros. fflush() Descarrega a stream. fgetc() fgets() Obt em uma string a partir de uma stream. fopen() fprintf() Imprime dados formados para uma stream. fputc() Escreve um caracter em uma stream. fputchar() Escreve um caracter em stdout. fputs() fread() Escreve uma string em uma stream. L e um bloco de dados de uma stream. Abre arquivo. Obt em o pr oximo caracter da stream. fgetpos() Obt em posi ca o da stream (ponteiro get).

freopen() Reabre um arquivo usando outro modo de abertura. fscanf() L e dados formatados de uma stream. fseek() Reposiciona posi ca o do ponteiro de leitura (stream s position indicator ). Retorna posi ca o corrente do ponteiro de arquivo. Obt em pr oximo caracter. Obt em uma string de stdin. Obt em o pr oximo valor de uma stream.

fsetpos() Reposiciona ponteiro para arquivo salvo numa determinada localiza ca o. ftell() getc() gets() getw() fwrite() Escreve um bloco de dados em uma stream. getchar() Obt em pr oximo caracter de stdin.

perror() Imprime mensagem de erro. printf() Imprime dados formatados para stdout. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

742 putc() putchar() Escreve um caracter para stdout. puts() putw() Escreve uma string para stdout. Escreve um inteiro em uma stream. Escreve um caracter para stream.

K.7. BIBLIOTECAS DE C

remove() Apaga um arquivo. rename() Renomeia um arquivo ou diret orio. rewind() Reposiciona ponteiro de arquivo a partir do in cio da stream. scanf() L e dados formatados de stdin. setbuf() Muda stream buferizada. setvbuf() Muda stream buferizada. sprintf() Formata dados para string. sscanf() L e dados formatados da string. tmpfile() Abre temporariamente um arquivo. tmpnam() Gera um arquivo tempor ario e u nico. ungetc() Coloca um caracter de volta na stream.

K.7.3
<ctime>

<ctime>
Data e hora no formato de C, rel ogio do sistema (antigo time.h). Veja http: //www.cplusplus.com/ref/. asctime() Converte uma estrutura tm para string. clock() ctime() Retorna o n umero de clock ticks desde que o processo foi iniciado. Converte time_t para string.

difftime() Retorna a diferen ca entre dois time_t. gmtime() Converte o valor time_t para uma estrutura UTC. localtime() Converte o valor time_t para uma estrutura tm como hora local. mktime() Converte uma estrutura tm para time_t. time() Obt em tempo corrente.

K.7.4

<cstring>

<cstring> Antigas fun co es para tratamento de strings de C. Veja http://www.cplusplus.com/ref/. memchr() Procura caracter no buer. memcmp() Compara dois buers. memcpy() Copia bytes de um buer para outro buer. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

K.7. BIBLIOTECAS DE C memmove() Copia bytes de um buer para outro buer. memset() Preenche o buer com o caracter especicado. strcat() Adiciona cstring no modo append. strchr() Procura caracter numa cstring. strcmp() Compara duas cstrings. strcoll() Compara duas cstrings usando informa co es do locale. strcpy() Copia cstrings. strcspn() Search string for occurrence of charcter set strerror() Obt em ponteiro para mensagem de erro da cstring. strlen() Retorna dimens ao da cstring. strncat() Adiciona substring em uma cstring. strncmp() Compara alguns caracteres das duas strings. strncpy() Copia caracteres de uma string para outra. strpbrk() Procura na cstring caracteres especicados. strrchr() Procura u ltima ocorr encia de um caracter na cstring. strspn() Obt em a dimens ao da substring. strstr() Procura substring. strtok() Trunca a cstring sequencialmente se o delimitador foi localizado. strxfrm() Transforma a cstring usando caracter sticas do locale.

743

K.7.5

Diversos

<cassert> Inclui a macro assert. <cerrno> Tratamento de erro. <cctype> Deni ca o de caracteres (classica ca o). <cwtype> Deni ca o de caracteres longos (classica ca o). <cwchar> Antigas fun co es para tratamento de strings de C longas. <clocale> Fun co es para considera ca o de localidades (aspectos regionais, culturais). <climits> Deni ca o de limites num ericos. <cfloat> Macros de limites num ericos (ponto utuante). <cstddef> Suporte de linguagem. <cstdarg> Tratamento de argumentos (lista de argumentos). <csignal> Tratamento de sinais. <cmath> Fun co es matem aticas padr oes (se ca o 30.1).

<unistd.h> Fun co es padr oes do Unix, GNU/Linux. Inclui fun co es como: chown, link, unlink, symlink, rmdir, chdir. Veja listagem ??. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

744

K.8. UNIX, GNU/LINUX

K.8

Unix, GNU/Linux

<unistd.h> Fun co es diversas de Unix, GNU/Linux (veja Parte ?? - Programa ca o Multiplataforma com Software Livre e Parte ?? Cluster de Computadores e Processamento Paralelo. <sys/stat.h> Fun co es Unix, incluindo: chmod(), mkdir(), getcwd().

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Ap endice L

Licen ca P ublica Geral GNU


Vers ao 2, junho de 1991. This is an unocial translation of the GNU General Public License into Brazilian Portuguese. It was not published by the Free Software Foundation, and does not legally state the distribution terms for software that uses the GNU GPL only the original English text of the GNU GPL does that. However, we hope that this translation will help Brazilian Portuguese speakers understand the GNU GPL better. Esta e uma tradu ca o n ao-ocial da Licen ca P ublica Geral GNU (GPL GNU) para o portugu es do Brasil. Ela n ao foi publicada pela Free Software Foundation, e legalmente n ao arma os termos de distribui ca o de software que utiliza a GPL GNU apenas o texto original da GPL GNU, em ingl es, faz isso. Contudo, esperamos que esta tradu ca o ajude aos que utilizam o portugu es do Brasil a entender melhor a GPL GNU. Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA A qualquer pessoa e permitido copiar e distribuir c opias desse documento de licen ca, desde que sem qualquer altera ca o.

L.1

Introdu c ao

As licen cas de muitos software s ao desenvolvidas para restringir sua liberdade de compartilh alo e mud a-lo. Contr aria a isso, a Licen ca P ublica Geral GNU pretende garantir sua liberdade de compartilhar e alterar software livres garantindo que o software ser a livre e gratuito para os seus usu arios. Esta Licen ca P ublica Geral aplica-se ` a maioria dos software da Free Software Foundation e a qualquer outro programa cujo autor decida aplic a-la. (Alguns outros software da FSF s ao cobertos pela Licen ca P ublica Geral de Bibliotecas, no entanto.) Voc e pode aplic a-la tamb em aos seus programas. Quando nos referimos a software livre, estamos nos referindo a liberdade e n ao a pre co. Nossa Licen ca P ublica Geral foi desenvolvida para garantir que voc e tenha a liberdade de distribuir c opias de software livre (e cobrar por isso, se quiser); que voc e receba o c odigo-fonte ou tenha acesso a ele, se quiser; que voc e possa mudar o software ou utilizar partes dele em novos programas livres e gratuitos; e que voc e saiba que pode fazer tudo isso. Para proteger seus direitos, precisamos fazer restri co es que impe cam a qualquer um negar estes direitos ou solicitar que voc e deles abdique. Estas restri co es traduzem-se em certas responsabilidades para voc e, se voc e for distribuir c opias do software ou modic a-lo. 745

E L.2. LICENCA PUBLICA GERAL GNU CONDIC OES PARA COPIA, DISTRIBUIC AO 746 MODIFICAC AO Por exemplo, se voc e distribuir c opias de um programa, gratuitamente ou por alguma quantia, voc e tem que fornecer aos recebedores todos os direitos que voc e possui. Voc e tem que garantir que eles tamb em recebam ou possam obter o c odigo-fonte. E voc e tem que mostrarlhes estes termos para que eles possam conhecer seus direitos. N os protegemos seus direitos em dois passos: (1) com copyright do software e (2) com a oferta desta licen ca, que lhe d a permiss ao legal para copiar, distribuir e/ou modicar o software. Al em disso, tanto para a prote ca o do autor quanto a nossa, gostar amos de certicar-nos que todos entendam que n ao h a qualquer garantia nestes software livres. Se o software e modicado por algu em mais e passado adiante, queremos que seus recebedores saibam que o que eles obtiveram n ao e original, de forma que qualquer problema introduzido por terceiros n ao interra na reputa ca o do autor original. Finalmente, qualquer programa e amea cado constantemente por patentes de software. Queremos evitar o perigo de que distribuidores de software livre obtenham patentes individuais, o que tem o efeito de tornar o programa propriet ario. Para prevenir isso, deixamos claro que qualquer patente tem que ser licenciada para uso livre e gratuito por qualquer pessoa, ou ent ao que nem necessite ser licenciada. Os termos e condi co es precisas para c opia, distribui c ao e modica ca o se encontram abaixo:

L.2

Licen ca p ublica geral GNU condi c oes para c opia, distribui c ao e modica c ao

0. Esta licen ca se aplica a qualquer programa ou outro trabalho que contenha um aviso colocado pelo detentor dos direitos autorais informando que aquele pode ser distribu do sob as condi co es desta Licen ca P ublica Geral. O Programa abaixo refere-se a qualquer programa ou trabalho, e trabalho baseado no Programa signica tanto o Programa em si como quaisquer trabalhos derivados, de acordo com a lei de direitos autorais: isto quer dizer um trabalho que contenha o Programa ou parte dele, tanto originalmente ou com modica co es, e/ou tradu ca o para outros idiomas. (Doravante o processo de tradu ca o est a inclu do sem limites no termo modica ca o.) Cada licenciado e mencionado como voc e. Atividades outras que a c opia, a distribui ca o e modica ca o n ao est ao cobertas por esta Licen ca; elas est ao fora de seu escopo. O ato de executar o Programa n ao e restringido e o resultado do Programa e coberto apenas se seu conte udo contenha trabalhos baseados no Programa (independentemente de terem sido gerados pela execu ca o do Programa). Se isso e verdadeiro depende do que o programa faz. 1. Voc e pode copiar e distribuir c opias eis do c odigo-fonte do Programa da mesma forma que voc e o recebeu, usando qualquer meio, deste que voc e consp cua e apropriadamente publique em cada c opia um aviso de direitos autorais e uma declara ca o de inexist encia de garantias; mantenha intactas todos os avisos que se referem a esta Licen ca e ` a aus encia total de garantias; e forne ca a outros recebedores do Programa uma c opia desta Licen ca, junto com o Programa. 2. Voc e pode modicar sua c opia ou c opias do Programa, ou qualquer parte dele, assim gerando um trabalho baseado no Programa, e copiar e distribuir essas modica co es ou trabalhos sob os temos da se ca o 1 acima, desde que voc e tamb em se enquadre em todas estas condi co es: a) Voc e tem que fazer com que os arquivos modicados levem avisos proeminentes armando que voc e alterou os arquivos, incluindo a data de qualquer altera ca o. Andr e Duarte Bueno

Programa ca o Orientada a Objeto com C++

E L.2. LICENCA PUBLICA GERAL GNU CONDIC OES PARA COPIA, DISTRIBUIC AO MODIFICAC AO 747 b) Voc e tem que fazer com que quaisquer trabalhos que voc e distribua ou publique, e que integralmente ou em partes contenham ou sejam derivados do Programa ou de suas partes, sejam licenciados, integralmente e sem custo algum para quaisquer terceiros, sob os termos desta Licen ca. Se qualquer programa modicado normalmente l e comandos interativamente quando executados, voc e tem que fazer com que, quando iniciado tal uso interativo da forma mais simples, seja impresso ou mostrado um an uncio de que n ao h a qualquer garantia (ou ent ao que voc e fornece a garantia) e que os usu arios podem redistribuir o programa sob estas condi co es, ainda informando os usu arios como consultar uma c opia desta Licen ca. (Exce ca o: se o Programa em si e interativo mas normalmente n ao imprime estes tipos de an uncios, seu trabalho baseado no Programa n ao precisa imprimir um an uncio.)

c)

Estas exig encias aplicam-se ao trabalho modicado como um todo. Se se co es identic aveis de tal trabalho n ao s ao derivadas do Programa, e podem ser razoavelmente consideradas trabalhos independentes e separados por si s o, ent ao esta Licen ca, e seus termos, n ao se aplicam a estas se co es quando voc e distribui-las como trabalhos em separado. Mas quando voc e distribuir as mesmas se co es como parte de um todo que e trabalho baseado no Programa, a distribui ca o como um todo tem que se enquadrar nos termos desta Licen ca, cujas permiss oes para outros licenciados se estendem ao todo, portanto tamb em para cada e toda parte independente de quem a escreveu. Desta forma, esta se ca o n ao tem a inten ca o de reclamar direitos os contestar seus direitos sobre o trabalho escrito completamente por voc e; ao inv es disso, a inten ca o e a de exercitar o direito de controlar a distribui ca o de trabalhos, derivados ou coletivos, baseados no Programa. Adicionalmente, a mera adi ca o ao Programa de outro trabalho n ao baseado no Programa (ou de trabalho baseado no Programa) em um volume de armazenamento ou meio de distribui ca o n ao faz o outro trabalho parte do escopo desta Licen ca. 3. Voc e pode copiar e distribuir o Programa (ou trabalho baseado nele, conforme descrito na Se ca o 2) em c odigo-objeto ou em forma execut avel sob os termos das Se co es 1 e 2 acima, desde que voc e fa ca um dos seguintes: a) O acompanhe com o c odigo-fonte completo e em forma acess vel por m aquinas, que tem que ser distribu do sob os termos das Se co es 1 e 2 acima e em meio normalmente utilizado para o interc ambio de software ; ou, O acompanhe com uma oferta escrita, v alida por pelo menos tr es anos, de fornecer a qualquer um, com um custo n ao superior ao custo de distribui ca o f sica do material, uma c opia do c odigo-fonte completo e em forma acess vel por m aquinas, que tem que ser distribu do sob os termos das Se co es 1 e 2 acima e em meio normalmente utilizado para o interc ambio de software ; ou, O acompanhe com a informa ca o que voc e recebeu em rela ca o ` a oferta de distribui ca o do c odigo-fonte correspondente. (Esta alternativa e permitida somente em distribui ca o n ao comerciais, e apenas se voc e recebeu o programa em forma de c odigo-objeto ou execut avel, com oferta de acordo com a Subse ca o b acima.)

b)

c)

O c odigo-fonte de um trabalho corresponde ` a forma de trabalho preferida para se fazer modica co es. Para um trabalho em forma execut avel, o c odigo-fonte completo signica Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

E L.2. LICENCA PUBLICA GERAL GNU CONDIC OES PARA COPIA, DISTRIBUIC AO 748 MODIFICAC AO todo o c odigo-fonte de todos os m odulos que ele cont em, mais quaisquer arquivos de deni ca o de interface, mais os scripts utilizados para se controlar a compila ca o e a instala ca o do execut avel. Contudo, como exce ca o especial, o c odigo-fonte distribu do n ao precisa incluir qualquer componente normalmente distribu do (tanto em forma original quanto bin aria) com os maiores componentes (o compilador, o kernel etc.) do sistema operacional sob o qual o execut avel funciona, a menos que o componente em si acompanhe o execut avel. Se a distribui ca o do execut avel ou c odigo-objeto e feita atrav es da oferta de acesso a c opias de algum lugar, ent ao ofertar o acesso equivalente a c opia, do mesmo lugar, do c odigofonte equivale ` a distribui ca o do c odigo-fonte, mesmo que terceiros n ao sejam compelidos a copiar o c odigo-fonte com o c odigo-objeto. 4. Voc e n ao pode copiar, modicar, sub-licenciar ou distribuir o Programa, exceto de acordo com as condi co es expressas nesta Licen ca. Qualquer outra tentativa de c opia, modica ca o, sub-licenciamento ou distribui ca o do Programa n ao e valida, e cancelar a automaticamente os direitos que lhe foram fornecidos por esta Licen ca. No entanto, terceiros que de voc e receberam c opias ou direitos, fornecidos sob os termos desta Licen ca, n ao ter ao suas licen cas terminadas, desde que permane cam em total concord ancia com ela. 5. Voc e n ao e obrigado a aceitar esta Licen ca j a que n ao a assinou. No entanto, nada mais o dar a permiss ao para modicar ou distribuir o Programa ou trabalhos derivados deste. Estas a co es s ao proibidas por lei, caso voc e n ao aceite esta Licen ca. Desta forma, ao modicar ou distribuir o Programa (ou qualquer trabalho derivado do Programa), voc e estar a indicando sua total aceita ca o desta Licen ca para faz e-los, e todos os seus termos e condi co es para copiar, distribuir ou modicar o Programa, ou trabalhos baseados nele. 6. Cada vez que voc e redistribuir o Programa (ou qualquer trabalho baseado nele), os recebedores adquirir ao automaticamente do licenciador original uma licen ca para copiar, distribuir ou modicar o Programa, sujeitos a estes termos e condi co es. Voc e n ao poder a impor aos recebedores qualquer outra restri ca o ao exerc cio dos direitos ent ao adquiridos. Voc e n ao e respons avel em garantir a concord ancia de terceiros a esta Licen ca. 7. Se, em conseq u encia de decis oes judiciais ou alega co es de infringimento de patentes ou quaisquer outras raz oes (n ao limitadas a assuntos relacionados a patentes), condi co es forem impostas a voc e (por ordem judicial, acordos ou outras formas) e que contradigam as condi co es desta Licen ca, elas n ao o livram das condi co es desta Licen ca. Se voc e n ao puder distribuir de forma a satisfazer simultaneamente suas obriga co es para com esta Licen ca e para com as outras obriga co es pertinentes, ent ao como conseq u encia voc e n ao poder a distribuir o Programa. Por exemplo, se uma licen ca de patente n ao permitir aa redistribui ca o, livre de royalties, do Programa, por todos aqueles que receberem c opias direta ou indiretamente de voc e, ent ao a u nica forma de voc e satisfazer a ela e a esta Licen ca seria a de desistir completamente de distribuir o Programa. Se qualquer parte desta se ca o for considerada inv alida ou n ao aplic avel em qualquer circunst ancia particular, o restante da se ca o se aplica, e a se ca o como um todo se aplica em outras circunst ancias. O prop osito desta se ca o n ao e o de induzi-lo a infringir quaisquer patentes ou reivindica ca o de direitos de propriedade outros, ou a contestar a validade de quaisquer dessas reivindica co es; esta se ca o tem como u nico prop osito proteger a integridade dos sistemas de distribui ca o de software livres, o que e implementado pela pr atica de licen cas p ublicas. Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

E L.2. LICENCA PUBLICA GERAL GNU CONDIC OES PARA COPIA, DISTRIBUIC AO MODIFICAC AO 749 V arias pessoas t em contribu do generosamente e em grande escala para os software distribu dos usando este sistema, na certeza de que sua aplica c ao e feita de forma consistente; ca a crit erio do autor/doador decidir se ele ou ela est a disposto a distribuir software utilizando outro sistema, e um licenciado n ao pode impor qualquer escolha. Esta se ca o destina-se a tornar bastante claro o que se acredita ser conseq u encia do restante desta Licen ca. 8. Se a distribui ca o e/ou uso do Programa s ao restringidos em certos pa ses por patentes ou direitos autorais, o detentor dos direitos autorais original, e que colocou o Programa sob esta Licen ca, pode incluir uma limita ca o geogr aca de distribui ca o, excluindo aqueles pa ses de forma a tornar a distribui ca o permitida apenas naqueles ou entre aqueles pa ses ent ao n ao exclu dos. Nestes casos, esta Licen ca incorpora a limita ca o como se a mesma constasse escrita nesta Licen ca. 9. A Free Software Foundation pode publicar vers oes revisadas e/ou novas da Licen ca P ublica Geral de tempos em tempos. Estas novas vers oes ser ao similares em esp rito ` a vers ao atual, mas podem diferir em detalhes que resolvem novos problemas ou situa co es. A cada vers ao e dada um n umero distinto. Se o Programa especica um n umero de vers ao espec co desta Licen ca que se aplica a ele e a qualquer nova vers ao, voc e tem a op ca o de aceitar os termos e condi co es daquela vers ao ou de qualquer outra vers ao publicada pela Free Software Foundation. Se o programa n ao especica um n umero de vers ao desta Licen ca, voc e pode escolher qualquer vers ao j a publicada pela Free Software Foundation. 10. Se voc e pretende incorporar partes do Programa em outros programas livres cujas condic o es de distribui ca o s ao diferentes, escreva ao autor e solicite permiss ao. Para o software que a Free Software Foundation det em direitos autorais, escreva ` a Free Software Foundation ; ` as vezes n os permitimos exce co es a este caso. Nossa decis ao ser a guiada pelos dois objetivos de preservar a condi ca o de liberdade de todas as deriva co es do nosso software livre, e de promover o compartilhamento e reutiliza ca o de software em aspectos gerais. AUSENCIA DE GARANTIAS LICENCIADO SEM ONUS, HA QUALQUER 11. UMA VEZ QUE O PROGRAMA E NAO GARANTIA PARA O PROGRAMA, NA EXTENSAO PERMITIDA PELAS LEIS APLICAVEIS. EXCETO QUANDO EXPRESSADO DE FORMA ESCRITA, OS DETENTORES DOS DIREITOS AUTORAIS E/OU TERCEIROS DISPONIBILIZAM O PROGRAMA NO ESTADO, SEM QUALQUER TIPO DE GARANTIAS, EXPRES LIMITADO A, AS GARANTIAS IMSAS OU IMPL ICITAS, INCLUINDO, MAS NAO A QUALQUER PROPLICITAS DE COMERCIALIZAC AO E AS DE ADEQUAC AO POSITO. O RISCO TOTAL COM A QUALIDADE E DESEMPENHO DO PROGRAMA SEU. SE O PROGRAMA SE MOSTRAR DEFEITUOSO, VOCE ASSUME OS CUSE TOS DE TODAS AS MANUTENC OES, REPAROS E CORREC OES. A MENOS QUE EXIGIDO PELAS LEIS APLICAVEIS 12. EM NENHUMA OCASIAO, OU ACORDO ESCRITO, OS DETENTORES DOS DIREITOS AUTORAIS, OU QUALQUER OUTRA PARTE QUE POSSA MODIFICAR E/OU REDISTRIBUIR O PRO RESPONSABILIZADOS POR GRAMA CONFORME PERMITIDO ACIMA, SERAO VOCE POR DANOS, INCLUINDO QUALQUER DANO EM GERAL, ESPECIAL, ACI DENTAL OU CONSEQUENTE, RESULTANTES DO USO OU INCAPACIDADE DE LIMITADO A, A PERDA DE DAUSO DO PROGRAMA (INCLUINDO, MAS NAO DOS OU DADOS TORNADOS INCORRETOS, OU PERDAS SOFRIDAS POR VOCE Programa ca o Orientada a Objeto com C++ Andr e Duarte Bueno

750

L.3. COMO APLICAR ESTES TERMOS AOS SEUS NOVOS PROGRAMAS OU POR OUTRAS PARTES, OU FALHAS DO PROGRAMA AO OPERAR COM QUALQUER OUTRO PROGRAMA), MESMO QUE TAL DETENTOR OU PARTE TENHAM SIDO AVISADOS DA POSSIBILIDADE DE TAIS DANOS. FIM DOS TERMOS E CONDIC OES

L.3

Como aplicar estes termos aos seus novos programas

Se voc e desenvolver um novo programa, e quer que ele seja utilizado amplamente pelo p ublico, a melhor forma de alcan car este objetivo e torn a-lo software livre que qualquer um pode redistribuir e alterar, sob estes termos. mais seguro anex Para isso, anexe os seguintes avisos ao programa. E a-los logo no in cio de cada arquivo-fonte para refor carem mais efetivamente a inexist encia de garantias; e cada arquivo deve possuir pelo menos a linha de copyright e uma indica ca o de onde o texto completo se encontra. <uma linha que forne ca o nome do programa e uma id eia do que ele faz.> Copyright (C) <ano> <nome do autor> Este programa e software livre; voc e pode redistribu -lo e/ou modic a-lo sob os termos da Licen ca P ublica Geral GNU, conforme publicada pela Free Software Foundation ; tanto a vers ao 2 da Licen ca como (a seu crit erio) qualquer vers ao mais nova. Este programa e distribu do na expectativa de ser u til, mas SEM QUALQUER GARANTIA; ou de ADEQUAC A QUALsem mesmo a garantia impl cita de COMERCIALIZAC AO AO QUER PROPOSITO EM PARTICULAR. Consulte a Licen ca P ublica Geral GNU para obter mais detalhes. Voc e deve ter recebido uma c opia da Licen ca P ublica Geral GNU junto com este programa; se n ao, escreva para a Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. Inclua tamb em informa co es sobre como contact a-lo eletronicamente e por carta. Se o programa e interativo, fa ca-o mostrar um aviso breve como este, ao iniciar um modo interativo: Gnomovision vers ao 69, Copyright (C) ano nome do autor O Gnomovision n ao possui QUALQUER GARANTIA; para obter mais detalhes digite show w. Ele e software livre e voc e est a convidado a redistribui-lo sob certas condi co es; digite show c para obter detalhes. Os comandos hipot eticos show w e show c devem mostrar as partes apropriadas da Licen ca P ublica Geral. Claro, os comandos que voc e usar podem ser ativados de outra forma que show w e show c; eles podem at e ser cliques do mouse ou itens de um menu o que melhor se adequar ao programa. Voc e tamb em deve obter do seu empregador (se voc e trabalha como programador) ou escola, se houver, uma declara ca o de aus encia de direitos autorais sobre o programa, se necess ario. Aqui est a um exemplo; altere os nomes: Yoyodyne, Inc., aqui declara a aus encia de quaisquer direitos autorais sobre o programa Gnomovision (que executa interpreta co es em compiladores) escrito por James Hacker. <assinatura de Ty Coon>, 1o. de abril de 1989 Ty Con, Vice-presidente Esta Licen ca P ublica Geral n ao permite incorporar seu programa em programas propriet arios. Se seu programa e uma biblioteca de sub-rotinas, voc e deve considerar mais u til permitir ligar aplica co es propriet arias com a biblioteca. Se isto e o que voc e deseja, use a Licen ca P ublica Geral de Bibliotecas GNU, ao inv es desta Licen ca.

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

Indice Remissivo
<algorithm>, 737 <bitset>, 736 <cmath>, 525 <complex>, 737 <cstdio>, 739 <cstdlib>, 738 <cstring>, 740 <ctime>, 740 <deque>, 736 <exception>, 737 <fstream>, 736 <functional>, 737 <iomanip>, 736 <ios>, 735 <iosfwd>, 736 <iostream>, 736 <istream>, 736 <iterator>, 736 <limits>, 737 <list>, 736 <locale>, 735 <map>, 736 <memory>, 737 <new>, 737 <numeric>, 737 <ostream>, 736 <queue>, 736 <set>, 736 <sstream>, 736 <stack>, 736 <stdexcept>, 737 <streambuf>, 735 <string>, 736 <sys/stat.h>, 742 <typeinfo>, 737 <unistd.h>, 742 <utility>, 737 <valarray>, 736, 737 <vector>, 736 #dene, 638 #if, 639 #if...#elif...#elif...#endif, 641 #if...#else, 640 #ifdef, 638 #ifdef...#else, 640 #ifndef, 639 #undef, 639 Abstra ca o, 69 abstratas, 77 acesso a disco, 429 Agrega ca o, 125 Algoritmos gen ericos, 595 Ambiente gr aco, 151 Ambientes de desenvolvimento, 151, 152, 727 Ambiguidade, 327 Ambiguidade em heran ca m ultipla, 347 An alise de dom nio, 115 An alise orientada a objeto, 105, 119 Ansi C, 183 Ansi C++, 183 AOO, 105, 119, 133 Armazenando e lendo objetos, 434 Arquivo de cabe calho, 187 Arquivo de implementa ca o, 188 Arquivo de projeto, 187 Arquivos de Cabe calho, 735 Arquivos de disco, 429 Arquivos de disco bin arios, 442 Assinatura, 77 associa ca o, 112 Associa co es, 124, 157, 521 Associa co es - identica ca o, 122 Assuntos, 116 assuntos, 116 Atividade, 79 ator, 111 Atribui ca o, 194 Atributo de liga ca o, 521 Atributos, 73, 259 751

752 atributos, 120, 156 Atributos - identica ca o, 120 Atributos - Uso avan cado, 264 Atributos com mutable, 264 Atributos com volatile, 265 Atributos const, 263 Atributos de classe, 261 Atributos de objeto, 260 Atributos est aticos, 261 auto ptr, 686 Base comum, 347 Biblioteca gr aca, 151 biblioteca gr aca, 151 Biblioteca padr ao - stl, 541 Bibliotecas, 402 bibliotecas, 150, 174 Bibliotecas de C, 525 Blocos, 195 break, 671 C odigo Aberto, 53 Cancelamento, 78 Casos de uso, 111 casos de uso, 111 cast, 462 catch, 475 Cen ario, 111 Chamada explicita do construtor, 340 class <bitset>, 532 class <complex>, 528 class <deque>, 569 class <fstream>, 429 class <iomanip>, 409 class <ios>, 413 class <ios base>, 403 class <istream>, 415 class <list>, 563 class <map>, 587 class <multimap>, 592 class <multiset>, 586 class <ostream>, 412 class <priority queue>, 580 class <queue>, 578 class <set>, 583 class <sstream>, 420 class <stack>, 575 class <string>, 447 class <vector>, 555 Classe, 125 Programa ca o Orientada a Objeto com C++

INDICE REMISSIVO Classe de associa ca o, 125 Classes, 72, 249 Classes abstratas, 129, 367 Classes aninhadas, 254 Classes de armazenamento, 195, 645 Classes friend, 381 Classes identica ca o, 119 Classes templates, 494, 511 Classica ca o, 77, 602 colabora ca o, 136 Coment arios, 193 Compara ca o, 598 Compartilhamento, 77 Compila ca o condicional, 638 Compilador - mensagens de erro, 357 Compilar, 185 Compondo namespace, 246 Composi co es, 125 composi co es, 126 composta, 131 comunica ca o, 136 Concep ca o, 105, 110 conjuntos, 604 const, 651 Construtor de c opia, 317 Construtor de convers ao, 461 Construtor default, 315 Construtor e Ambiguidade, 327 Containers, 543 continue, 672 Controle, 147, 665 controle, 149 Conven ca o para nomes de objetos, 197 Convers ao com reinterpret cast, 466 Convers ao de ponteiros, 686 Convers ao din amica, 464 Convers ao est atica, 464 Convers ao explicita, 463 Convers oes, 78, 459 CRC, 171 Cria ca o e destrui ca o dos objetos, 349 Debugar, 185 Declara ca o, 194 Declara ca o de um m etodo, 269 Declara co es, 211 declara co es, 197 Deni ca o, 194 Deni ca o de um m etodo, 270 deni co es, 198 Andr e Duarte Bueno

INDICE REMISSIVO Denindo um namespace, 243 Delega ca o, 76 delete, 300 Depend encias, 130 Destrutores, 314 Dev C++, 153 dia, 93 Diagrama de atividade, 142 Diagrama de atividades com raios de nata ca o, 144 Diagrama de caso de uso, 111 Diagrama de classes, 122 Diagrama de classes com associa co es, 124 Diagrama de classes com heran cas, 128 Diagrama de colabora ca o, 136 Diagrama de componentes, 158 Diagrama de estados compostos ou sub-estados, 139 Diagrama de estrutura composta, 131 Diagrama de execu ca o, 159 Diagrama de intera ca o geral, 145 Diagrama de m aquina de estado, 138 Diagrama de objetos, 130 Diagrama de pacotes, 116 Diagrama de pacotes (assuntos), 116 Diagrama de sequ encia, 134 Diagrama de tempo, 145 Diagramas da UML, 85 Diagramas de estados concorrentes, 140 Diagramas UML, 93 Dicion ario, 171 Diretrizes de pr e-processador, 637 Diretrizes de pr e-processamento, 196 Diversos, 741 do a ca o while (teste);, 671 Documenta ca o, 106, 167 Documenta ca o do programa, 167 dynamic cast, 464 Efeitos do projeto nas associa co es, 157 Efeitos do projeto nas heran cas, 157 Efeitos do projeto nos m etodos, 156 Elabora ca o, 105, 114 Elementos da UML, 88 elipse..., 678 Empacotamento, 172 empacotamento, 172 Encapsulamento, 70, 250, 253 Engenharia de Software, 99 engenharia de software, 101 Programa ca o Orientada a Objeto com C++

753 Entrada e sa da, 401, 735 Entrada e sa da no C++, 401 Entrada na linha de comando, 675 Enumera co es, 699 enumerated, 699 Enviando comandos para outro programa, 442 escala, 83, 175 Escopo, 195, 651 escopo, 211 Especializa ca o, 112 especica ca o, 110 Especica co es, 110 Especicador, 195 Especicador de acesso, 250 Especicador de heran ca, 337 estado, 138 estados, 137 Estados identica ca o, 137 Estere otipos, 89 Estruturas, 695 Estruturas aninhadas, 697 Etapas de desenvolvimento de um programa, 109 Evento, 79 Eventos, 133, 134 Exce co es, 79 exce co es-padr ao, 476 Excess oes, 471 Exemplos de objetos, 62 explicit, 463 express ao? a ca -verdadeira : a ca o-falsa;, 669 Extens ao, 113 eXtreme Programming, 104 FAQ, 728 fase de pr e-processamento, 637 FIFO, 578 for(in cio;teste;incremento) a ca o;, 669 Framework, 174 framework, 174 Friend, 379 friend, 78 Fun ca o main(), 675 Fun co es, 73, 675 Fun co es friend, 382 Fun co es gen ericas, 598 Fun co es objetos, 613 Fun co es recursivas, 677 Fun co es template, 492 Andr e Duarte Bueno

754 Gabaritos, 489, 505 Generaliza ca o, 112 Generaliza ca o e heran ca, 128 get(), 442 GNU, 53 GNU//Linux, 53 GNU/Linux (Unix), 151 GPL, 52 heap, 477 Heapsort, 604 Heran ca, 74, 335 Heran ca m ultipla, 75, 345, 355 heran ca m ultipla, 127 Heran ca m ultipla virtual, 350 Heran ca simples, 355 Heran cas, 157 heran cas, 127, 157 Heran cas - identica ca o, 127 Hereditariedade, 74 Hist oria de C++, 181 HOWTO, 725 IDE, 151 Identidade, 76 Identica ca o de agrega co es, 125 Identica ca o de associa co es, 122 Identica ca o de classes, 119 Identica ca o de composi co es, 125 Identica ca o de estados, 137 Identica ca o de eventos e mensagens, 133 Identica ca o de heran cas, 127 Identica ca o de pacotes, 116 Identicadores, 193, 197 if, 666 if......else if......else if......else, 667 if.....else, 666 Implementa ca o, 160 Implementa ca o do programa, 106 Impressora, 441 Inclus ao, 113 Inclus ao de arquivos, 637 Inicializa ca o dos atributos, 316 Inst ancia, 63, 76 Instru co es de guarda, 642 Interface, 77, 128, 148 interface, 54, 117 Inverter, 600 Itera ca o, 132, 145 Iteradores, 547 Programa ca o Orientada a Objeto com C++ Iterators, 547 kdevelop, 154 kernel num erico, 55

INDICE REMISSIVO

Liga ca o din amica, 78 Liga ca o est atica, 78 linguagem de modelagem unicada, 85 linha de comando, 55 Linkar, 185 Links, 725 Linux, 53 Literais, 194 locale, 422 Lvalues, 196 M etodos, 73, 267 m etodos, 121, 156 M etodos - identica ca o, 121 M etodos const, 279 M etodos construtores, 313 M etodos de convers ao, 462 M etodos destrutores, 314 M etodos est aticos, 282, 361 M etodos friend, 381 M etodos inline, 284 M etodos n ao virtuais, 361 M etodos normais, 276, 361 M etodos virtuais, 363 M etodos virtuais puros, 367 m odulos, 116 Mac OS System X, 151 Macros, 641 Macros pr e-denidas, 641 Manuten ca o, 172 Manuten ca o do programa, 106 Matem aticos, 603 mecanismo de recupera ca o, 56 Mensagens, 133, 134 Mesclar, 600 Metodologia, 162 Misturar, 600 Modelagem, 81 Modelagem Orientada a Objeto, 49, 81 Modelagem orientada a objeto, 84 Modelo, 81 modelo, 133, 156 Modelo baseado em prototipagem, 102 Modelo de objetos, 119 Modelo din amico, 133 Andr e Duarte Bueno

INDICE REMISSIVO Modelo espiral, 102 Modelo funcional, 142 Modelo incremental, 102 Modelo iterativo, 102 Modelo RAD, 102 Modelo RUP, 103 Modelo selecionado, 105 Modelo sequencial linear, 101 Modelo TMO, 103 Modelo XP, 104 modelos, 101 Modicadores de acesso, 650 modo gr aco, 57 modo texto, 56 Modularidade, 79 Namespace, 241 Necessidade de convers ao, 460 new, 300, 481 Nome dos objetos, 197 Nomes, 193 Nomes de classe, 77 NonVirtual Interface, 253 Novidades e vantagens de C++, 183 NVI, 253 O que e engenharia de software, 99 Objeto, 63 objetos, 61 Objetos din amicos, 299 Objetos fun co es, 613 Objetos identica ca o, 130 Oculta ca o, 70 Open Source Initiative, 53 Operador condicional, 660 Operador de resolu ca o de escopo, 662 Operador decremento, 660 Operador delete, 662 Operador incremento, 660 Operador m odulo, 661 Operador new, 662 Operador size t, 234, 662 Operador sizeof, 662 Operador typedef, 662 Operador v rgula, 661 Operadores, 194, 655 Operadores aritim eticos, 656 Operadores bits, 659 Operadores compostos, 657 Operadores de atribui ca o, 657 Programa ca o Orientada a Objeto com C++

755 Operadores l ogicos, 658 Operadores relacionais, 657 Operadores sobrecarregados, 386 Ordem de cria ca o, 351 Ordem de cria ca o e destrui ca o dos objetos, 325 Ordem de destrui ca o, 351 Ordena ca o, 601 otimiza co es, 157 Pacotes, 79 pair, 583 Palavras chaves, 193 Palavras chaves do C++, 196 Par ametros por c opia, 272 Par ametros por ponteiro, 273 Par ametros por refer encia, 272 Persist encia, 76 Pesquisar, 600 Pilhas, 604 Plataforma de programa ca o, 149 Plataformas, 147 plataformas, 149 Polimorsmo, 75, 361, 365 Ponteiro de fun ca o, 689 Ponteiro para m etodos, 690 Ponteiro para ponteiro, 685 Ponteiro this, 302 Ponteiro void, 684 Ponteiros, 78, 297, 683 Ponteiros const, 303 Ponteiros para const, 303 POO, 61, 64, 156 Preced encia dos operadores, 656 Preenchimento, 598 Proler, 185 programa, 51 Programa ca o em grande escala, 175 Programa ca o estruturada, 63 Programa ca o orientada a objeto, 64 Programas, 51 Projeto do sistema, 105, 147 Projeto orientado a objeto, 106, 156 Propriedades, 73 prot otipo, 117 Prot otipo catch, 472 Prot otipo classe template, 495 Prot otipo const cast, 466 Prot otipo construtor, 314 Prot otipo convers oes, 459 Prot otipo destrutor, 314 Andr e Duarte Bueno

756 Prot otipo dynamic cast, 465, 466 Prot otipo exce co es, 476 Prot otipo fun co es template, 490 Prot otipo heran ca m ultipla, 345 Prot otipo heran ca m ultipla virtual, 350 Prot otipo m etodo convers ao, 462 Prot otipo para construtores e destrutores, 314 Prot otipo para declarar e denir atributos, 259 Prot otipo para declarar e denir classes, 249 Prot otipo para declarar e denir m etodos, 268 Prot otipo para enumera co es, 227, 700 Prot otipo para friend, 380 Prot otipo para heran ca, 335 Prot otipo para heran ca m ultipla, 345 Prot otipo para templates, 490 Prot otipo refer encias, 305 Prot otipo reinterpret cast, 466 Prot otipo sizeof, 234 Prot otipo sobrecarga de operador, 386, 394, 397 Prot otipo static cast, 464 Prot otipo template e argumentos pr e-denidos, 498 Prot otipo throw, 472 Prot otipo try, 472 Prot otipos de sobrecarga, 394 Prot otipos para convers oes, 459 Prot otipo struct, 224, 695 Protocolos, 77, 147, 148 Prototipo delete, 301 Prototipo new, 300 pstream.h, 736 put(), 442 Rapid Application Development, 102 Rational Unied Process, 103 read(), 434 Realiza ca o, 130 Recursos, 147 Redeclara ca o, 340 Redirecionamento, 437 Refer encias, 78, 297, 304 refer encias, 297 Refer encias e dynamic cast, 466 reinterpret cast, 466 Remo ca o, 599 Responsabilidades, 77 Restri co es, 130 Retorno de um m etodo, 271 Reusabilidade, 172 Programa ca o Orientada a Objeto com C++ Reuso, 172 reuso de classes, 172 reuso de m etodos, 173 Revistas, 734 robustes de c odigo, 253 RUP, 103

INDICE REMISSIVO

S mbolos, 193 Sa da aux liar, 441 seekg(), seekp(), 439 Sele ca o de bibliotecas externas, 150 Sequ encia de controle, 476 Sinergia, 79 Sintaxe de Cpp, 193 sizeof, 234, 355 Sobrecarga de M etodos, 293 sobrecarga de m etodos, 78 Sobrecarga de operador, 385 sobrecarga de operador, 78 Sobrecarga de operador como fun ca o friend, 387 Sobrecarga de operador como m etodo membro da classe, 388 software, 51 Software Livre, 52 software livre, 52 Software propriet ario, 52 softwares, 51 static, 652 static cast, 464 std, 242 STL, 539 stl, 541 strings de C++, 447 Superclasse, 77 switch....case, 667 Tecnologia de Modelagem de Objetos, 103 tellg(),tellp(), 439 Templates, 79, 489, 505 Teste, 161 Teste de Software, 161 Teste e depura ca o, 106 throw, 474 Tipica ca o, 76, 237 Tipos, 215 Tipos de programa ca o em C++, 184 Tipos denidos em bibliotecas externas, 228 Tipos derivados, 195 Tipos do usu ario, 223 Andr e Duarte Bueno

INDICE REMISSIVO Tipos e intervalos, 217 Tipos param etricos, 494, 511 Tipos pr e-denidos, 195 Transforma ca o, 602 Trocas, 599 try, 474 Tutoriais, 728 Typedefs, 546 typeid, 236 umbrello, 94 UML, 85, 726 Uni oes, 698 union, 698 Uso de tipos pr e-denidos de C++, 215 Vari aveis, 73 Vis ao desorganizada, 64 Vis ao orientada a objeto, 64 Vis oes da UML, 85 Visual Paradigm, 96 volatile, 651 while (teste)instru ca o;;, 670 Windows, 151 write(), 434 XP, 104

757

Programa ca o Orientada a Objeto com C++

Andr e Duarte Bueno

S-ar putea să vă placă și