Você está na página 1de 101

Linguagem C++

Introduo linguagem C++


A linguagem C++ uma extenso da linguagem C, uma vez que permite toda a eficincia e flexibilidade desta, acrescidas de potencialidades que permitem a programao orientada por objectos.

A linguagem C++ considerada hbrida, pois permite tirar partido do paradigma de orientao por objecto ou ser tratada como uma linguagem procedimental.

A melhor forma de aprender a linguagem C++ utiliz-la!

Programao 2

39

Organizao de um programa
Um programa em C++ constitudo por um conjunto de: Definies e declaraes e instrues. Uma definio fornece a informao que permite ao compilador reservar memria para objectos (ou variveis) ou gerar o cdigo para as funes. Uma declarao apresenta nomes de entidades e os seus tipos sem necessariamente definir (alocar) um objecto ou funo. As instrues permitem o acesso a entidades definidas: acesso a variveis e objectos, invocao de funes e mtodos.

Podendo ser organizadas em mltiplos ficheiros. /* O meu primeiro programa */ #include<iostream> using namespace std; void main() { cout << Ola mundo << endl; }

Programao 2

40

Visual C++ 2008 Express Edition


O Visual Studio uma ferramenta de software categorizado como um Ambiente Integrado de desenvolvimento (do ingls, IDE). As principais caractersticas desta ferramenta so: Edio de cdigo Iluminao de palavras reservadas Acesso imediato lista de membros dos objectos (CTRL-space) Depurador (debugger) integrado E outras: Suporte para diversas linguagens Edio de recursos visuais Trabalho cooperativo

Programao 2

41

Solues e projectos

A organizao de itens no Visual Studio .NET realizada por solues. As solues permitem a utilizao de outros contentores para a gesto eficiente do desenvolvimento de aplicaes: Solues: o Projectos: Itens: Ficheiros Directorias

Criao de projectos
A criao de um projecto novo acarreta a criao de uma soluo nova: Programao 2 42

File | New | Project Podem, no entanto, ser criadas solues vazias e posteriormente adicionar um ou mais projectos.

Tipos de projectos e modelos


Projectos Visual C++ o General Empty Project

O novo projecto ficar numa directoria com o seu nome.

Programao 2

43

Abertura e encerramento de solues


Abertura de uma soluo existente: File | Open | Project / Solution Deve procurar-se o ficheiro com extenso .sln Encerramento de uma soluo: File | Close Solution

Explorador da soluo (Solution Explorer)


Permite visualizar as solues, os projectos das solues e os itens atribudos aos projectos

Programao 2

44

Vista de classes (Class View)


Permite visualizar as entidades lgicas dos projectos (espaos de nomes, classes, mtodos, etc).

Legenda dos smbolos:

Programao 2

45

Gesto de itens
Os Itens (ficheiros de cdigo) podem ser adicionados no menu File, no menu Project ou carregando com o boto direito do rato no explorador da soluo.

Programao 2

46

Debugger
O debugger permite analisar a execuo do programa executando-o em passos e observando o contedo das variveis. Para que o programa pare numa determinada linha devese colocar um ponto de quebra (breakpoint). O inicio do programa em modo debug dado na opo de menu Debug | Start Debugging. Para executar normalmente deve-se escolher a opo Debug | Start Without Debugging As instrues podem agora ser executadas passo a passo com a barra. As variveis podem ser observadas na janela autos ou locals.

Programao 2

47

Principais diferenas entre a linguagem C e C++


Comentrios de linha: /* */ // O nome de um enumerado considerado um tipo de dados.
enum semana {segunda, terca, quarta, quinta, sexta, sbado, domingo};

typedef enum {segunda, terca, quarta, quinta, sexta, sbado, domingo} semana;

no havendo necessidade em defini-lo.

O nome de uma classe e estrutura considerado um tipo de dados. struct registo{ int codigo; char *nome; unsigned int idade; } Declaraes dentro de blocos ou aps instrues for(int n=0;n<10;n++)

Programao 2

48

Operador de contexto (scope) :: int var; void func() { int var; ::var=0; } Especificador const permite oferecendo maior proteco. const int a=1; Converso de tipos explicita. Para alm da converso (cast) o nome de um tipo predefinido ou definido pelo programador pode ser utilizado como uma funo para converso de tipos. int i=10; float r=float(i); bloquear varveis,

Sobrecarga (overloading) de funes, ou seja, poder ter, no mesmo contexto, funes com o mesmo nome, mas diferenciveis pelo nmero ou tipo dos parmetros.

Programao 2

49

Valores de parmetros por omisso (default). Passagem de parmetros por referncia void incrementa(int &valor) { valor++; } Especificador inline. Permite a substituio no local de chamada de uma funo pelo seu cdigo. Operadores new e delete. int *i; i=(int*) malloc(sizeof(int)*50) int *i=new int[50];

Programao 2

50

Declaraes e definies
Um programa em C++ uma sequncia de declaraes e definies. A definio de main indica o incio da execuo.

Qualquer identificador antes de ser utilizado, tem que ser declarado. Para isso, necessrio indicar ao compilador o seu tipo.

O tipo de uma entidade indica ao compilador de que entidade se trata. Definies: char c; int conta=1; char *nome=Vanessa; const double pi=3.1415926535897932385; int quadrado(int x){return (x*x);} Declaraes: int dobro(int); extern int erro;

Programao 2

51

Visibilidade ou contexto (scope)


O nome resultante de uma declarao apenas visvel desde o ponto que definido at ao fim do bloco em que definido. int x; void f() { int x; x=1; { int x; x=2; } x=3; } int *p=&x; // global // local, esconde x // esconde x

// usa x global

Para aceder a uma varivel global escondida deve utilizarse o operador ::. int x; Void f2() { int x=1; ::x=2; }

Tempo de vida
Quando no especificado o contrrio pelo programador, uma entidade criada quando definida, e destruda quando fica fora de contexto.

O modificador static permite que uma entidade dure at ao fim do programa. Programao 2 52

int a=1; void f() { int b=1; static int c=a; cout << a= << a++ << b= << b++ << c= << c << \n; c=c+2; } void main() { while(a<4) f(); }

Programao 2

53

Constantes
As constantes so todos os valores fixos que podem ser colocados ao longo de um programa.

Inteiros

123 1234567l (ou L) 12345u (U, ul ou UL)

int long unsigned

Vrgula flutuante

123.4 1e-2 123.4f 1e-2l

double double float long double

Octal

037

31

Hexadecimal

0x1f 0xFUL Programao 2

31 15 54

Caracteres

Os caracteres em C++ so armazenados internamente como nmeros, a sua interpretao que os torna caracteres. x 0 31 48

Alguns caracteres so especiais, por no serem acessveis pelo teclado, e tm que ser escritos atravs de sequncias de escape. Apesar da sua representao serem 2 caracteres, o valor representado apenas 1. Tabela de sequncias de escape \a alert \b backspace \f formfeed \n newline \r carriage return \t horizontal tab \v vertical tab \\ backslash (barra) \? ? \ \ \ooo Nmero octal (ooo) \xhh Nmero Hexadecimal (hh)

Programao 2

55

O caracter \0

Existe ainda um caracter especial, o \0, que representa o caracter nulo e corresponte ao inteiro 0. utilizado para marcar o fim de uma string.

Expresses constantes
possvel definir um identificador para uma expresso constante. A sua utilizao implica a substituio literal do valor definido. #define MAXLINE 1000 char line[MAXLINE];

Entidades constantes
const int a=5; const char *s;

Programao 2

56

Constantes String
Ou tambm designadas apenas por strings so uma cadeia de 0 ou mais caracteres, envolvidos entre aspas Sou uma string Tu es o que? Tecnicamente uma string um array de caracteres, com o caracter \0 a termin-la. Por conseguinte, todas as string ocupam mais 1 caracter do o nmero de caracteres necessrios.

Ateno: x e x so entidades completamente distintas.

Constantes enumeradas
Uma enumerao uma lista de valores inteiros constantes, aos quais atribudo um identificador. enum booleano {FALSO, VERDADEIRO};

O identificador FALSO vale 0 e VERDADEIRO vale 1.


enum meses {JAN=1, FEV, MAR, , NOV, DEZ};

Nota: Os elementos da enumerao so efectivamente identificadores, no strings.

Programao 2

57

Tipos de dados
Tipos fundamentais
char int float double void
Modificadores de Tipos

signed unsigned long short


Tipos existentes em C++
Tipo char unsigned char signed char int unsigned int signed int short int unsigned short int signed short int long int signed long int unsigned long int float double long double Tamanho em bits 8 8 8 32 32 32 16 16 16 32 32 32 32 64 80 Intervalo -128 a 127 0 a 255 O mesmo que char -2.147.483.648 a 2.147.483.647 0 a 4.294.967.295 O mesmo que int -32768 a 32767 0 a 65.535 o mesmo que short int -2.147.483.648 a 2.147.483.647 O mesmo que long int 0 a 4.294.967.295 3.402823466e+38 1.7976931348623158e+308 1.189731495357231765e+4932

Programao 2

58

Apontadores
Para um tipo T, T* representa o tipo de um apontador para T. Assim, variveis do tipo T* podem armazenar endereos para uma varivel do tipo T. int *pi; char **cpp;

Para se aceder ao endereo de uma varivel utilizado o operador &. int a=5; int *pi; pi=&a; *pi=10;

Arrays
Sendo T um tipo, T[tam] o tipo de um array de tam elementos de tipo T. Os elementos so acedidos de 0 a tam-1. float v[3]; int a[2][5]; int a[]={1, 2, 3, 4, 5}; char str[]=uma string;

Apontadores e arrays
Os arrays esto estreitamente relacionados com apontadores. O nome de um array pode ser tomado como um apontador que representa o endereo do primeiro elemento do array;

Programao 2

59

Estruturas
As estruturas permitem agregar num tipo vrias entidades de diversos tipos. struct morada{ char *nome; char *rua; int numero; char *cidade; int codigoPostal; }; O acesso aos constituintes de uma estrutura feito atravs do operador (.) aplicado s variveis da estrutura ou (->) quando aplicado a apontadores da estrutura. morada m; m.nome=Patricia Marques; m.numero=21;

Programao 2

60

Expresses e instrues
Operadores Operadores Aritmticos
+ * / % Soma Subtrao Multiplicao Diviso Resto da Diviso (modulus)

20-2*3 14 26 % 5 1

Operadores Relacionais
> >= < <= == != Maior Maior ou igual Menor Menor ou igual Igual a Diferente

Estes operadores tm prioridade inferior aos aritmticos. Expresses como: i < lim -1 so equivalentes. e i < (lim-1)

Programao 2

61

Operadores Lgicos
&& || ! e ou no

A prioridade de && maior do que ||, por sua vez, a prioridade de ambos inferior aos operadores aritmticos e lgicos. i < lim -1 && c != EOF equivalente a (i < (lim -1)) && (c != EOF)

Por definio o valor de uma expresso relacional ou lgica 1 se a expresso for verdadeira e 0 se for falsa. 10 > 3 1 5 != 5 || 7<=10 1

Programao 2

62

Converses de tipo Converses implcitas


necessrio ter ateno a utilizao de operadores com tipo diferentes. Sempre que um operador tenha operandos de tipos diferentes o tipo mais limitado convertido para o de maior capacidade. float + int float Em caso de atribuio para um tipo mais restrito, apesar de no ser ilegal, pode haver perda de informao e um aviso por parte do compilador. int a; int f=5.2; a=f;

Converses explicitas
Utiliza-se o casting (moldagem): char c=10; int x=(int)c; ou int x=int(c); No caso de objectos, para detectar uma converso bem sucedida deve utilizar-se, o dynamic_cast. A *a=new A; B *b=dynamic_cast<B*>(a); if(b!=0)

Programao 2

63

Operadores de incremento e decremento


++ -incrementa decrementa

Ambos os operadores podem surgir em duas formas: ++a a++ prefixado posfixado

Em ambas as formas o operando incrementado, mas na primeira o incremento feito antes de o operador ser utilizado, na segunda, o operando utilizado e depois incrementado. n=5; x=n++; x 5 n 6 n=5; x=++n; x 6 n 6

Operadores sobre bits


Apenas podem ser utilizados em tipos inteiros: char, short, int, long. & Programao 2 e 64

| ^ << >> ~ n & 0177

ou ou exclusivo deslocamento para a esquerda deslocamento para a direita complemento de 1

Coloca a zero todos os bits de n excepto os 7 menos significativos. n=231; (11100111) n & 0177 103 (01100111)

No confundir & e | com && e ||. 1 & 2 0 1 && 2 1

Operadores de Atribuio e expresses


Um expresso um conjunto de operadores e operandos da qual resulta um valor. Os operandos podem ser constantes ou variveis.

Uma expresso pode ser utilizada em qualquer parte do programa, sendo, normalmente atribuda a uma varivel, por questes de comodidade e eficincia. variavel = expresso; Programao 2 65

a=50;

Expresses como a=a+5, utilizando a notao a+=5.

podem

ser

simplificadas,

Esta simplificao pode se utilizada em quase todos os operadores binrios: + * / % << >> & ^ |

Programao 2

66

Exemplos: a=10; 2+3+7*5 (5/2+8*10) a*5-a*2 a++*7+3 b=5 10 40 82 30 73 5 1 1 0 20

a>0 && a<20 a && b a & b a+=9

(sendo a=10)

Expresso condicional

A expresso condicional, permite decidir entre o resultado de duas expresses com base numa condio. expr1 ? expr2 : expr3 a=5; a<0 ? -1 : 1 z= (a>b) ? a : b

1 o maior

Programao 2

67

Resumo dos operadores


Tabela de operadores ordenados por precedncia. Smbolo Descrio Aplicao
:: -> [] () () sizeof ++ -~ ! + & * new delete () * / % + << >> < <= > >= == != & ^ | && || ?: = (operadores de atribuio) , Resoluo de contexto Seleco Indexao chamada a funo construo de objecto dimenso de tipo ps ou pr incremento ps ou pr decremento complemento bit a bit negao lgica menos unrio mais unrio endereo de valor apontado por alocao libertao cast multiplicao diviso resto da diviso adio subtrao deslocar para a esq. deslocar para a dir. menor menor ou igual maior maior ou igual igualdade desigualdade AND bit a bit XOR bit a bit OR bit a bit AND lgico OR lgico operador condicional atribuio sequncia nome::membro apontador->membro apontador[exp] exp(lista_exp) tipo (lista_exp) sizeof(tipo) lvalor++ ou ++lvalor lvalor-- ou --lvalor ~exp !exp -exp +exp &lvalor *exp new tipo delete apontador (tipo)exp exp * exp exp / exp exp % exp exp + exp exp - exp lvalor << exp lvalor >> exp exp < exp exp <= exp exp > exp exp >=exp exp == exp exp != exp exp & exp exp ^ exp exp | exp exp && exp exp || exp exp ? exp : exp lvalor=exp exp, exp

Programao 2

68

Controle de Fluxo
As instrues de controle de fluxo permitem especificar por que ordem so executados os clculos.

Instrues e blocos

Uma expresso quando terminada por um ; torna-se uma instruo: x = 0; i++; f();

Um bloco um conjunto de instrues agrupadas entre chavetas ({ }), de tal forma que so equivalentes a uma nica instruo.

Programao 2

69

if-else
utilizado para exprimir execuo de instrues com base na avaliao de uma condio. if(expressao) instrucao1 else instrucao2

A parte do else opcional.

A expressao avaliada, se for diferente de 0, instrucao1 executado, se for 0, executado instrucao2.

O else sempre associado ao if mais prximo. if(n>0) if(a>b) z=a; else z=b;

Em caso de dvidas utilizar blocos.

Programao 2

70

Else-if
Utilizada em caso de decises mltiplas. if(expressao) instrucao else if(expressao) instrucao else instrucao

switch
Utilizado em decises mltiplas em que uma expresso comparada com um valor constante. switch(expressao){ case expr-const1: instrucoes1 case expr-const2: instrucoes2 default: instrucoes }

A instruo break fora a sada para fora do switch.

Programao 2

71

Ciclos - while e for


So instrues que permitem a repetio condicionada de blocos. while(expressao) instrucao

instrucao executada enquanto expressao for verdadeira (no nula). for(expr1; expr2; expr3) instrucao

que significa: executa expr1 (inicializao), executa instrucao, enquanto expr2 for verdadeira (no nula), no fim de cada iterao executa expr3.

A instruo break pode ser usada para interromper incondicionalmente um ciclo.

O ciclo for adequado para situaes em que exista uma inicializao e um incremento inerente em cada iterao.

do-while
do instrucao Programao 2 72

while(expressao);

instrucao executada pelo menos uma vez, se a expressao for verdadeira executada de novo.

break e continue

O break permite a sada prematura de um ciclo ou bloco.

O continue permite que um ciclo passe para a seguinte iterao. Nos ciclos while e do-while, a condio executada imediatamente a seguir, enquanto que no ciclo for a instruo de incremento ainda executada.

Programao 2

73

Funes
Uma funo pode ser definida da seguinte maneira: tipo-de-retorno nome-da-funcao(argumentos) { declaracoes e instrucoes }

Quando o tipo de retorno omitido, o tipo int assumido.

A interaco com uma funo feita atravs dos seus argumentos, do tipo de retorno e das variveis globais.

A instruo return utilizada para devolver um valor da funo chamada para quem a chamou. Qualquer expresso pode ser devolvida: return expressao;

Programao 2

74

Quando se pretender uma funo que no devolva valor, void dever ser utilizado como tipo de retorno. Nesse caso o return no dever ter qualquer parmetro.

Uma funo pode ter mais do que um return, desde que em ramos de execuo diferentes. int func(char c) { char a=c; if(c==a) return 1; else return 0; } Sempre que uma funo chamada feita uma cpia das suas variveis locais e dos seus argumentos, por essa razo nunca se deve devolver o apontador de uma varivel local.

Prottipo de uma funo


Uma funo para ser utilizada deve estar declarada ou pela sua prpria definio ou pelo seu prottipo. double sqrt(double);

Programao 2

75

Passagem de argumentos
Em C++, possvel passar argumentos por valor e por referncia. void f(int val, int &ref) { val++; ref++; } int i=1, j=1; f(i, j); possvel tambm bloquear parmetros das funes com o especificador const. void f(const float &f) { }

Programao 2

76

Sobrecarga de funes
Em C++ possvel definir funes que realizam operaes diferentes com o mesmo nome. Esta vantagem permite que sejam realizadas tarefas idnticas com objectos diferentes, utilizando o mesmo nome. void print(int); void print(char *);

Argumentos por omisso


Numa funo possvel omitir sequencialmente a partir do ltimo. os argumentos

void print(int num, int base=10); print(50); print(40, 16);

Estruturas
Permitem agrupar dados de tipos diferentes. struct Estrutura{ char c; int i; }; struct Estrutura e; e.c=10;

Programao 2

77

Classes em C++
Uma class define um novo tipo de dados. class nome_identificador{ private: dados e mtodos; // dados e mtodos no podem ser acedidos directamente protected: dados e mtodos; // dados e mtodos s podem ser acedidos por classes derivadas public: dados e mtodos; // dados e mtodos podem ser acedidos directamente };

Uma definio de classe em todo semelhante definio de uma struct. Os dados so definidos como campos de uma struct ou variveis. Os mtodos so definidos da mesma forma que funes.

Os dados e os mtodos so acedidos e invocados, respectivamente, atravs do operador . (ponto) ou -> no caso de o objecto ser um apontador. Os atributos devem ser privados para evitar alteraes que tornem os objectos inconsistentes. Devendo criar-se mtodos pblicos para o seu acesso e modificao (getters e setters). Por exemplo, para acertar um relgio analgico utiliza-se o regulador (mtodo) para que as horas e os minutos (atributos) no fiquem inconsistentes. Programao 2 78

Construtores
Os construtores permitem a inicializao automtica das instncias. permitida a definio de vrios construtores de forma a disponibilizar um leque de inicializaes possveis. O construtor considerado um mtodo especial, cujo nome igual ao nome da classe.

Um construtor invocado automaticamente quando definido um objecto de uma classe.

Existem 4 categorias de construtores: Construtor por omisso; Construtor de cpia; Construtor de converso; Todos os outros

Construtor por omisso


um construtor que no possui parmetros. O compilador gera este construtor automaticamente, salvo sejam definidos outros pelo utilizador.

Programao 2

79

Construtor de cpia
O construtor de cpia aquele que tem exactamente um parmetro cujo tipo a prpria classe. invocado sempre que uma instncia precisa de ser copiada durante a execuo normal do programa. O compilador gera um construtor deste tipo automaticamente, em que feita uma cpia dos valores dos membros. Este construtor invocado programa em situaes como: automaticamente pelo

Criao de instncias a partir de outras da mesma classe; Retorno de instncias por valor em funes; Na passagem de parmetros por valor.

Programao 2

80

Construtor de converso
Um construtor de converso aquele que tem exactamente um parmetro e no um construtor de cpia. Estes construtores no so gerados automaticamente. O seu objectivo converter o parmetro num objecto da classe em questo. Sempre que se cria um construtor de converso est-se, implicitamente, a criar uma converso do tipo de dados do argumento para o tipo de dados da classe. invocado automaticamente: Criao de instncias a partir de outros tipos; Retorno de instncias por valor em funes; Na passagem de parmetros por valor (a atribuio um caso, como se ver mais frente).

Programao 2

81

Arrays e apontadores de objectos


A criao de vectores (arrays) de objectos s possvel se o construtor por defeito estiver definido. class C { int x; public: c(){ x=0; } c(int i){ x=i; } }; C vecC[10]; tambm possvel definir apontadores para instncias. Tal como os apontadores de tipos simples, os apontadores de instncias podem referenciar objectos j existentes ou serem alocados dinamicamente. C C C C a; *p0=&a; *p1=new C; *p2=new C(5);

C *ap=new C[10];

As instncias libertadas.

alocadas devem

ser

obrigatoriamente

Programao 2

82

Auto-referncia nas classes


No cdigo de definio dos mtodos de uma classe, encontra-se sempre disponvel um apontador especial que referencia o objecto para onde foi enviada a mensagem do mtodo que est a ser executado.

Este apontador designado por this, e utilizado em objectos que se auto referenciam ou para retirar ambiguidades.

Quando um mtodo de uma classe invocado dentro de outro mtodo da mesma classe, o apontador this est implcito.

Programao 2

83

Membros constantes
Quer os atributos, quer os mtodos podem ser definidos como constantes. Os atributos so inicializados na altura da construo do objecto. Os mtodos declarados como tal, -lhes retirada a capacidade de modificar os atributos do objecto.

1. Um mtodo declarado como constante s pode invocar no seu corpo mtodos constantes; 2. Um mtodo no constante s pode ser invocado por objectos no constantes, enquanto que, um mtodo constante pode ser invocado por um objecto constante e no constante.

Programao 2

84

Membros constantes
Os membros constantes devem ser utilizados sempre que se pretenda efectuar proteco de dados. class Obj{ const int c; int x; public: Obj(int a, int r): c(r){ x=a; } int getX() const{ return(x); } void setX(int a){ x=a; } }; const Obj oc(5, 10); Obj o(10, 20); o.getX() oc.getX() // Vlido // Vlido

o.SetX(5) // Vlido oc.SetX(5) // no vlido

Programao 2

85

Sobrecarga de operadores (Overloading)


A sobrecarga de operadores permite sobrepor a utilizao normal dos operadores nas classes criadas pelo utilizador.

tipo operator<operador>(argumentos);
A grande vantagem poder utilizar os operadores em instncias da mesma forma que seriam utilizados nos tipos predefinidos.

Para os operadores ++ e --

tipo operator++(); tipo operator--();


significa a verso prefixada

tipo operator++(int); tipo operator--(int);


significa a verso posfixada

Programao 2

86

Associaes simples e Agregao de classes


Em C++, as associaes simples so, tipicamente, representadas por apontadores membros, enquanto que a agregao , tipicamente, representada por instncias membros, podendo, no entanto, ser tambm representada por apontadores. Na associao simples, tipicamente, os objectos associados existem mesmo antes do objecto que associa ser criado, no sendo destrudos quando o objecto que associa destrudo. Na agregao, tipicamente, os objectos agregados so criados e destrudos quando os objectos agregadores so criados e destrudos, respectivamente.
Associao simples 1-1
class A { int x; public : A() { x = 0; } }; class B { A* a; public: B() { a = NULL; } void setA(A* na) { a = na; } }; void main() { A* a = new A; B b; b.setA(a); delete a; }

Programao 2

87

Agregao de classes
Quando se definem objectos como membros de outros objectos, coloca-se a questo de como so criados os objectos agregados.
class A { int x; public : A() { x = 0; } }; class B { A a; public: B(){} }; void main() { B b; }

#include<iostream> using namespace std; class interna { int x; public: interna(int a){ x=a; } void print(){ cout << x << endl; } };

Programao 2

88

class externa { int y; interna x; interna z; public: externa(int a): x(20), z(-36), y(a) { } void print(){ cout << y << endl; } void print_x(){ x.print(); } void print_z(){ z.print(); } }; void main() { externa o(-12); interna i(25); o.print_x(); o.print_z(); o.print(); i.print(); }

Programao 2

89

Carro
Conduz

Pneu

Pessoa

#include<iostream> #include<string.h> using namespace std; class Pneu { char marca[50]; int diametro; public: Pneu(){ marca[0]='\0'; diametro=0; } Pneu(char *m, int d){ strcpy(marca, m); diametro=d; } void print() const{ cout << "Pneu: Marca: " << marca << ", Diametro: " << diametro << endl; } };

Programao 2

90

class Pessoa { char nome[50]; public: Pessoa(char *n){ strcpy(nome, n); } void print() const{ cout << "Pessoa: " << nome << endl; } }; class Carro { char marca[50]; char cor[50]; Pneu pneus[4]; Pessoa *condutor; public: Carro(char *m, char *c, char *mp, int d){ strcpy(marca, m); strcpy(cor, c); for(int i=0;i<4;i++) pneus[i]=Pneu(mp, d); condutor=0; } void definirCondutor(Pessoa *p){ condutor=p; } void print() const{ cout << "Carro: Marca: " << marca << ", Cor: " << cor << endl; cout << "Pneus: " << endl; for(int i=0;i<4;i++) pneus[i].print(); if(!condutor) cout << "No existe condutor" << endl; else condutor->print(); } };

Programao 2

91

void main() { Carro c("Porsche", "Amarelo", "Good Year", 17); c.print(); Pessoa p("Felisberto"); c.definirCondutor(&p); c.print(); }

Getters e Setters
Os atributos devem ser sempre privados utilizando-se mtodos para aceder e modificar os seus valores. Mesmo em atributos independentes, deve definir-se um par de mtodos getAtributo e setAtributo.

class Pessoa { char nome[50]; public: Pessoa(char *n){ strcpy(nome, n); } const char *getNome()const{ return(nome); } void setNome(char *n){ strcpy(nome, n); } };

Programao 2

92

Modelos (templates) de funes e classes


Um modelo ou template define uma famlia de funes ou classes, em que se torna possvel especificar um tipo varivel ou um valor varivel. Existem duas categorias de parmetros: Parmetros de tipo (typename X ou class X). Os parmetros de tipo podem ser substitudos por um qualquer tipo simples, combinado ou classe. Parmetros de valor (int I). Os parmetros de valor so tipicamente valores do tipo especificado. Template de Funes Permite definir uma famlia de funes Exemplo de template de funes: definio de uma famlia de funes soma() que permite somar valores de qualquer

tipo

template<class I> I soma(I a, I b){ I s=a+b; return(s); } Uma funo gerada a partir de um template de funes designada por funo template geralmente, a chamada de uma funo no requer que se explicite o valor dos seus argumentos template o compilador consegue inferir o tipo (I) atravs dos argumentos da funo Programao 2 93

Exemplo: float x=5.0f, y=1.5f, z; z=soma(x,y); Exemplo: double x=5.0, y=1.5, z; z=soma(x,y); Porm, nem sempre isso possvel quando no possvel inferir o tipo I atravs dos argumentos da funo, tem que se indicar explicitamente o significado desse tipo

Exemplos: void main(){ cout << soma(5.0,7.0) << endl; cout << soma(5,7) << endl; cout << soma<double>(5,7) << endl; Complexo x(2,5), y(3,8), Z; Z= soma(x,y); }

Programao 2

94

Template de Classes Permite definir uma classe de forma genrica, em que o tipo de alguns dos seus dados, e valores de que necessite, constem como parmetros na sua definio

Exemplo de template de classes: definio de uma lista

genrica, que permite

- conter qualquer tipo de objectos - ter a dimenso que se pretenda


template<class T, int MAX> class Lista{ T array[MAX]; int n; public: Lista(){n=0;} void inserir(T e){ if(n<MAX) array[n++]=e; } T remover(){ T r=0; if(n>0) r=array[--n]; return(r); } };

Este template de classes permite instanciar posteriormente vrias classes para diferentes tipos de objectos e dimenses Programao 2 95

- possvel, por exemplo, instanciar os seguintes objectos: Lista<int,50> lint; Lista<Pessoa,100> lpessoa;

Uma classe instanciada a partir de um template de classes designada por classe template

Lista um Template de Classes Lista<int,50> uma Classe Template (Instncia do template Lista) Lista<Pessoa,100> (Instncia do template Lista) lint um Lista<int,50>) uma Classe Template (Instncia (Instncia da da classe classe

objecto

lpessoa um objecto Lista<Pessoa,100>)

Quando instancimos a seguinte classe template: Lista<int,50> T foi associado ao tipo int, e MAX ao valor 50

o parmetro-tipo T tanto pode ser associado a um tipo elementar predefinido, como a uma classe ou a qualquer outro tipo de dados Programao 2 96

Um template pode ter um qualquer n de parmetros os parmetros-tipo podem ser identificados indistintamente pelos classificadores typename ou class Exempos: template <class T, int DIM> ... template<typename T, int N, float K> ...

Um template de classes, s por si, no gera cdigo O compilador s gera cdigo para as classes template por esse motivo, habitual colocar os templates de classes em ficheiros .h

Programao 2

97

Membros funo de um template de classes

Um mtodo de um template de classes , implicitamente, um template de funes por isso, quando um mtodo de um template de classes definido fora da sua classe, deve ser explicitamente declarado como template Exemplo: template<class T, int MAX> void Lista<T,MAX>::inserir(T e){ if(n<MAX) array[n++]=e; }

Programao 2

98

Biblioteca STL (Standard Template Library)


A STL disponibiliza um conjunto de classes e templates com diversas funcionalidades, entre as quais, strings, coleces e iteradores. Nas coleces podemos encontrar implementaes de: vectores, listas, conjuntos, dicionrios. Ver: http://www.cplusplus.com/reference/stl/ Utilizao de um conjunto (set)
Definio do template: template<class K> class set { public: class iterator{ }; }; Alm do template principal, est ainda definida uma classe que permite a iterao dos elementos. class iterator { public: K operator*() const; K* operator->() const; iterator operator++(int); iterator operator--(int); };

Programao 2

99

O template set tem os mtodos principais: template<class K> class set { public: pair<iterator, bool> insert(const K&); iterator find(const K&) const; size_type erase(const K&); void clear(); size_type size() const; bool empty() const; iterator begin(); iterator end(); };

A classe pair<iterator,bool> tem dois atributos pblicos: first e second, que permitem aceder, respectivamente, a um iterador e a um booleano. O booleano indica se o elemento foi inserido ou no. O iterador refere o elemento contido na coleco (o inserido ou o que j existia). Como a coleco set, ordena os elementos, necessria a definio de um operador de relao de ordem dos elementos, neste caso, o operador <.

Programao 2

100

Exemplo #include<iostream> #include<string> #include<set> using namespace std; class Pessoa { string nome; public: Pessoa(string n){ nome=n; } string getNome() const{ return(nome); } void setNome(string s) { nome=s; } bool operator<(const Pessoa &p) const{ return(nome<p.nome); } };

Programao 2

101

void main() { set<Pessoa> seto; set<Pessoa*> setp; Pessoa p("Jose"); Pessoa t("Carlos"); seto.insert(p); pair<set<Pessoa>::iterator, bool> r=seto.insert(p); seto.insert(t); Pessoa q("Jose"); seto.erase(q); Pessoa *pp=new Pessoa("Luis"); setp.insert(pp); set<Pessoa>::iterator i; for(i=seto.begin();i!=seto.end();i++){ cout << i->getNome() << endl; } set<Pessoa*>::iterator j; for(j=setp.begin();j!=setp.end();j++){ Pessoa *n=*j; cout << n->getNome() << endl; } }

Programao 2

102

Utilizao simplificada Para simplificar a utilizao do set, ir utilizar-se uma classe designada Coleccao.
template<class K> class Coleccao: public set<K> { public: bool insert(const K &c); K *find(const K &c); int size() const; void erase(const K &); //void clear(); //bool empty() const; //iterator begin(); //iterator end(); }; template<class K> bool Coleccao<K>::insert(const K &c) { pair<set<K>::iterator, bool> r=set<K>::insert(c); return(r.second); } template<class K> K *Coleccao<K>::find(const K &c) { K *r=0; set<K>::iterator i=set<K>::find(c); if(i!=set<K>::end()) r=i.operator ->(); return(r); } template<class K> int Coleccao<K>::size() const{ return((int)set<K>::size()); }

Programao 2

103

template<class K> void Coleccao<K>::erase(const K &c ) { set<K>::erase(c); }

void main() { Coleccao<Pessoa> seto; Coleccao<Pessoa*> setp; Pessoa p("Jose"); Pessoa t("Carlos"); seto.insert(p); bool r=seto.insert(p); seto.insert(t); Pessoa q("Jose"); seto.erase(q); Pessoa *pp=new Pessoa("Luis"); setp.insert(pp); Coleccao<Pessoa>::iterator i; for(i=seto.begin();i!=seto.end();i++){ cout << i->getNome() << endl; } Coleccao<Pessoa*>::iterator j; for(j=setp.begin();j!=setp.end();j++){ Pessoa *n=*j; cout << n->getNome() << endl; } }

Programao 2

104

Associaes e coleces
As associaes para N podem ser simplificadas utilizando coleces, uma vez que a gesto das operaes de insero, remoo, pesquisa, etc., podem ser centralizadas. Genericamente, existem duas formas de gerir as instncias que cada classe associa, e para isso, definem-se dois tipos de coleces: Por cpia. o Neste caso a classe que associa fica responsvel pela gesto das instncias que associa, devendo criar uma cpia na insero e libertar a instncia nas remoes. o Esta forma tem, no entanto, uma desvantagem: as alteraes das instncias dentro da coleco no se reflectem para as instncias que foram inseridas (originais) e vice-versa. o mais onerosa em termos de armazenamento. Tipicamente utilizada para guardar o repositrio original de instncias, uma nica vez.

Programao 2

105

Por apontador ou referncia. o Neste caso a classe que associa no fica responsvel pela gesto das instncias que associa. o Os apontadores originais so directamente inseridos na coleco, no sendo, por isso, efectuadas cpia das instncias que apontam. o Consequentemente, tambm no necessrio libertar as instncias apontadas nas remoes. o A entidade que utiliza a classe que deve ser responsvel pela gesto (alocao e libertao) das instncias. o possvel alterar directamente as instncias coleccionadas, uma vez que existem um apontador para o original. o mais vantajosa armazenamento. em termos de

o Tipicamente utilizada para guardar associaes que referenciam as instncias originais.

Programao 2

106

Associaes 1-N

Quando existe uma associao com vrios associados envolvidos conveniente recorrer criao de uma coleco desses elementos. A coleco pode ser implementada por diversas estruturas de dados, no entanto, convm que estejam definidas, pelo menos, as operaes: adicionar (add), remover (remove), procurar (find), entre outras que possam ser convenientes. A associao pode ser vista como:

Na realidade esta viso no deve ser representada no diagrama de classes, mas sim a anterior. Programao 2 107

Associaes N-N

A associao N-N pode ser vista como:

Mas na realidade esta viso no deve ser representada no diagrama de classes, mas sim a anterior.

Programao 2

108

Classes Associativas N-N

Pode ser convertido em:

Com coleces ficaria:

Programao 2

109

Incluso de ficheiros de cabealho (.h)


A incluso de ficheiros de cabealho pode tornar-se complexa, quando existe incluso mltipla de ficheiros. Algumas regras para a resoluo de conflitos: Nada de pnico com a quantidade de erros! Implementar uma classe por um par ficheiros: um .h e um cpp. Para a classe X, deve definir um X.h e um X.cpp. Escrever #pragma once no inicio dos ficheiro .h Implementar os mtodos no ficheiro .cpp. Evitar fazer o #includeX.h num ficheiro Y.h. Tentar sempre que possvel faz-lo no Y.cpp. Se num ficheiro Y.h apenas existirem declaraes de apontadores de instncias de uma classe X, deve apenas efectuar-se a declarao em avano de X: class X; Em incluses circulares X Y, a que tipicamente correspondem agregaes, a classe que agrega deve fazer um include e a classe agregada deve fazer uma declarao em avano. Os seguintes erros de compilao: P.ex.: syntax error : missing ';' before '* P.ex.: missing storage-class or type specifiers Normalmente, implicam a remoo de um include e a colocao de uma declarao em avano.

Programao 2

110

Referncias
As referncias so nomes alternativos para objectos. So obrigatoriamente inicializadas e referenciam o valor contido na varivel que inicializou a referncia. Basicamente uma referncia um endereo, simplesmente, torna-se desnecessria a utilizao do operador * (valor apontado por). int a; int &r=a; r=5; // efectivamente altera a &r // devolve o endereo de a Em parmetros de funes e mtodos: Neste caso, os parmetros com referncias iro assumir as variveis que se colocam na chamada da funo. Por serem referncias, os parmetros passados na invocao tm que ser obrigatoriamente variveis. void troca(int &a, int &b); troca(x, y); // os parmetros devem ser variveis

Programao 2

111

Referncias
No retorno de funes e mtodos: A utilizao de referncias no retorno de funes particularmente importante para ser possvel a modificao do valor devolvido no exterior da funo. Por exemplo, a possibilidade de colocar essa funo esquerda de uma atribuio (l-value). O valor retornado na funo no pode ser uma varivel local da funo nem pode ser constante.
#include<iostream> using namespace std; class Numero { int a; public: Numero(int x){ a=x; } int &altera(){ return(a); } void print() const{ cout << a << endl; } }; void main() { Numero a(10); a.print(); a.altera()=20; a.print(); }

Programao 2

112

Herana
O conceito de herana permite relacionar classes de forma hierrquica. Assim, todas as classes descendentes de uma outra classe herdam todas as variveis e mtodos, podendo ser acrescidas de mais variveis mtodos.

Subclasses - Classes descendentes. Superclasses - Classes ascendentes.


Uma classe pode ser derivada duma outra atravs da construo: class classe_derivada: public classe_base { ... };

Programao 2

113

Acrscimo e substituio de mtodos


Quando uma classe herdada possvel acrescentar novos mtodos classe derivada. Se se definir na classe derivada um mtodo com o mesmo nome da classe base, o mtodo da classe base sobreposto (overriding).
class Ponto { protected: float x, y; public: Ponto(); Ponto(float, float); void print(); }; class Ponto3D: public Ponto { float z; public: Ponto3D(); Ponto3D(float, float, float); void print(); }; Ponto p(2, 3); Ponto3D p3d(5, 6, 7); p.print(); p3d.print();

Um mtodo pode fazer uso de um outro mtodo com o mesmo nome da classe base utilizando: Ponto::print();

Programao 2

114

Construtores e herana
Como os construtores so mtodos especiais, no possvel utilizar o mesmo mecanismo utilizado para os mtodos, i.e., invocao no corpo do mtodo.

Para isso utilizam-se as listas de inicializao. Quando no so utilizadas as listas de inicializao, o construtor da classe derivada invoca sempre o construtor por defeito da classe base. Com lista de Inicializao
Ponto3D::Ponto3D() { z=0; } Ponto3D::Ponto3D(int a, int b, int c): { z=c; } Ponto(a, b)

Programao 2

115

Tipos de proteco no acesso aos membros


Veja-se o seguinte exemplo:
class A { public: int a; protected: int b; private: int c; }; class B: public A { void Bfunction(); }; void B::Bfunction() { a = 5; // ok, public b = 5; // ok, protected visvel nas classes derivadas c = 5; // Ilegal - private no visvel } void main() { B b; b.a = 5; // ok, public b.b = 5; // Ilegal - protected b.c = 5; // Ilegal - private }

Programao 2

116

Converso ascendente (Upcast)


Um apontador ou referncia de uma classe derivada pode ser sempre convertido num apontador ou referncia de uma classe base. Ponto3D *p3d=new Ponto3D(2, 5, 8); Ponto *p3d1=new Ponto3D(5, 10, 15); Ponto3D p3(2,3,4); Ponto &p=p3; p3d->print(); p3d1->print();

Converso descendente (Downcast)


Nalgumas situaes necessrio fazer converso contrria, isto , converter de uma classe base para uma descendente. Ponto *p=new Ponto3D(5, 10, 15); p->getZ(); // Errado! Neste caso p, no dispe de acesso a um mtodo getZ(),por exemplo. Ponto3D *p3=dynamic_cast<Ponto3D*>(p); p3->getZ(); O dynamic_cast assegura que a converso s possvel se, efectivamente, o objecto a converter do tipo para o qual se pretende converter. Caso contrrio, devolve zero.

Programao 2

117

A converso ascendente particularmente utilizada em parmetros de funes ou mtodos.


#include<iostream> using namespace std; enum notas {Do, Re, Mi}; class Instrumento { public: void toca(notas n){ cout << "Instrumento::toca\n"; } }; class Flauta: public Instrumento { public: void toca(notas n){ cout << "Flauta::toca\n"; } }; class Viola: public Instrumento { public: void toca(notas n){ cout << "Viola::toca\n"; } }; void afinar(Instrumento &i) { i.toca(Do); } void main() { Viola v; afinar(v); }

O mesmo exemplo poderia utilizar apontadores.

Programao 2

118

Polimorfismo e funes virtuais


O polimorfismo permite que, em tempo de execuo, sejam invocados diferentes mtodos utilizando a mesma mensagem no mesmo apontador ou referncia. Definindo o mtodo print como uma funo virtual, podemos tirar partido do polimorfismo:
class Ponto { protected: float x, y; public: Ponto(); Ponto(float, float); virtual void print(); };

invocado o mtodo do objecto que foi criado e no da referncia do objecto que invoca o mtodo. p3d1->print(); // invoca print de Ponto3D

Programao 2

119

Gesto de memria dinmica interna a uma classe


Quando uma classe efectua internamente gesto de memria dinmica (alocao e libertao) necessrio tomar algumas precaues, definindo um conjunto de mtodos de suporte para o correcto funcionamento dessas classes: Destrutor Operador de atribuio Construtor de cpia
class Aponta { int a; int *ap; public: Aponta(){ a=0; ap=new int; *ap=0; } Aponta(int x, int y){ a=x; ap=new int; *ap=y; } Aponta(const Aponta &c){ a=c.a; ap=new int; *ap=*c.ap; } Aponta &operator=(const Aponta &c){ if(this!=&c){ a=c.a; delete ap; ap=new int; *ap=*c.ap; } return(*this); } ~Aponta(){ delete ap; } };

Programao 2

120

Destrutor
Os destrutores so tambm mtodos especiais que so invocados automaticamente sempre que se torna necessrio destruir uma instncia de uma classe. So invocados em situaes como: Libertao instncia; explcita de apontadores para essa

Destruio normal de instncias locais a uma funo ou bloco ou parmetros por valor;

Operador de atribuio
um caso particular da sobrecarga de operadores e deve ser definido sempre que o construtor de cpia tambm for definido. Permite que uma instncia seja atribuda a outra j criada. <classe> &operator=(const <classe>&); Por omisso, na atribuio os dados de um objecto so copiados um por um bit por bit. Nos membros apontadores apenas copiado o endereo, no sendo copiados os valores apontados. Por isso, que a definio de operadores de atribuio se manifesta to importante.

Construtor de cpia
invocado sempre que h necessidade de efectuar uma cpia de uma instncia.

Programao 2

121

Construtores e Destrutores
Um construtor invocado sempre que uma instncia definida. Num contexto local, os destrutores so invocados por ordem inversa da sua construo. Os construtores das instncias globais so executados antes do main iniciar. Os construtores de instncias so executados pela ordem da sua definio dentro do mesmo ficheiro. Os destrutores de instncias globais so executados por ordem inversa da sua construo a seguir finalizao do main.

Destrutores na herana
Os destrutores das classes base so sempre invocados automaticamente pelo compilador pela ordem inversa da sua construo. Os construtores so executados de acordo com a ordem em que as classes so derivadas, desde a classe base at ltima classe derivada. Os destrutores so executados de acordo com a ordem inversa em que as classes so derivadas, desde a ltima classe derivada at classe base.

Polimorfismo e destrutores
Devido ao seu funcionamento, na utilizao de polimorfismo deve ser sempre definido o destrutor como virtual para que seja sempre invocado o destrutor da classe correcta, ou seja, o da classe alocada e no da classe base. Programao 2 122

Exemplo
class A { int x; public : A() { x = 0; } }; class B { A* a; public: B() { a = new A; } B(const B& b) { a = new A(*b.a); } B& operator = (const B& b) { if (this != &b) { delete a; a = new A(*b.a); } return (*this); } ~B() { delete a; } }; void main() { B b; B c(b); }

Programao 2

123

Coleces hbridas
As coleces hbridas recorrem ao upcast e ao polimorfismo para coleccionar, na mesma entidade, instncias com uma classe base comum. Como a coleco tem que ser implementada com apontadores, a gesto de memria dos elementos da coleco deve ser da responsabilidade de quem utiliza a coleco e no da coleco. Para o correcto funcionamento de um set da STL com apontadores, foi necessrio criar um novo template ColeccaoHibrida, que apenas aceita apontadores como parmetros. O operador< da classe base foi definido como virtual. As sobreposies de mtodos nas derivadas podem requerer um dynamic_cast. AS classes que contm coleces hbridas tm que definir o construtor de cpia, destrutor e operador de atribuio. Na cpia necessrio recorrer a um processo de duplicao dinmica (clonagem).

Programao 2

124

Classes abstractas
Em muitas situaes a classe base representa um conceito abstracto servindo apenas para agregar dados e operaes ou definir uma interface padro que ter que ser definida nas classes derivadas. Um mtodo que tenha o inicializador: =0 designado de funo virtual pura. Uma classe abstracta quando contm um ou mais funes virtuais puras. De uma classe abstracta no possvel definir objectos. class Figura{ ... virtual void Rodar()=0; virtual void Desenhar()=0; ... };

Uma funo virtual pura mantm-se pura enquanto no definida, mantendo-se a classe abstracta e portanto impossibilitando a definio de objectos.

Programao 2

125

class X { public: virtual void f()=0; virtual void g()=0; }; X b; // erro: definio de objecto com classe abstracta class Y: public X { void f(){ ; }; // sobrepoe X::f // erro: Y continua abstracta

Y b;

class Z : public Y { void g(); // sobrepoe X::g }; Z c; // ok

S possvel definir objectos quando a classe derivada tiver o interface completamente definido.

Programao 2

126

Herana Mltipla
Considera-se herana mltipla quando derivada tem vrias classes base directas. Exemplo de herana mltipla:
terreste aqutico

uma

classe

anfbio

Qualquer mtodo das superclasses pode ser invocado tal como na herana simples, sendo tambm utilizada a resoluo de contexto (::) quando existam mtodos sobrepostos.

Ocorrncia mltipla da classe base


A herana mltipla pode decorrer em situaes em que uma classe base aparece mais do que uma vez, trazendo obviamente problemas de conflito em relao invocao dos mtodos.
Base Base

DerA

DerB

Derivada

Neste caso se na classe Derivada for invocado um mtodo da classe Base , o compilador no sabe em qual das classes Base deve invocar o mtodo.

Programao 2

127

Classes base virtuais


Existem situaes em que no conveniente a existncia mltipla da classe base. Para tal, define-se a classe base como virtual, ficando a classe Base comum nas classes derivadas.

Base

DerA

DerB

Derivada

Programao 2

128

Exemplo: Ocorrncia mltipla da classe base


No caso da herana mltipla com ocorrncia mltipla da classe base, a existncia de duas classes Base pode originar ambiguidades. A invocao de mtodos pode requerer uma qualificao adicional: DerA::Base::print(), para referir o mtodo print da classe Base, base de DerA. A ordem de invocao dos construtores sempre da base para as derivadas, pela ordem que so colocadas na derivao.
#include<iostream> using namespace std; class Base{ char nome[10]; public: Base(char *n){ strcpy(nome, n); } virtual void print(){ cout << "Base: (" << nome << ")" << endl; } }; class DerA: public Base{ public: DerA(): Base("DerA"){} void print(){ Base::print(); cout << "DerA" << endl; } };

Programao 2

129

class DerB: public Base{ public: DerB(): Base("DerB"){} void print(){ Base::print(); cout << "DerB" << endl; } }; class Derivada: public DerA, public DerB{ public: void print(){ DerB::Base::print(); // print da Base de DerB DerA::print(); DerB::print(); cout << "Derivada" << endl; } }; void main() { Derivada d1; // ok d1.print(); // Base* d=new Derivada; // Errado! Podem ser duas Base // d->print(); }

Programao 2

130

Exemplo: classes base virtuais


Com classes base virtuais, a classe base Base apenas existe uma nica vez, pelo que a ordem normal de invocao dos construtores ligeiramente alterada. A ordem a seguinte: Base uma vez DerA Mas no invoca o construtor de Base DerB Mas no invoca o construtor de Base E Derivada

Quem invoca o construtor de Base a Derivada, pelo que, as listas de inicializao devem a ser colocadas. As listas de inicializao da classe Base nas classes DerA e DerB no tm qualquer efeito.
#include<iostream> using namespace std; class Base{ char nome[10]; public: Base(char *n){ strcpy(nome, n); } virtual void print(){ cout << "Base: (" << nome << ")" << endl; } }; class DerA: public virtual Base{ public: DerA(): Base("DerA"){}

Programao 2

131

void print(){ Base::print(); cout << "DerA" << endl; } }; class DerB: public virtual Base{ public: DerB(): Base("DerB"){} void print(){ Base::print(); cout << "DerB" << endl; } }; class Derivada: public DerA, public DerB{ public: Derivada(): Base("Unica") {} void print(){ //DerB::Base::print(); // no necessrio DerB::Base, porque a base s uma Base::print(); DerA::print(); DerB::print(); cout << "Derivada" << endl; } };

void main() { Derivada d1; // ok d1.print(); Base* d=new Derivada; // Agora sim, uma classe Base pode referenciar uma instncia de Derivada d->print(); delete d; }

Programao 2

132

Operadores de converso
Permitem a converso de um objecto para outro tipo. class Real { double d; public: Real(double pd){ d=pd; operator double() const{ return(d); } }; Real r(10.0); double d=r;

Programao 2

133

Membros estticos
Um membro (dados ou funes) definido como esttico partilhado por todos os objectos.
#include<iostream> using namespace std; class ABCD{ int ch; static int s; public: ABCD(){ ch=0; } void setCH(int c){ ch=c; } void setS(int a){ s=a; } void printCH(){ cout << ch << endl; } void printS(){ cout << s << endl; } static int getS(){ return(s); } }; int ABCD::s=0; void main() { ABCD a, b, c, d; b.setCH(5); b.setS(10); b.printCH(); b.printS(); c.setCH(50); c.setS(100); b.printCH(); b.printS(); }

Programao 2

134

Declaraes friend
As declaraes friend so feitas na definio de classes e permitem que a entidade definida como tal, tenha acesso a todos os elementos privados dessa classe. So normalmente funes ou classes externas classes em questo. int pode_entrar(Temfriends t) { t.a=10; } class Temfriends { int a; public: Temfriends(); friend int pode_entrar(Temfriends); ... }

Programao 2

135

Entrada/Sada da dados em C++ (iostream) Sada Formatada


cout << "Numero: " << 10 << endl; double d=3.1415927; Define o comprimento do campo da sada subsequente. cout.width(10); Define a preciso do campo da sada subsequente. cout.precision(2); cout << d << "\n"; Sobrecarga do operador <<

ostream &operator<<(ostream &s, const <classe> &var);

Sendo definido como friend na classe.

Entrada Formatada
int a; cout << "Introduza numero: "; cin >> a; Sobrecarga do operador >>

istream &operator>>(istream &s, <classe> &var);

Sendo definido como friend na classe. Programao 2 136

Entrada/Sada de dados em C++ (iostream) Entrada e sada no formatada


Envia um carcter para uma sada. ostream& ostream::put(char ch); Recolhe um carcter de uma entrada. istream& istream::get(char &ch); Devolve o carcter para a entrada. istream& istream::putback(char ch); Recolhe uma linha para line, com tamanho mximo size-1 at encontrar o carcter terminator. Este no colocado em line. istream& istream::getline(char line[], int size, char terminator=\n);

Programao 2

137

Input/Output em C++ (fstream) Acesso a ficheiros


O acesso a ficheiros feito, definindo instncias de ifstream e ofstream, respectivamente para ficheiros de entrada e sada. Os operadores sobre streams standard aplicam-se s streams de ficheiros. Deve-se incluir o namespace <fstream>. ifstream f(c:\\dados.txt); // entrada ofstream f(c:\\dados.txt); // sada

fstream f(c:\\dados.bin, ios::out | ios::binary) // sada em modo binrio Modos


ios::app ios::ate ios::in ios::out Acresenta Posiciona no fim do ficheiro Entrada Sada ios::binary ios::trunc ios::nocreate ios::noreplace Modo binrio Apaga o contedo Falha se no existe Se existe, falha, excepto se ios::app ou ios::ate

Tambm possvel abrir um ficheiro definindo a instncia do canal por omisso e utilizar o mtodo open. ofstream f; f.open(abc.txt);

Programao 2

138

Mtodos void open(const char *filename, ios_base::openmode _Mode); write(unsigned char *p, int n); read(unsigned char *p, int n); void close();

Exemplo

#include<iostream> #include<fstream> using namespace std; void main() { char buf[256]; ifstream f("io.cpp"); if(!f){ cout << "No foi possivel abrir o ficheiro"; return; } while(!f.eof()){ f.getline(buf, 255); cout << buf << endl; } f.close();
} Programao 2 139