A Linguagem C

++
Renato Maia
maia@inf.puc-rio.br

TeCGraf/PUC-Rio
Renato Maia 1

nov/2004

Hello, World!

#include <iostream>

int main() { std::cout << "Hello, world!" << "\n"; }

nov/2004

Renato Maia

2

MÓDULO I
Recursos Básicos

nov/2004

Renato Maia

3

Recursos Básicos
Exemplo
Calculadora

Parte 1:

Parte 2:
Espaços de Nomes Compilação e Ligação

Tipos Declarações Ponteiros Vetores Estruturas Operadores Expressões Comandos Funções

nov/2004

Renato Maia

4

Tipos

nov/2004

Renato Maia

5

false Conversões: true 1 false 0 0 false ?0 true Renato Maia 6 nov/2004 .Tipo Lógico Tipo: bool Literais: true .

. 'Z' Algarismos: '0'. .. 'b'.. unsigned Literais: Letras: 'a'. '1'. .. '\0' Números: 97 // o 'a' na tabela ASCII Renato Maia 7 nov/2004 . '9' Especiais: '\n'... '\t'.Tipo Caractere Tipo: char Modificadores: signed .

unsigned short .Tipo Inteiro Tipo: int Modificadores: signed . long Literais: Decimal: 20 Octal: 020 Hexadecimal: 0x20f nov/2004 Renato Maia 8 .

1.23 1.Tipos Reais Tipos: float .23e10 1. double Modificadores: long (aplicável ao double) Literais: (não podem conter espaços) 1.23 .23e-10 nov/2004 Renato Maia 9 .

Tipo Vazio Tipo: void Uso: Como tipo de retorno de uma função Define funções que não retornam valores Como tipo de ponteiro Define um ponteiro para tipo indefinido (ponteiro genérico) nov/2004 Renato Maia 10 .

SEG. Uso Definir um tipo que assume um conjunto de valores inteiros pré-definidos (enumerados). TER. SAB }. SEX. QUI. nov/2004 Renato Maia 11 .Enumerações Exemplo: enum DiaSem { DOM. QUA.

Declarações nov/2004 Renato Maia 12 .

struct User . const double pi = 3. Thor } ."winter}. namespaceNS { int a. const char const char * season[ ] = {"spring". "fall". template<class T> T abs(T a) { return a<0 ? –a : a. struct Date { int d. int day(Date* p) { return p->d. y } .Declarações Tipo Declarador Iniciação/Definição char ch . Renato Maia 13 Especificador nov/2004 . double sqrt(double) . * name = "Najla" . } typedef list<int> SmallNums . m. enum Beer { Carlsberg."summer". } .1415926535897932385 . string s . extern int error_number . Tuborg. } . int count =1 .

Declarações (observações) Declaração com vários nomes int a. Nomes de identificadores hello. namespace e static Renato Maia 14 nov/2004 . // apenas o 'b' é iniciado. DEFINED. pb. __. um_nome_razoavelmente_GRANDE Iniciação (apenas estáticos) Globais. b = 0. _123. int* pa. // o 'pb' NÃO é um ponteiro. var23.

cout << x. cout << x. } nov/2004 . Renato Maia 15 int x = 0. } x = 3. { int x = 1. { int x = 2.Escopo cout << x. cout << x.

Pchar p1. p2.Declaração de Tipos Exemplos: typedef char *Pchar. Renato Maia 16 nov/2004 . Na realidade a declaração de um typedef define apenas um sinônimo para algum tipo. char *p3 = p1.

Ponteiros e Vetores nov/2004 Renato Maia 17 .

nov/2004 . char *pc = &c.Ponteiros &c c: 'a' Outras Formas char **ppc. char (*fp)(char*). Renato Maia 18 pc: Uso char c = 'a'. char *vetp[15]. char c2 = *pc.

Ao invés disso usa-se o valor 0. int *pi = 0. null de Java). Nenhum objeto é criado no endereço 0.g. que pode ser atribuído a ponteiros.Iniciação de Ponteiros A linguagem C++ não define uma palavra reservada para indicar um endereço de memória inválido ou nulo (e. Renato Maia 19 nov/2004 .

v7 = {1. // equiv. int v5[5] = {1.2.3.3. 4 }. Dimensões float d1[3].4. 3.'b'.: int v5[3] = {1. int v1[ ] = { 1. 20]. float d2[10][20].2. char v3[3] = {'a'. Iniciação // v1 é do tipo int[4] // não: char v3[2] = {'a'.0.0}.0}.0}.2.3} int v7[5].5} // erro: apenas na iniciação nov/2004 Renato Maia 20 . 2.Vetores // não: float d2[10.'b'.

'\0' }. sizeof("cadeia") == 7 Acesso através de ponteiros irrestritos (vs. 'e'. if (p == q) cout << "one!\n". ponteiros para const.) // erro: resultado indefinido char *pc = "imutavel". char c3[ ] = { 'c'. Comparação de cadeias const char *p = "C++". const char *q = "C++". 'i'. pc[0] = ' '. // depende da implementação do C++ Quebrando cadeias grandes const char longa[ ] = "inconstitucional" "issimamente\n" // "inconstitucionalissimamente\n" Renato Maia 21 nov/2004 . 'd'. 'a'. 'a'.Literais de Cadeias de Caracteres Na iniciação de vetores de caracteres char c2[ ] = "cadeia".

Ponteiros e Vetores p+=5. p = v. // erro: não é possível atribuir um ponteiro a um vetor nov/2004 Renato Maia 22 . // conversão implícita v = p. char *p. p: v: 'c' 'a' 'd' 'e' 'i' 'a' 0 p: Conversão implícita para ponteiros char v[ ] = "cadeia".

use(*p). p++ Subtração de ponteiros (ou endereços) int int int int v1[10]. i++ for (char *p = v . // indefinido nov/2004 Renato Maia 23 . char v[ ] = "uma cadeia\n" for (int i = 0 . i1 = &v1[5] .&v2[3]. // i1 == 2 i2 = &v1[5] .Aritmética de Ponteiros Iteração sobre uma cadeia de caracteres ) ) use(v[i]). *p != 0 . v2[10]. v[i] != 0 .&v1[3].

Constantes Declaração const int model = 90. // v[i] é const const int x. const int v[ ] = { 1. 4. nov/2004 . char const*pc2. 2. 5 }. // erro: exige iniciação Ponteiros constantes // ponteiro constante // ponteiro para uma constante // ponteiro para uma constante Renato Maia 24 char*const cp. const char*pc. 3.

Referências Definição // r e i se referem ao mesmo elemento // x = 1 // i = 2 int i = 1. Iniciação int& r2. r = 2. // erro: falta iniciação extern int& r3. int& r = i. // ok: r3 é iniciado em outro módulo Renato Maia 25 nov/2004 . Uso int x = r.

double* pd2 = pi.// ok: conversão implicita de int* para void* *pv. double* pd1 = pv. nov/2004 Renato Maia 26 .Ponteiros Genéricos (void *) Recurso de baixo nível Operações int* pi = &i. void* pv = pi. // erro: não é possível incrementar um void* // conver. // erro: não é possível acessar um void* pv++. // erro // erro // inseguro Conversões (cast) int* pi2 = static_cast<int*>(pv). explíc. double* pd3 = static_cast<double*>(pv).

Estruturas nov/2004 Renato Maia 27 .

char state[2] . long int number. long zip.Estruturas Declaração // "Jim Dandy" // 61 // "South St" // "New Providence" // ’N’ ’J’ // 7974 struct address { char *name. char *street. nov/2004 Renato Maia 28 . char *town. }.

"South St".number = 61. "New Providence". jd. Iniciação address jd = { "Jim Dandy".name = "Jim Dandy". 7974 }. 61.´J´}.Estruturas (cont. {´N´. nov/2004 Renato Maia 29 . jd.) Uso address jd.

nov/2004 Renato Maia 30 .m Uso address *p = &jd cout << p->name << ´\n´ << p->number << ´ ´ << p->street << ´\n´ << p->town << ´\n´ << p->state[0] << p->state[1] << ´ ´ << p->zip << ´\n´.Ponteiro para Estruturas Operador de acesso através de ponteiros p->m (*p).

} Renato Maia 31 nov/2004 . current = next. address set_current(address next) { address prev = current.Cópia de Estruturas address current. return prev.

}. }. List* member_of. // definido posterior. struct Link { Link* pre. nov/2004 Renato Maia 32 . struct Link { Link* previous.Declaração Antecipada struct List. }. struct List { Link* head. Link* suc. Link* successor.

Operadores nov/2004 Renato Maia 33 .

Operadores Relacionais == != > < >= <= Igual Diferente Maior que Menor que Maior ou igual Menor ou igual nov/2004 Renato Maia 34 .

Operadores Aritiméticos + * / % -++ Renato Maia 35 Adição Subtração Multiplicação Divisão Módulo Inversor de sinal Incremento Decremento nov/2004 .

Operadores Lógicos && || ! E (and) Ou (or) Negação (not) nov/2004 Renato Maia 36 .

Operadores sobre Bits & | ^ ~ << >> E bit a bit Ou inclusivo bit a bit Ou exclusivo (xor) bit a bit Complemento Deslocamento a esquerda Deslocamento a direita nov/2004 Renato Maia 37 .

Operadores de Atribuição = *= /= %= += -= <<= >>= &= |= ^= Atribuição simples Multiplicação e atribuição Divisão e atribuição Módulo e atribuição Soma e atribuição Subtração e atribuição Deslocamento a esquerda e atribuição Deslocamento a direita e atribuição E bit a bit e atribuição Ou inclusivo bit a bit e atribuição Ou exclusivo bit a bit e atribuição nov/2004 Renato Maia 38 .

<expr> <cond> ? <true> : <false> Seqüência Condicional cout << ( (p1+p2+p3)/3 >= 5 ? "aprovado" : "reprovado" ) nov/2004 Renato Maia 39 .Operadores Composicionais <expr> .

Operadores de Memória Dinâmica new delete delete[ ] Alocação Desalocação Desalocação de vetores nov/2004 Renato Maia 40 .

) reinterpret_cast<tipo>(valor) Conversão dinâmica dynamic_cast<tipo>(valor) Conversão de C (tipo) valor nov/2004 Renato Maia 41 .Operad. de Conversão de Tipos Conversão estática (tipos relacionados) static_cast<tipo>(valor) Conversão estática (tipos não relacion.

// tipo definido na biblioteca padrão do C++ nov/2004 Renato Maia 42 . int i = int(d).Operadores de Construção Construtor tipo (valor) Exemplos double d = 1.23. complex c = complex(d).

. nov/2004 Renato Maia 43 .. int a = f() + g() // g() pode executar primeiro Sempre use parênteses para garantir a precedência esperada. Evite escrever expressões complexas e pouco legíveis. Conte com as otimizações do compilador. if ( (i & mask) == 0 ) // .Operadores (observações) Ordem de avaliação dos operandos é indefinida.

Comandos nov/2004 Renato Maia 44 .

Bloco de Comandos { <comando>. . <comando>. } Renato Maia 45 nov/2004 . <comando>. <comando>...

default: <comandos>. } Condicional if (<expr>) <comando>. else <comando>. break. nov/2004 Renato Maia 46 . break.Comandos de Seleção Seleção switch (<expr>) { case <const>: <comandos>. break. case <const>: <comandos>.

<cond>. for (..Comandos de Iteração Laço com teste no início while (<cond>) <comando>. Laço com contador for (<início>.. <increm>) <comando>. */ } // para sempre nov/2004 Renato Maia 47 .. Laço com teste no final do <comando> while (<cond>).) { /* .

. i++) for (j = 0. for (i = 0. j++) if (nm[i][j] == a) goto found.Comando de Salto O famigerado goto int i. int j. found: // nm[i][j] == a nov/2004 Renato Maia 48 . j<m. // não encontrado // .. i<n.

Funções

nov/2004

Renato Maia

49

Definição

extern void swap(int*, int*); // declaração

void swap(int* p, int* q) // definição { int t = *p; *p = *q; *q = t; }
Renato Maia 50

nov/2004

Funções inline

inline int fac(int n) { return (n<2) ? 1 : n*fac(n-1); } int i = 720; int i = (int n = 6, (n<2) ? 1 : ...)

int i = f(6); int i = f(6);

nov/2004

Renato Maia

51

Variáveis Estáticas

void f(int a) n == 0, x == 0 { n == 1, x == 0 while (a--) n == 2, x == 0 { static int n = 0; // iniciada uma vez int x = 0; // iniciada n vezes cout << "n == " << n++ << ", x == " << x++ << '\n'; } }

nov/2004

Renato Maia

52

Passagem de Parâmetros

Passagem por referência

void increment(int& aa) { aa++; }; int x = 1; increment(x); // x == 2

Parâmetros constantes

void f(const int *p) { *p = 1; /* erro! */ }

Parâmetros anônimos

void search(table* t, const char* key, const char*) { // não é possível utilizar o terceiro parâmetro }

nov/2004

Renato Maia

53

Constantes por Referência // error: não pode ser constante // ok: double t = double(1) . void g(double d. Referência para valores constantes double& dr = 1. const double& cdr = t. } Renato Maia // error: argumento constante // passa uma referência a r // error: necessária conversão de tipo nov/2004 54 . update(r) . update(d) . float r) { update(2. const double& cdr = 1.0f) . Valores constantes por referência void update(float& i) .

*/ return &local.. /* . } // cuidado! int& fr() { int local = 1.. int& getcounter(int i) { return vet[i]. /* .Valor de Retorno Retorno por referência int vet[5]. Retorno de variáveis automáticas int* fp() { int local = 1. } getcounter(3)++. */ return local... } // cuidado! nov/2004 Renato Maia 55 .

print(long(1)) or // print(double(1)) ? } nov/2004 Renato Maia 56 .0). // print(long) print(1.Sobrecarga de Funções void print(double). void print(long). void f() { print(1L). // erro: ambígua. // print(double) print(1).

int base =10).10) . print(31. print(31.16) . } Erros comuns int h(int a = 0.2) . } Alternativa void print(int value. char* c = 0) . int b. void f() { print(31) . inline void print(int value) { print(value.Parâmetros Default void print(int value. int base) . // erro nov/2004 Renato Maia 57 .

// iniciação arg for (. static_cast<char*>(0)). } // error(1. "Econtrado".. cerr << p << ' '. severity) .. .Parâmetros Variáveis #include <cstdarg> void error(int severity. "Erro".char*) . if (severity) exit(severity) . nov/2004 Renato Maia 58 . } va_end(ap) . "Faltal". va_start(ap.) { char* p = va_arg(ap.. // limpa o conteúdo de ap cerr << '\n'.) { // "severidade" e mensagens va_list ap. if (p == 0) break.

Ponteiros para Funções

void print(const char *s) { /* ... */ }

void (*pf)(const char*); // ponteiro para função

void f() { pf = print; pf("error"); }
Renato Maia

// também: pf = &print; // também: (*pf)("error");

nov/2004

59

Macros

Substituições simples

#define PI 3.141593

Macros razoáveis

#define CASE break;case #define FOREVER for(;;)

Macros perigosas
// 2 + i++ * 2 + i++

#define SQUARE(a) a * a int m = SQUARE(2 + i++)

nov/2004

Renato Maia

60

Exemplo
Calculadora

nov/2004

Renato Maia

61

Exemplo

Entrada

perimetro = 2 * pi * (r = 2.5) area = pi * r * r

Saída

15.708 19.635

nov/2004

Renato Maia

62

Gramática da Calculadora
term: term / primary term * primary primary primary: NUMBER NAME NAME = expression - primary ( expression )

program: END expr_list END expr_list: expression ; expression ; expr_list expression: expression + term expression - term term

nov/2004

Renato Maia

63

Renato Maia 64 Token_value double string nov/2004 . LP = '('.Tokens enum Token_value { NAME. MINUS = '-'. NUMBER. curr_tok = PRINT. string_value. PLUS = '+'. PRINT = '. ASSIGN = '='. END. number_value. DIV = '/'. MUL = '*'. RP = ')' }.'.

get(ch)) return curr_tok = END.Leitura de Tokens Token_value get_token() { char ch = 0. do { // pula espaços em branco. exceto '\n' if(!cin. … Renato Maia 65 nov/2004 . } while (ch != '\n' && isspace(ch)) .

case '. case '*': case '/': case '+': case '-': case '(': case ')': case '=': return curr_tok = Token_value(ch) . … nov/2004 Renato Maia 66 .Leitura de Tokens … switch (ch) { case 0: return curr_tok = END.': case '\n': return curr_tok = PRINT.

cin >> number_value. return curr_tok = NUMBER.': cin.putback(ch) .Leitura de Tokens … case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '. … Renato Maia 67 nov/2004 .

return curr_tok = NAME. } error("bad token") . cin.putback(ch) . return curr_tok = PRINT.Leitura de Tokens … default: // NAME. } } nov/2004 Renato Maia 68 . ou erro if (isalpha(ch)) { string_value = ch.get(ch) && isalnum(ch)) string_value += ch . while (cin. NAME=.

} nov/2004 Renato Maia 69 .Erros double error(const string& s) { no_of_errors++. cerr << "error: " << s << '\n'. return 1.

for(.Expressão double expr(bool get) { // adiciona e subtrai double left = term(get) .. break. default: return left. break.) switch (curr_tok) { case PLUS: left += term(true) . } } nov/2004 Renato Maia 70 . case MINUS: left -= term(true) .

. } return error("divide by 0") . for (. break. break. } } Renato Maia 71 nov/2004 . case DIV: if (double d = prim(true)) { left /= d.Termo double term(bool get) { // multiplica e divide double left = prim(get) . default: return left.) switch (curr_tok) { case MUL: left *= prim(true) .

nov/2004 Renato Maia 72 .Variáveis Armazenar numa tabela que associe strings a números reais Sugestão: usar o template 'map' da biblioteca padrão do C++ std::map<string.double> table.

return v. return v.Primário double prim(bool get) { // manipula primários if (get) get_token() . } … Renato Maia 73 nov/2004 . get_token() . switch (curr_tok) { case NUMBER: // constante real { double v = number_value. } case NAME: { double& v = table[string_value] . if (get_token() == ASSIGN) v = expr(true) .

// consome o ')' return e. get_token() . case LP: { double e = expr(true) . if (curr_tok != RP) return error(") expected") . } default: return error("primary expected") . } } Renato Maia 74 nov/2004 .Primário … case MINUS: // menos unário return -prim(true) .

Função main int main(int argc.7182818284590452354. } nov/2004 Renato Maia 75 .1415926535897932385. // constantes predefinidas table["e"] = 2. } return 0. if (curr_tok == END) break. cout << expr(false) << '\n'. if (curr_tok == PRINT) continue. while (cin) { get_token() . char* argv[]) { table["pi"] = 3.

2. Se nenhuma chave for fornecida.Exercícios 1. tal que chave é uma string dada pela linha de comando. A codificação deve ser feita na forma c^chave[i]. Compilar e executar o programa de exemplo mostrado previamente Escrever um programa de encriptação que recebe um texto pela entrada padrão (cin) e devolve um texto codificado na saída padrão (cout). então nenhuma codificação deve ser feita. Dessa forma quando um texto for novamente codificado com a mesma chave o texto original é recuperado. nov/2004 Renato Maia 76 . Os caracteres da chave devem ser utilizados de forma circular.

dat > back.txt: Comandos: C:\>encrypt senha < input.dat: back.dat C:\>encrypt senha < output.txt Renato Maia 77 nov/2004 .Teste do Exercício 2 nome do seu programa chave de criptografia um arquivo de texto qualquer arquivo com o texto codificado arquivo com o texto decodificado Legenda: encrypt: senha: input.txt > output.txt: output.

Espaços de Nomes nov/2004 Renato Maia 78 .

PLUS=´+´. double prim(bool get) { /* .. NUMBER.´. PRINT=´. */ } double term(bool get) { /* . DIV=´/´.. ASSIGN=´=´.. RP=´)´ }. MUL=´*´.. */ } double expr(bool get) { /* . Token_value curr_tok. END. */ } } namespace Lexer { enum Token_value { NAME. double number_value. string string_value. LP=´(´.Espaços de Nomes namespace Parser { double expr(bool) .. */ } } nov/2004 Renato Maia 79 . MINUS=´-´. Token_value get_token() { /* ....

) switch (Lexer::curr_tok) { case Lexer::MUL: left *= prim(true) . } // .Nomes Qualificados // note a qualificação Parser:: // nenhuma qualificação necessária // note a qualificação Lexer:: // note a qualificação Lexer:: // nenhuma qualificação necessária double Parser::term(bool get) { double left = prim(get) . // ... for (. } nov/2004 Renato Maia 80 ....

Utilizando Declarações namespace Parser { double term(bool get).) switch (curr_tok) { // qualificação Lexer:: é desnecessária case Lexer::MUL: left *= prim(true) .. } nov/2004 Renato Maia 81 . // .... using Lexer::curr_tok.. } // .. // .. // use o curr_tok do Lexer } double Parser::term(bool get) { double left = prim(get). for (.

..) switch (curr_tok) { // qualificação Lexer:: é desnecessária case MUL: // qualificação Lexer:: é desnecessária left *= prim(true) .... // . // incorpora todas as declarações } double Parser::term(bool get) { double left = prim(get).Diretivas de Utilização namespace Parser { double term(bool get).. } // . using namespace Lexer. for (.. } nov/2004 Renato Maia 82 . // .

.. void f() { /* . */ } } /* Equivalente a: namespace $$$ { int a. */ nov/2004 Renato Maia 83 .. void f() { /* . */ } int g() { /* .Espaços de Nomes Anônimos namespace { int a.. */ } int g() { /* .... */ } } using namespace $$$..

*/ } American_Telephone_and_Telegraph::String s3 = "Grieg".Alias de Espaços de Nome // nome muito longo namespace American_Telephone_and_Telegraph { /* . // alias namespace ATT = American_Telephone_and_Telegraph. American_Telephone_and_Telegraph::String s4 = "Nielsen". nov/2004 Renato Maia 84 . ATT::String s4 = "Nielsen"... ATT::String s3 = "Grieg".

Exercício Dividir o programa de exemplo da calculadora em módulos (usando espaços de nomes) Módulo Léxico (namespace Lexer) Leitura e interpreção de tokens Módulo Parser (namespace Parser) Interpretação e avaliação de expressões Módulo de Erros (namespace Error) Contagem e exibição de erros nov/2004 Renato Maia 85 .

Compilação e Ligação nov/2004 Renato Maia 86 .

// habilita verificações #endif void f3(int* p) { assert(!ARG_CHECK || p!=0) .Compilação Condicional #ifdef NDEBUG const bool ARG_CHECK = false. } nov/2004 Renato Maia 87 . // desabilita verificações #else const bool ARG_CHECK = true. // ou não faz verificação ou p!=0 // ...

cpp Renato Maia error.h error.cpp lexer.h lexer.cpp parser.cpp 88 nov/2004 .Compilação em Partes <map> <string> parser.h main.

PRINT = '. RP = ')' }.Cabeçalho do Módulo Lexer #include <string> namespace Lexer { enum Token_value { NAME. ASSIGN = '='. extern Token_value curr_tok. extern double number_value. DIV = '/'. LP = '('. MUL = '*'. NUMBER. extern std::string string_value. END. MINUS = '-'. PLUS = '+'.'. Token_value get_token(). } nov/2004 Renato Maia 89 .

h" #include "error. Lexer::Token_value Lexer::get_token() { /* . Lexer::Token_value Lexer::curr_tok = Lexer::PRINT. double Lexer::number_value.. std::string Lexer::string_value.Módulo Lexer #include "lexer. */ } nov/2004 Renato Maia 90 .h" #include <iostream> #include <cctype> using std::cin..

} // CALC_ERROR_H #endif nov/2004 Renato Maia 91 ..Guardas de Inclusão Para evitar que um cabeçalho seja incluído diversas vezes no mesmo arquivo // error..h: #ifndef CALC_ERROR_H #define CALC_ERROR_H namespace Error { // .

void mais_outra_funcao_c(char*). extern "C" { void uma_funcao_c(int. void outra_funcao_c(int. extern "C" void funcao_c(int.h" } nov/2004 Renato Maia 92 . É necessário informar ao compilador quando uma função deve ser ligada como uma função C. int).Ligação com Código C A forma de chamada de funções C é diferente das chamadas de C++. int). double). } extern "C" { #include "modulo_c.

// cmp tem ligação C } // cmp tem ligação C++ void isort(void* p. // FT tem ligação C++ extern "C" { typedef int (*CFT)(const void*.1. void xsort(void* p.&ccmp) .1. const void*) .sz. const void*) . // ccmp() tem ligação C void f(char* v. int sz) { qsort(v. // compare() tem ligação C++ extern "C" int ccmp(const void*. } // erro // ok // ok // erro nov/2004 Renato Maia 93 . size_t n.sz.1.1. qsort(v. const void*) .sz. size_t n. size_t sz.&ccmp) . size_t sz.sz.CFT cmp) . isort(v. isort(v. size_t n.Ponteiros para Funções C typedef int (*FT)(const void*. // CFT tem ligação C void qsort(void* p.CFT cmp) . size_t n. // cmp tem ligação C extern "C" void ysort(void* p.FT cmp) .&compare) .FT cmp) . // cmp tem ligação C++ int compare(const void*. const void*) . size_t sz.&compare) . size_t sz.

h) Módulo de Erros (error.h) Módulo Parser (parser.cpp e lexer.cpp) Renato Maia 94 nov/2004 .Exercício Dividir o programa de exemplo da calculadora em unidades de compilação diferentes (usando a mesma estrutura de módulos do último exercício) Módulo Léxico (lexer.cpp e parser.cpp e error.h) Módulo Principal (main.

MÓDULO II Mecanismos de Abstração nov/2004 Renato Maia 95 .

Mecanismos de Abstração Parte 3: Herança Múltipla Templates Parte 1: Classes Objetos Parte 2: Parte 4: Exceções Informação de Tipo Dinâmica (RTTI) Sobrecarga de Operadores Classes Derivadas nov/2004 Renato Maia 96 .

Classes nov/2004 Renato Maia 97 .

Classes As classes de C++ define um novo tipo que funcionam como um tipo básico da linguagem A forma de usar um objeto de uma classe não deve diferir do uso dos tipos básicos A única diferença deve ser na sua criação nov/2004 Renato Maia 98 .

void init(int dd.Funções Membro class Date { int d. int mm.m. m = mm. int yy) { // especifica a classe a que pertence d = dd. } }. int mm. void add_year(int n) { y += n. } void add_day(int n) { d += n. } nov/2004 Renato Maia 99 .y. int yy) . } void add_month(int n) { m += n. void Date::init(int dd. y = yy.

} void add_day(int n) { d += n. nov/2004 Renato Maia 100 . } void add_month(int n) { m += n. y.m.Controle de Acesso class Date { int d. } }. int yy) . // privado: acessível por funções membro public: // público: acessível por qualquer cliente void init(int dd. void add_year(int n) { y += n. int mm.

.Classes e Estruturas Estruturas são equivalentes a classes. } nov/2004 Renato Maia 101 . sendo que o controle de acesso padrão é o público.. struct X { // .. } Equivalente a: class X { public: // ..

Importância Controle Acesso Erros que causam inconsistência de dados privados são localizados na implementação das funções membro de acesso Alterações na implementação não são propagadas aos clientes Simplifica a utilização da classe. pois é necessário conhecer apenas a interface pública nov/2004 Renato Maia 102 .

// verifica de a data é válida } nov/2004 Renato Maia 103 . m = mm ? mm : today. 1983) . public: Date(int dd=0. int mm.int yy=0).int mm=0. 7. Date now.d. 12) . Date::Date(int dd. Date birthday(4. y = yy ? yy : today. y. // . }.m.. int yy) { d = dd ? dd : today.m.Construtores Inicição de objetos Date Date today(22) . Date july4(4. class Date { int d.y..

y.Membros Estáticos Acesso a membros estáticos Date now. static Date today. public: Date(int dd=0. mm. class Date { int d.int mm=0.int y){ today = Date(dd. now.int m. 2004).m. Date Date::today(17. static void settoday(int. 2004). // . 11. int). ou Date::settoday(22.. }. yy) } nov/2004 Renato Maia 104 . 11.settoday(22. int. 2004).. void Date::settoday(int d.int yy=0). 11.

Auto-Referência Todo objeto tem um ponteiro implícito demominado this que aponta para o próprio objeto bool Date::is_the_same(Date& other) { return *this == other. } nov/2004 Renato Maia 105 .

inline int Date::month() const { return m. y.. 1865). cout << my_date. public: int day() const { return d++..month() << "/" << my_date.day() << "/" << my_date.Funções Membro Constantes Não alteram os estado do objeto class Date { int d. // . }. } Podem ser chamadas a partir de referências constantes const Date my_date(12. } // erro: tentativa de alteração do estado int month() const. 4.year() nov/2004 Renato Maia 106 .m.

. mutable string cache.. Alteração de membros através de funções membro constantes string Date::string_rep() const { if (!cache_valid) { compute_cache() .. }.. // . string string_rep() const. public: // . } return cache. void compute_cache() const. cache_valid = true.Membros Mutáveis class Date { mutable bool cache_valid. } nov/2004 Renato Maia 107 .

Date next_weekday(Date d) .Funções Auxiliares É possível definir funções auxiliares para manipular objetos int diff(Date a. bool leapyear(int y) . Função membro vs. nov/2004 Renato Maia 108 . Date next_saturday(Date d) .Date b) . função auxiliar Função membro acessa diretamente o estado privado do objeto Função auxiliar realiza sua tarefa apenas com as operações da interface pública do objeto.

} const Matrix&m. const Vector& v class Matrix.Funções Amigas Permite acessar a interface privada das classes Vector multiply( { Vector r. for (int j = 0.. r. const Vector&) .. class Vector { float v[4] . }.v[j] . // . class Matrix { Vector v[4] . }.v[j] * v. } return r. j<4.v[i]. ) nov/2004 Renato Maia 109 .v[i] +=m. j++) r. i++) { // r[i] = m[i] * v. friend Vector multiply( const Matrix&.v[i] = 0. const Vector&) . i<4.. for (int i = 0.. friend Vector multiply( const Matrix&. // .

. // .. }. nov/2004 Renato Maia 110 . }. int* next() .. // . class List { friend int* List_iterator::next() . }...Funções Amigas Classes Amigas class List { friend class List_iterator. Todas funções membro de List_iterator se tornam amigas da classe List Funções Membro class List_iterator { // ..

como ilustrado nos exemplos anteriores: Construtor default Definir o valor da data default Use uma abordagem similar à função Date::settoday() Funções para acesso aos dados Dia. considere meses com exatos 30 dias. nov/2004 Renato Maia 111 . meses e anos Para simplificar.Exercício Implementar o tipo Date. mês e ano Funções para adicionar dias.

Objetos nov/2004 Renato Maia 112 .

Criação e Destruição Sempre que um objeto não é mais utilizado. a destruição pode ser feita automaticamente pelo compilador ou pode ser feita explicitamente nov/2004 Renato Maia 113 . ele deve ser destruído Assim como a inicialiação (ou construção) de objetos.

~Date(). class Date { cache* c.. void compute_cache () const.int mm=0.. }. // destrutor // . string rep.int yy) { c = new cache. public: Date(int dd=0.int mm. nov/2004 Renato Maia 114 . } struct cache { bool valid.int yy=0). // .. string string_rep() const.. }. // .Destrutores Libera os recursos alocados durante a construção do objeto Date::Date(int dd. } Date::~Date() { delete c.. c->valid = false..

apaga 'c' cout << "O dia " << copia..c = dia->c.string_rep() << "foi apagado\n". nov/2004 Renato Maia 115 .. copia.// copia.Cópia Default Operação de cópia default void apaga(Date *dia) { Date copia = *dia.d = dia->d. delete dia.. // erro } // . .. // destrói o objeto.

Variáveis Locais Construção: Fluxo de execução encontra a declaração da variável Destruição Variável sai do escopo Exemplo void f(int i) { if (i>0) { Date aa. } Date bb. // . } nov/2004 Renato Maia 116 .. // ....

Destruição Explicitamente através do operador delete delete d. 11. } nov/2004 Renato Maia 117 .string_rep() << "\n". delete dia. cout << "Hoje é dia " << dia.Memória Dinâmica Construção Explicitamente através do operador new Date *d = new Date(22. Cuidados Objetos destruídos delete dia. 2004). // erro Brechas de memória (memory leaks) void hoje() { Date *dia = new Date().

public: DaySequence(const Date& s. const int i) : days(i). start(s) { } } nov/2004 Renato Maia 118 . Destruição Na destruição do objeto o que pertence . na ordem que aparecem na declaração. na ordem inversa da que aparecem na declaração. Inicialização de Membros class DaySequence { const int days. Date start.Membros de Classes Construção Na construção do objeto a que pertence.

// cria 10 objetos usando o construtor Date::Date() Date vdd[10] = new Date[10]. delete[] vdd.Vetores Construção Na criação do vetor Apenas é permitido para tipos com um construtor sem parâmetros Destruição Na destruição do vetor Exemplo Date vds[10]. // destroy os 10 objetos do vetor nov/2004 Renato Maia 119 .

.Variáveis Locais Estáticas Construção Fluxo de execução encontra a declaração da variável pela primeira vez.. // apenas o d2 é contruído f(2).. Destruição Termino do programa Exemplo // Construção dos objetos f(0).. // d1 é construído f(1). } } nov/2004 Renato Maia 120 . // . if (i) { static Date d2. // . // nenhum dos objetos é criado // Declaração das variáveis void f(int i) { static Date d1.

namespace Z { Date date2. } nov/2004 Renato Maia 121 . Date X::memdate. }.Não Locais Variáveis não locais: Variáveis globais Variáveis em espaços de nomes Variáveis estáticas de classe Construção Antes no início da função main Na ordem que suas definições aparecem Destruição Após o término da função main Na ordem inversa que suas definições aparecem // apenas a definição do membro estático // declaração de variável global // declaração do membro estático da classe X // delaração da varíavel no espaço de nomes Exemplo class X { static Date memdate. Date date.

cout << cs. string& s3) { const char* cs= (s1+s2).c_str() . // problema: cs aponta para uma área desalocada if (strlen(cs=(s2+s3). string& s2.c_str())<8 && cs[0]==´a´) { // ok // qualquer uso de cs aqui é inválido } } nov/2004 Renato Maia 122 .Objetos Temporários Construção Na avaliação da expressão que os criam Destruição Ao final da avaliação da expressão que os criam Exemplo void f(string& s1.

female } const char* s. Name* lookup(const char *) .Exercício Implementar o tipo Table. class Table { Name* p. que deve oferecer a seguinte interface: struct Name { enum Gender { male. size_t sz. nov/2004 Renato Maia 123 . bool insert(Name&) . }. int c. ~Table(). public: Table(size_t s = 15). Gender g. }.

Sobrecarga de Operadores nov/2004 Renato Maia 124 .

* (Seleção de membros através de ponteiros para função) nov/2004 Renato Maia 125 . delete[] +| ~ -= << >= -> Operadores que NÃO podem ser redefinidos :: (Resolução de escopo) . (Seleção de membros) .Operadores Disponíveis * ! *= >> && [] / = /= >>= || () % < %= <<= ++ new ^ > ^= == -new[] & += &= != ->* delete Operadores que podem ser redefinidos |= <= .

im. Função Auxiliar complex operator+(complex. double) . public: complex(double r.Funções Operadoras Função Membro class complex { double re. nov/2004 Renato Maia 126 . }. double i=0) : re(r) . im(i) { } complex operator+(complex) .

operator@(b) Operadores Unários (a@) a.operator@() nov/2004 Renato Maia 127 . b) ::operator@(a) a.Casamento de Função Operador Escolha da função operador para um operador @ Operadores Binários (a@b) ou ou ::operator@(a.

// decremento posfixo X operator-(). // menos unário X operator-(X. // & binário (e bit a bit) X operator++() .X) .X) .X.int) . // menos binário X operator--(X&. // erro: / unário }. // erro: ternário X operator%(X) . // & unário (endereço de) X operator&(X) . // erro: ternário X operator/() . // erro: % unário nov/2004 Renato Maia 128 .Exemplos de Sobrecarga de Operadores class X { // members (with implicit 'this' pointer): X* operator&() .X) . // erro: nenhum operando X operator-(X. // nonmember functions: X operator-(X) . // incremento prefixo X operator&(X.

retorna o valor do segundo parâmetro) Entretanto. esses significados podem ser redefinidos através da sobrecarga de operadores nov/2004 Renato Maia 129 . faz cópia dos valores dos membros) & (endereço de. retorna o endereço do objeto) . (seqüência.Significados Predefinidos As funções operator=. operator[]. operator() e operator-> devem ser definidas como funções membro não estáticas Apenas alguns operadores já possuem um significado predefinido = (atribuição.

Date::operator=(const Date& other) { if (*this != other) { delete c. // copia = data. y = other. } } Renato Maia nov/2004 130 .d. c = new cache. d = other.m. m = other. y = other. d = other.y.d. c->valid = false. Construtor de cópia Date::Date(const Date& other) { c = new cache. 4.Cópia de Objetos // exemplo: // Date copia = data. m = other. 1876).m. } Operador de atribuição // exemplo: // Date copia(2.y. c->valid = false.

se X é definido num espaço de nomes N.Procura pela Implementação de Operadores Considere a expressão x@y. As mesmas regras para casamento de funções sobrecarregadas são aplicadas a operadores. procura por declarações de @ em M. procura por declarações de @ em N Adicinonalmente. todas as declarações de operator@ são levadas em consideração para determinar a que se adequa a expressão. se Y é definido num espaço de nomes M. (x é do tipo X e y é do tipo Y) Se X é uma classe e define operator@ como um membro essa função membro como operadora Caso contrário Procura por declarações de operator@ no contexto de x@y Adicinonalmente. Neste último caso. nov/2004 Renato Maia 131 .

// significa operator==(x.Conversões Implícitas bool operator==(complex. // significa operator==(complex(3). x==3. void f(complex x.y) x==y. complex y) { // significa operator==(x.y) } Essas conversão não se aplicam para funções operadoras membro nov/2004 Renato Maia 132 .complex(3)) 3==y.complex) .

} // conversão para int operator int() const { return v.Operadores de Conversão Explícita class Tiny { char v. } Tiny& operator=(int i) { assign(i) . } public: Tiny(int i) { assign(i) . } nov/2004 Renato Maia 133 . return *this. } }. } int Tiny::operator int() const { return v. Atenção // certo // errado Tiny::operator int() const { return v. else v=i. void assign(int i) { if (i&~077) v=0.

o compilador informará o erro. Tome cuidado com conversões inesperadas (ou a falta delas) class Quad { public: Quad(double) .. Quad r2 =Quad(a1)+a2. }. void f(double a1.Quad) . double a2) { Quad r1 = a1+a2. } // adição com precisão dupla // força aritmética da classe quad nov/2004 Renato Maia 134 . // . Quad operator+(Quad.Ambigüidades Sempre que a combinação de construtores e operadores de conversão gerarem ambiguidade na resolução de funções sobrecarregadas..

String s = 'a'.. // prealoca n bytes String(const char* p) . // valor inicial é uma string C string p }. nov/2004 Renato Maia 135 . explicit String(int n) . Solução class String { // .Construtores Explícitos // inicializa z com complex(2) // cria uma string com int('a') elementos Considere complex z = 2..

double val. ++p) if (s == p->name) return p->val. vec.push_back(Pair(s. for (. double v =0) :name(n) . for (. ++p) cout << p->name << ": " << p->val << ´\n´.begin().end(). return vec. p!=vec. } class Assoc { struct Pair { string name.end(). Pair(string n ="". public: Assoc() {} double& operator[](const string&) .Operador de Indexação double& Assoc::operator[](const string& s) { vector<Pair>::iterator p=vec. // privado para prevenir cópia Assoc(const Assoc&) .begin().0)) .val. Assoc& operator=(const Assoc&) . void Assoc::print_all() const { vector<Pair>::const_iterator p=vec. p!=vec. } nov/2004 Renato Maia 136 . }.back(). void print_all() const. val(v) { } }. vector<Pair> vec.

} void main() { Add func(2.Operador de Chamada de Função // salva o valor // adiciona valor class Add { complex val. i++) func(vc[i]). void for_each(Add& func) { for (int i = 0. complex vc[10]. } }. public: Add(complex c) { val = c. } void operator()(complex& c) const { c += val.i) . for_each(func). double i) { val = complex(r. i < 10. } Add(double r. } nov/2004 Renato Maia 137 . 3).

// ok } nov/2004 Renato Maia 138 ...operator->().operator–>())–>m = 7 void f(Ptr p) { p->m = 7. Declaração (operador unário) class Ptr { /* . } Uso void g(Ptr p) { X* q1 = p->. */ Transformação // (p. }.Operador de Dereferência X* operator->(). // erro de sintaxe X* q2 = p.

Ptr_to_T& operator++() . int size. s // prefixo // posfixo // prefixo // posfixo // prefixo nov/2004 Renato Maia 139 . Ptr_to_T& operator--(). int s) . Ptr_to_T operator--(int) . public: Ptr_to_T(T* p. T&operator*() . // associa a pos. T* array.Operadores Unários Posfixos class Ptr_to_T { T* p. T* v. p do vetor v de tam. Ptr_to_T operator++(int) . }.

Classes Derivadas nov/2004 Renato Maia 140 .

public: void print() const. class Employee { string name.. // . }... // .. short level. nov/2004 Renato Maia 141 . }. // . public: void print() const.. } // .Classes Derivadas class Manager : public Employee { set<Employee*> group.. Date hiring_date.. string get_name() const { return name. shot department..

.... group level . nov/2004 Renato Maia 142 ..Estrutura de Objetos Manager: name department . Employee: name department ..

elist.push_front(&m1). mas funciona pm->level = 2. // força bruta. // desastre: ee não tem um 'level' pm = static_cast<Manager*>(pe) . // ok: pm aponta para mm que tem um 'level' } nov/2004 Renato Maia 143 .push_front(&e1).Polimorfismo void f(Manager m1. // ok: todo Gerente é um Empregado Manager* pm= &ee. } void g(Manager mm. // erro: nem todo Empregado é um Gerente pm->level = 2. elist. Employee e1) { list<Employee*> elist. Employee ee) { Employee* pe= &mm.

e. } nov/2004 Renato Maia 144 . protected) void Manager::print() const { Employee::print(). de Funções Membro Não é possível acessar membros privados em classes derivadas void Manager::print() const { // erro: name é privado cout << "Name: "<< name << '\n'. cout << "\tDept:\t"<< department << '\n'. // erro: department é privado cout << "\tLevel:\t" << level << '\n'.size() << '\n'.size() << '\n'. cout << "\tTeam:\t" << group. // cuidado: print() não qualificado causa recursão cout << "\tLevel:\t" << level << '\n'.Implement. i. cout << "\tTeam:\t" << group. } É necessário usar a interface pública (e protegida.

nov/2004 Renato Maia 145 . Escopo Protegido (protected) Nomes podem ser usados em funções membro e funções amigas da classe e nas funções membro e funções amigas das suas classes derivadas. Escopo Público (public) Nomes podem ser usados em quaisquer funções.Controle de Acesso Escopo Privado (private) Nomes podem ser usados em funções membro e funções amigas da classe.

class Z : private B { /* ...Acesso a Membros Herdados class X : public B { /* .. Acesso aos membros públicos e protegidos de B e conversão de X* para B* só pode ser feito em funções membro e amigas de X. */ }.. Adicionalmente. */ }. class Y : protected B { /* . Acesso aos membros públicos e protegidos de B e conversão de Y* para B* só pode ser feito em funções membro e amigas de Y e de suas classes derivadas. o acesso aos membros protegidos de B só pode ser feito em funções membro e amigas de Z e de suas classes derivadas. Acesso aos membros públicos de B e conversão de Z* para B* só pode ser feito pode ser feito de qualquer função. Renato Maia 146 nov/2004 . */ }...

int d) : name(n).Construção Classe Base Employee(const string& n. int lvl) : Employee(n. int d. department(d) { // … } Classe Derivada Manager(const string& n. level(lvl) // não é possível iniciar diretamente // os membros de Employee { // … } nov/2004 Renato Maia 147 . d).

slice_copy(m).Cópia Fatiada Exemplo void f(const Manager& m) { Employee e = m. 1. Manager m("John Gee". // atribui a parte Employee de m a e } Cuidado void slice_copy(Employee ee) { ee. // objeto Employee criado com os dados de m nov/2004 Renato Maia 148 . } // .. // constrói e a partir da parte Employee de m e = m..print(). 4).

virtual_call(&m).Funções Virtuais Definição class Employee { // ... Manager m("John Gee". virtual void print() const. 4). nov/2004 Renato Maia 149 . }.. // a função print adequada é chamada } // . 1.. Exemplo void virtual_call(Employee* ee) { ee->print().

}. virtual bool is_closed() = 0. virtual void draw() = 0. // . nov/2004 Renato Maia 150 . int radius. } Circle(Point p. Não é possível criar objetos de classes abstratas Shape s. */ }. int r) .. }.. Permite definir classes com funções sem implementação class Shape { public: // funções virtuais puras virtual void rotate(int) = 0. bool is_closed() { return true. // erro: Shape é abstrata class Circle : public Shape { public: // define funções virtuais herdadas void rotate(int) { } void draw() .Classes Abstratas Classes abstratas somente são utilizadas como classe base class Point { /* .. private: Point center..

}. // acesso direto p->*pmd = "string" . typedef const char* Class::*PMD. // acesso através de ponteiro para membro } nov/2004 Renato Maia 151 . // chamada através de ponteiro para membro PMD pmd = &Class::memb_data. // tipo ponteiro para função membro typedef void (Class::*PMF)() . p->memb_func() .Ponteiros para Membros struct Class { const char* memb_data. // tipo ponteiro para membro de dado void f(Class* p) { PMF pmf = &Class::memb_func(). p->memb_data() . virtual void memb_func() = 0. // chamada direta (p->*pmf)() .

classe Date) que façam tarefas simples e de forma eficiente. Se possível utilizando a classe concreta. da mesma forma se utiliza um int na classe Date. Sempre tente definir um bom conjunto de tipos como base da sua aplicação e defina esses tipos através de classes concretas nov/2004 Renato Maia 152 .g. Se o comportamento de uma classe concreta não é adequado.Propósito de Classes Concretas Classes concretas são usadas para definir novos tipo (e. uma nova classe deve ser construída.

Herança Múltipla nov/2004 Renato Maia 153 .

Problema Suponha um sistema de simulação onde cada elemento simulado realiza uma tarefa e possui uma representação visual dessa tarefa. Cada elemento tem o comportamento de uma tarefa e de algo visual. Definimos duas classes: Task: define o comportamento relativo a execução de uma tarefa Displayed: define o comportamento relativo a exibição visual de informações nov/2004 Renato Maia 154 .

A implementação da simulação de um satélite pode ser feita numa única classe que herde as interfaces e implementações fornecidas pelas classes Task e Displayed. Satellite dados funções nov/2004 Renato Maia 155 .Solução com Herança Múltipla Task dados funções Displayed dados funções Para cada elemento simulado a sua repesentação visual (Displayed) é muito dependente da sua tarefa (Task).

Herança Múltipla Classe com herança múltipla class Satellite : public Task. public Displayed { // .delay(10) ..transmit() .. // Satellite::transmit() } nov/2004 Renato Maia 156 . // Displayed::draw() s. // Task::delay() s. }. É possível acessar membros das duas classes base void f(Satellite& s) { s.draw() .

// passa um ponteiro para a parte Task } nov/2004 Renato Maia 157 . void g(Satellite* p) { highlight(p) . void suspend(Task*) . // passa um ponteiro para a parte Displayed suspend(p) .Herança Múltipla Objetos de classes com herança múltipla de comportam como um objeto de cada classe base void highlight(Displayed*) .

. void f(Satellite* sp) { debug_info* dip = sp->get_debug() ... }. }. virtual debug_info* get_debug() . // erro: ambíguo dip = sp->Task::get_debug() . virtual debug_info* get_debug() .Resolução de Ambigüidade class Task { // . class Displayed { // .. // ok dip = sp->Displayed::get_debug() . // ok } nov/2004 Renato Maia 158 .

. debug_info* dip2 = Displayed::get_debug() . return dip1->merge(dip2) . public Displayed { // . debug_info* get_debug() // defefine Task::get_debug() e // Displayed::get_debug() { debug_info* dip1 = Task::get_debug() . nov/2004 Renato Maia 159 ..Redefinição de Membros Definir na classe derivada o comportamento adequado class Satellite : public Task. } }.

Classes Base Duplicadas Link dados funções Link dados funções struct Link { Link* next. Displayed dados funções // . Satellite dados funções nov/2004 Renato Maia 160 . }. }.. class Task : public Link { // o Link é usado para manter // a lista de todas Tasks. }.... Task dados funções // . class Displayed : public Link { // o Link é usado para manter // a lista de todos Displayed.

Task* t.next = s. // erro: ambíguo s->Task::next = t.Classes Base Duplicadas Atenção: void insert_before(Satellite* s. Displayed* d) { s->next = t. d.next = s.next. s->Displayed::next = d.next. t.next. } nov/2004 Renato Maia 161 .

Classes Base Virtuais Link dados funções Classes base virtuais não são duplicadas quando herdadas Task dados funções class Task : public virtual Link { // . }.. Displayed dados funções Satellite dados funções nov/2004 Renato Maia 162 .. }... class Displayed : public virtual Link { // .

*/ } . class DD : public D1. B* pb = pd.. }. class D1 : public virtual B { /* ...Controle de Acesso struct B { int m.. private D2 { /* .. // . // ok: accessível através de D1 nov/2004 Renato Maia 163 .. */ }.. DD* pd = new DD. // ok: accessível através de D1 int i1 = pd->m.. */ } . class D2 : public virtual B { /* .

Classes intimamente dependentes Reduzir o uso de funções amigas juntando a implementação de duas classes intimamente dependentes numa única. Reutilização de código Permitir compor uma nova classe a partir da implementação de outras nov/2004 Renato Maia 164 .Usando Herança Múltipla Múltiplas interfaces Compor uma classe com uma interface composta da interface de duas outras classes.

Templates nov/2004 Renato Maia 165 .

nov/2004 Renato Maia 166 ...Declaração template<class C> class String { struct Srep. C read(int i) const. }. public: String(). String(const C*). Srep *rep. // . String(const String&).

C()) . template<class C> C String<C>::read(int i) const { return rep->s[i] . // número de elementos // . // ponteiro para elementos int sz.. }. } template<class C> String<C>::String() { p = new Srep(0.Definição template<class C> struct String<C>::Srep { C* s. } nov/2004 Renato Maia 167 ..

// escreve o resultado } Versão com Jchar (tipo fictício para representar caracteres japoneses) int main() { String<Jchar> buf. while (cin>>buf) m[buf]++. map<String<Jchar>.int> m. while (cin>>buf) m[buf]++.Instanciação Versão com char int main() { String<char> buf.int> m. // escreve o resultado } nov/2004 Renato Maia 168 . map<String<char>.

nov/2004 Renato Maia 169 . /* … */ } Outros templates template<class T. }. Xrefd<Entry.. int sz. C<T*> refs. etc.) template<class T.Parâmetros Um tipo template<class C> class String { /* … */ } Uma constante de um tipo básico (int.. int i> class Buffer { T v[i].vector> x1. template<class> class C> class Xrefd { C<T> mems. double. // .

String<unsigned char> s2. 20-10> b3. Buffer<char. As seguintes variáveis são do mesmo tipo s1 s2 b1 s4 s3 b2 nov/2004 Renato Maia 170 .Equivalência de Tipos Considere String<char> s1. // o compilador pode avaliar expressões constantes. typedef unsigned char Uchar. Buffer<char. 10> b2. String<char> s4. String<Uchar> s3.

p=p->suc) cout << p->val << '\n'. void f(List<int>& li. List<Rec>& lr) { li. const T& v) : suc(s) . public: List() : head(7) { } // erro: ponteiro inicializado com int void print_all() { for (Link* p = head. val(v) { } // erro de sintaxe: faltando um ponto e vírgula } Link* head. } }. // erro: se Rec não define o operador << } nov/2004 Renato Maia 171 .Corretude do Template template<class T> class List { struct Link { Link* suc. Link(Link* s. // ok lr. T val. p.print_all() .print_all() .

j-=gap) if (v[j+gap]<v[j]) swap(v[j]. } nov/2004 Renato Maia 172 . const size_t n = v. 84). vector<string>& vs) { sort(vi) . v[j+gap]). i++) for (int j=i-gap. // sort(vector<string>&).Template de Funções template<class T> void sort(vector<T>& v) { // Shell sort (Knuth.size() . 0<gap. sort(vs) . 0<=j. // sort(vector<int>&). } void f(vector<int>& vi. Vol. gap/=2) for (int i=gap. 3. pg. for (int gap=n/2. i<n.

int>(i) . erro nov/2004 Renato Maia 173 . U is int // T é char. } void g(int i) { implicit_cast(i) . U is double // T é char*. class U> T implicit_cast(U u) { return u. implicit_cast<double>(i) .Definição dos Parâmetros de Uma Função Template template<class T. implicit_cast<char. } // error: não pode deduzir T // T é double. implicit_cast<char*. U é int. double>(i) .

int>(i) . class U> T implicit_cast(U u) { return u. erro nov/2004 Renato Maia 174 .Parâmetros Default template<class T = int. U is int // T é double. double>(i) . } // T é int. U is double // T é char*. U is int // T é char. implicit_cast<char. implicit_cast<char*. U é int. } void g(int i) { implicit_cast(i) . implicit_cast<double>(i) .

Vector() : Base() {} explicit Vector(int i) : Base(i) {} T*& elem(int i) { return static_cast<T*&>(Base::elem(i)) .Especializações Vector<Shape*> vps. nov/2004 Renato Maia 175 .. template<class T> class Vector<T*> : private Vector<void*> { public: typedef Vector<void*> Base. } T*& operator[](int i) { return static_cast<T*&>(Base::operator[](i)) . Vector<char*> vpc. Vector<Node*> vpn. } // . }..

. não um set<Shape*> } nov/2004 Renato Maia 176 . // erro.... */ }.Templates e Herança class Shape { /* . class Triangle : public Shape { /* . */ }...insert(new Triangle()) . } void g(set<Circle*>& s) { f(s) .... void f(set<Shape*>& s) { // .. // . s é um set<Circle*>. */ }. class Circle : public Shape { /* . s.

Exceções nov/2004 Renato Maia 177 .

} nov/2004 Renato Maia 178 .Lançamento struct Range_error { int i. Range_error(int ii) { i = ii. char to_char(int i) { if (i<numeric_limits<char>::min() || numeric_limits<char>::max()<i) throw Range_Error(). } }. return c.

. // . } } nov/2004 Renato Maia 179 . } catch (Range_error) { cerr << "oops\n".Captura void g(int i) { try { char c = to_char(i) ..

. class Underflow: public Matherr{ }. class Zerodivide: public Matherr{ }. */ } catch (Overflow) { // trata Overflow ou qualquer coisa que derive de Overflow } catch (Matherr) { // trata qualquer Matherr que são seja Overflow } } nov/2004 Renato Maia 180 . void f() { try { /* . class Overflow: public Matherr{ }..Hierarquia de Exceções class Matherr{ }.

Re-Lançamento void h() { try { // código que pode lançar exceções Matherr } catch (Matherr) { if (pode_tratar_completamente) { // trata Matherr } else throw. // re-lança a exceção } } nov/2004 Renato Maia 181 .

..Captura de Qualquer Exceção void m() { try { // faz algo } catch (.) { // limpeza throw. } } // trata qualquer exceção nov/2004 Renato Maia 182 .

) { // trata qualquer exceção } catch (std::exception& e) { // trata qualquer exceção da biblioteca padrão } catch (std::bad_cast) { // trata erros de conversão dinâmica } } nov/2004 Renato Maia 183 ..Ordem de Captura void g() { try { /* ... */ } catch (..

// .Exceções em Construtores Vector* f(int i) { try { Vector* p = new Vector(i) . nov/2004 Renato Maia 184 . }.. // . Vector::Vector(int sz) { if (sz<0 ||max<sz) throw Size() .. } // ... enum {max = 32000 }.. return p.. } catch(Vector::Size) { // lida com erro de tamanho } } class Vector { public: class Size{ }.

.. public: X(int) . }.. // .. nov/2004 Renato Maia 185 . // ... } class X { Vector v.Exceções na Iniciação de Membros X::X(int s) try :v(s) // iniciação de v por s { // corpo do construtor } // captura de exceções lançadas por v catch (Vector::Size) { // .

.) { if (uncaught_exception()) // faça algo else throw..Exceções em Destrutores Durante o lançamento de uma exceção os objetos que perdem seu escopo são destruídos Exceções lançadas por destrutores durante o lançamento de uma exceção causam o encerramento do programa Para evitar essa situação usa-se a função da biblioteca padrão uncaught_exception X::~X() try { f(). } catch (. // re-lança } { nov/2004 Renato Maia 186 .

.. } catch (x3) { throw... */ } catch (x2) { throw.) { std::unexpected() .. } // encerra a aplicação nov/2004 Renato Maia 187 .. */ } Equivalente a: void f() try { /* .Especificação de Exceções void f() throw (x2. } catch (. x3) { /* .

Exceções não capturadas resultam na chamada de std::terminate. terminate_handler set_terminate(terminate_handler) . que chama um tratador definido pela seguinte função: typedef void (*unexpected_handler)() .Exceções Não Capturadas Exceções não especificadas resultam na chamada de std::unexpected. que chama um tratador definido pela seguinte função: typedef void (*terminate_handler)() . unexpected_handler set_unexpected(unexpected_handler) . nov/2004 Renato Maia 188 .

Exceções Padrão lançada pelo operador new lançada pelo operador dynamic_cast lançada pelo operador typeid lançada por uma função com especificação de exceções Lançadas pela linguagem bad_alloc bad_cast bad_typeid bad_exception Lançadas pela bibioteca padrão exception logic_error runtime_error range_error overflow_error underflow_error length_error domain_error out_of_range invalid_argument bad_alloc bad_cast bad_exception bad_typeid out_of_range nov/2004 Renato Maia 189 .

Run-Time Type Information (RTTI) nov/2004 Renato Maia 190 .

Receiver Transmisser Radio nov/2004 Renato Maia 191 . */ }.. */ }.. */ }.Exemplo Storable Component Component class Component : public virtual Storable { /* .. class Receiver : public Component { /* ... */ }... class Transmitter : public Component { /* . public Transmitter { /* .. class Radio : public Receiver.

else { // Opa! Não é possível ecoar } } nov/2004 Renato Maia 192 .Conversão Dinâmica void echo_handler(Receiver* pr) { // pw aponta para um Transmitter? if (Transmitter* pt = dynamic_cast<Transmitter*>(pr)) pt->send(pr->receive()) .

// base não polimórfica (não tem funções virtuais) }.Classes Não-Polimórficas class My_storable: public Storable { // . // erro: Date não // é polimórfica } nov/2004 Renato Maia 193 .. // base polimórfica (tem funções virtuais) }. void g(Storable* pb. Date* pd) { My_storable* pd1 = dynamic_cast<Storable*>(pb) ... // ok My_date* pd2 = dynamic_cast<My_date*>(pd) .. class My_date : public Date { // .

.receive()).. } catch (bad_cast){ /* . t. */ } nov/2004 Renato Maia 194 .Conversão de Referências O operador dynamic_cast em referências lança a exceção bad_cast try { Transmitter& t = dynamic_cast<Transmitter&>(r).send(r.

.. Component* pc = dynamic_cast<Component*>(ps) .Ambigüidades Objetos da classe Radio são compostos por dois objetos Component (de Receiver e Transmitter) void h1(Radio& r) { Storable* ps = &r. // . // pc = 0 } nov/2004 Renato Maia 195 .

sem verificação pr = dynamic_cast<Radio*>(prec) . // ok. // Storable é base virtual pr = static_cast<Radio*>(ps) . // ok. // erro: conversão de base virtual pr = dynamic_cast<Radio*>(ps) . // ok. verificação dinâmica Storable* ps= &r. // Receiver é uma base de Radio Radio* pr = static_cast<Radio*>(prec) .Navegando na Hierarquia de Classes void g(Radio& r) { Receiver* prec= &r. verificação dinâmica } nov/2004 Renato Maia 196 .

Construção e Destruição de Objetos Durante a construção ou destruição de um objeto. nov/2004 Renato Maia 197 . mesmo que seja a criação de um objeto de uma classe derivada. apenas parte dele existe Na execução do construtor da classe Receiver para um objeto Radio o objeto Radio ainda não existe completamente. É bom evitar chamar funções virtuais na construção ou destruição de objetos. pois pode ocasionar a chamada da função da classe sendo construída.

const type_info& typeid(type_name) throw(bad_typeid) . nov/2004 Renato Maia 198 . . const type_info& typeid(expression) .Operador typeid Pseudo declaração class type_info.

. private: type_info(const type_info&) . // . bool operator== (const type_info&) const. bool before(const type_info&) const. type_info& operator=(const type_info&) .Informações de Tipo // é polimórfico // pode ser comparado // ordem // nome do tipo // evita cópia // evita cópia class type_info { public: virtual ~type_info() . nov/2004 Renato Maia 199 . const char* name() const. }.. bool operator!= (const type_info&) const.

Pascal. } Programadores de linguagems procedurais C..Mal Uso do RTTI void rotate(const Shape& r) { if (typeid(r) == typeid(Circle)) { // do nothing } else if (typeid(r) == typeid(Triangle)) { // rotate triangle } else if (typeid(r) == typeid(Square)) { // rotate square } // . Modula-2 e Ada nov/2004 Renato Maia 200 ..

// ... */ }. // . class Ship : public Object{ /* . Object* p = c->get() .. Ship* f(Ship* ps. // polimórfico class Container : public Object { public: void put(Object*) . if (Ship* q=dynamic_cast<Ship*>(p)) { return q. } else { // faça algo (lança um erro) } } nov/2004 Renato Maia 201 . }.Container* c) { c->put(ps) .Mal Uso do RTTI Programadores de linguagens altamente dependentes de verificação dinâmica de tipos Smaltalk.... Java(?) class Object{ /* ... Object* get() . */ }. Lisp.

MODULO III Biblioteca Padrão nov/2004 Renato Maia 202 .

Biblioteca Padrão Parte 3: Strings Streams Parte 1: Visão Geral Contêiners Parte 2: Iteradores Algoritmos Objetos Função nov/2004 Renato Maia 203 .

Visão Geral nov/2004 Renato Maia 204 .

Strings nov/2004 Renato Maia 205 .Organização I/O Streams. etc. etc. ordenação. alocadores. objetos função. buffers. etc. Diagnóstico Numérica Complexos. RTTI. Contêiners Localização Estruturas de dados Utilidades Suporte C++ Operadores. etc. pares. operações sobre vetores e matrizes. Configurações regionais Limites numéricos. arquivos. assetivas. etc. Iteradores Algoritmos Busca. etc. Exceções.

Standart Template Library Algoritmos (operações) Contêiners (estruturas de dados) Iteradores (acesso genérico) nov/2004 Renato Maia 206 .

Contêiners nov/2004 Renato Maia 207 .

Operações Comuns

template <class T, class A = allocator<T> > class std: :vector { public: // Tipos typedef T value_type; typedef A allocator_type; typedef typename A::size_type size_type; typedef typename A::difference_type difference_type; typedef /* DEP. DE IMPLEMENT. */ iterator; // algo como um T* typedef /* DEP. DE IMPLEMENT. */ const_iterator; // +/- const T* typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef typename A::pointer pointer; // para elemento typedef typename A::const_pointer const_pointer; typedef typename A::reference reference; // de elemento typedef typename A::const_reference const_reference; ...
Renato Maia 208

nov/2004

Operações Comuns (cont)

template <class T, class A = allocator<T> > class vector { public: // ... // iteratores: iterator begin() ; // aponta para o primeiro const_iterator begin() const; iterator end() ; // aponta para um após o último const_iterator end() const; reverse_iterator rbegin() ;// aponta para o último const_reverse_iterator rbegin() const; reverse_iterator rend() ; // aponta para um antes do primeiro element of reverse sequence const_reverse_iterator rend() const ; // ... };
Renato Maia 209

nov/2004

Programação Genérica

template<class C> typename C::value_type sum(const C& c) { typename C::value_type s = 0; typename C::const_iterator p = c.begin() ; // começa do começo while (p!=c.end()) { // continue até o fim s += *p; // pega um valor ++p; // faça p apontar para o próximo elemento } return s; }

nov/2004

Renato Maia

210

Características Comuns
Tipo dos elementos Tipo do alocador usado Tipo do Tipo do Tipo do Tipo do iterador iterador constante iterador reverso iterador reverso constante

Tipos parametrizados

value_type allocator_type

Tipos de iteradores

iterator const_iterator reverse_iterator const_reverse_iterator

Tipos ponteiro e referência
Tipo ponteiro para o elemento Tipo ponteiro constante para o elemento Tipo referência para o elemento Tipo referência constante para o elemento

pointer const_pointer reference const_reference

nov/2004

Renato Maia

211

Características Comuns
Cria o contêiner vazio Copia um contêiner de mesmo tipo Cria um contêiner e copia em [begin, end[ Apaga todos os elementos e libera a memória

Criação e destruição

Construtor default Construtor de cópia Construtor(begin, end) Destrutor

Comparação
Verifica se o conteúdo é igual Verifica se o conteúdo não é igual Verifica se o conteúdo é lexicograficamente menor Verifica se o conteúdo é lexicograficamente maior Verifica se o conteúdo é lexicograficamente menor ou igual Verifica se o conteúdo é lexicograficamente maior ou igual Atribui o conteúdo de outro contêiner

== != < > <= >= =

nov/2004

Renato Maia

212

end[ Remove todos os elementos Acesso size() empty() max_size() begin() end() rbegin() rend() Alteração swap(c) insert(pos.end) clear() nov/2004 Renato Maia 213 .Características Comuns Devolve o número de elementos Verifica se o contêiner está vazio Devolve o número máximo de elementos Iterador para o início Iterador para um após o fim Iterador para o início da iteração reversa Iterador para um após o fim da iteração reversa Troca o conteúdo com outro contêiner (::swap(c.elem) erase(beg.c)) Insere uma cópia de elem (significado de pos varia) Remove todos os elementos em [beg.

int> map. pois os contêiners guardam cópias de elementos.Requisitos dos Elementos Cópia Os elementos devem poder ser copiados. map[name] = 11. cout << map["Renato"] << '\n'. nov/2004 Renato Maia 214 . Comparação Containers associativos fazem comparação dos elementos nas buscas (< e =) O que acontece no código abaixo? std::map<char*. char name[] = "Renato".

vector<MyClass> vobj. nov/2004 Renato Maia 215 . vector<vector<string> > mtrstr.Contêiner Vetor seqüência de elementos para acesso aleatório ☺ Acesso aleatório Alterações no meio ou no início Cabeçalho #include <vector> Parâmetros Tipo dos elementos armazenados Tipo do gerenciador de memória (opcional) Exemplos vector<int> vi.

end[ Atribui um vetor com n cópias de val assign(beg.Operações do Contêiner Vetor n posições com valor default n posições com valor val Construtores vector(n) vector(n. end) assign(n.val) Acesso Indexação sem verificação Indexação com verificação Primeiro elemento Último elemento [pos] at(pos) front() back() nov/2004 Renato Maia 216 .val) Atribuição Atribui um vetor com os valores de [beg.

val) insert(pos.val) Alteração no final push_back(val) pop_back() Alteração na seqüência insert(pos.Operações do Contêiner Vetor Tamanho de posições alocadas Reserva espaço para um total de n elemetos Altera o número de elementos Idem. end) erase(pos) nov/2004 Renato Maia 217 .end[ antes de pos Apaga elemento em p Capacidade capacity() reserve(n) Tamanho resize(n) resize(n.beg. val define o valor de inicialização Adiciona ao final Remove o último elemento Insere cópia de val antes de pos Insere n cópias de val antes de pos Insere os valores de [beg.val) insert(pos.n.

list<MyClass> lobj. nov/2004 Renato Maia 218 .Contêiner Lista seqüência de elementos para acesso seqüêncial ☺ Alterações na ordem dos elementos ☺ Inserções em quaisquer pontos da seqüência Acesso aleatório Cabeçalho #include <list> Parâmetros Tipo dos elementos armazenados Tipo do gerenciador de memória (opcional) Exemplos list<int> li. list<vector<string> > lvet.

val) Atribuição Atribui um vetor com os valores de [beg.end[ Atribui um vetor com n cópias de val assign(beg.val) Acesso Primeiro elemento Último elemento front() back() nov/2004 Renato Maia 219 . end) assign(n.Operações do Contêiner Lista n posições com valor default n posições com valor val Construtores list(n) list(n.

end[ antes de pos Apaga elemento em p insert(pos. end) erase(pos) nov/2004 Renato Maia 220 .val) insert(pos.n.Operações do Contêiner Lista Adiciona ao final Remove o último elemento Adiciona um novo primeiro elemento Remove o primeiro elemento Alteração nas extremindades push_back(val) pop_back() push_front(val) pop_front() Alteração na seqüência Insere cópia de val antes de pos Insere n cópias de val antes de pos Insere os valores de [beg.val) insert(pos.beg.

list.Operações do Contêiner Lista Remove todos os elementos com valor val Remove os elementos que op(elem)==true Remove duplicatas Remove duplicatas que op(elem)==true Remoção remove(val) remove_if(op) unique() unique(op) Alterações sem cópia splice(pos.p) move *p de list para antes de pos splice(pos..list) incorpora todos os elementos de list para antes de pos splice(pos.list.end[ .op) Internala com list mantendo a ordenação (op) reverse() Inverte a ordem dos elementos nov/2004 Renato Maia 221 .end) move os elementos de list em [beg.beg. idem sort() Ordena usando operador < sort(op) Ordena usando comparação cmp merge(list) Internala com list mantendo a ordenação (<) merge(list..

deque<vector<string> > dqvet. nov/2004 Renato Maia 222 . deque<MyClass> dqobj.Contêiner Fila Dupla seqüência de elementos para acesso nas extremidades ☺ Acesso nas extremidades Alterações no meio da seqüência Cabeçalho #include <deque> Parâmetros Tipo dos elementos armazenados Tipo do gerenciador de memória (opcional) Exemplos deque<int> dqi.

Operações do Contêiner Fila Dupla n posições com valor default n posições com valor val Construtores deque(n) deque(n.val) Acesso Indexação sem verificação Indexação com verificação Primeiro elemento Último elemento [pos] at(pos) front() back() nov/2004 Renato Maia 223 .end[ Atribui um vetor com n cópias de val assign(beg.val) Atribuição Atribui um vetor com os valores de [beg. end) assign(n.

Operações do Contêiner Fila Dupla
Altera o número de elementos Idem, val define o valor de inicialização

Tamanho

resize(n) resize(n,val)

Alteração nas extremindades
Adiciona ao final Remove o último elemento Adiciona um novo primeiro elemento Remove o primeiro elemento

push_back(val) pop_back() push_front(val) pop_front()

Alteração na seqüência
Insere cópia de val antes de pos Insere n cópias de val antes de pos Insere os valores de [beg,end[ antes de pos Apaga elemento em p
Renato Maia 224

insert(pos,val) insert(pos,n,val) insert(pos,beg, end) erase(pos)

nov/2004

Contêiner Pilha

Adaptador de contêiner seqüencial para acesso FIFO Cabeçalho

#include <stack>

Parâmetros

Tipo dos elementos armazenados Tipo dos contêiner seqüêncial utilizado (default deque<T>)

Exemplos

stack<int> si; stack<MyClass, vector<MyClass>> stkobj;

nov/2004

Renato Maia

225

Operações do Contêiner Pilha

template<class T, class C = deque<T> > class stack { protected: C c; public: typedef typename C::value_type value_type; typedef typename C::size_type size_type; typedef C container_type; explicit stack(const C& a =C()) : c(a) { } bool empty() const { return c.empty() ; } size_type size() const { return c.size() ; } value_type& top() { return c.back() ; } const value_type& top() const { return c.back() ; } void push(const value_type& x) { c.push_back(x) ; } void pop() { c.pop_back() ; } };

nov/2004

Renato Maia

226

Contêiner Fila

Adaptador de contêiner seqüencial para acesso LIFO Cabeçalho

#include <queue>

Parâmetros

Tipo dos elementos armazenados Tipo dos contêiner seqüêncial utilizado (default deque<T>)

Exemplos

queue<int> qi; queue<MyClass, vector<MyClass>> queobj;

nov/2004

Renato Maia

227

Operações do Contêiner Fila

template<class T, class C = deque<T> > class queue { protected: C c; public: typedef typename C::value_type value_type; typedef typename C::size_type size_type; typedef C container_type; explicit queue(const C& a =C()) : c(a) { } bool empty() const { return c.empty() ; } size_type size() const { return c.size() ; } value_type& front() { return c.front() ; } const value_type& front() const { return c.front() ; } value_type& back() { return c.back() ; } const value_type& back() const { return c.back() ; } void push(const value_type& x) { c.push_back(x) ; } void pop() { c.pop_front() ; } };
Renato Maia 228

nov/2004

push(2). qi. qi. nov/2004 Renato Maia 229 . cout << qi.pop().push(4).Contêiner Fila de Prioridades Adaptador de contêiner seqüêncial para acesso de elementos de maior prioridade Cabeçalho #include <queue> Parâmetros Tipo dos elementos armazenados Tipo dos contêiner seqüêncial utilizado (default deque<T>) Comparador de elementos que define relação de prioridades Exemplos priority_queue<int> qi.

class Cmp = less<typename C::value_type> > class priority_queue { protected: C c. } void push(const value_type&) . void pop() . Cmp cmp. Renato Maia 230 nov/2004 . }. public: typedef typename C::value_type value_type.size() . const C& =C()) . typedef C container_type. } size_type size() const { return c. bool empty() const { return c.empty() . } const value_type& top() const { return c. const Cmp& =Cmp() . In last. cmp(a1) { } template <class In> priority_queue(In first.front() . typedef typename C::size_type size_type. explicit priority_queue(const Cmp& a1 =Cmp() . const C& a2 =C()) : c(a2) . class C = vector<T>.Operações da Fila de Prioridades template <class T.

class T2> struct std::pair { typedef T1 first_type. T2 second. T1 first. second(p. second(y) { } template <class U. second(T2()) { } pair(const T1& x.second) { } }. class V> pair(const pair<U.Utilitário Pares template <class T1. nov/2004 Renato Maia 231 . pair() : first(T1()) . const T2& y) : first(x) .first) .V>& p) : first(p. typedef T2 second_type.

Contêiners Mapa e Multimapa Conjunto de pares (chave.int> m.valor) para acesso baseado na chave Cabeçalho #include <map> Parâmetros Tipo dos elementos da chave Tipo dos elementos armazenados Tipo do comparador dos elementos (opcional) Tipo do gerenciador de memória (opcional) Exemplos map<string. nov/2004 Renato Maia 232 . ++m["int"]. cout << m["int"].

usando op como comparação op Os pares em [beg.op) Acesso Apenas para o contêiner mapa.end.end[.Operações do Cont. (Multi)Mapa vazio. Devolve uma referência para o valor mapeado por k Se não houver o elemento este é inserido com o valor default [k] Mapeamento count(k) find(k) lower_bound(k) lower_bound(k) equal_range(k) Número de elementos com a chave k Devolve a primeira posição com a chave k ou end() Devolve a primeira onde um elemento com a chave k seria inserido Devolve a última posição onde um elemento com a chave k seria inserido Devolve a primera e a última posição onde um elemento com a chave k seria inserido Renato Maia 233 nov/2004 . usando op como comparação op Construtores contêiner(op) contêiner(beg.

insert(1).Contêiners Conjunto e Multiconjunto Conjunto de valores para verificação de pertinência Cabeçalho #include <set> Parâmetros Tipo dos elementos armazenados Tipo do comparador dos elementos (opcional) Tipo do gerenciador de memória (opcional) Exemplos set<int> conj. conj. nov/2004 Renato Maia 234 .insert(4). */ .find(2) == conj.end()) /* .. if (conj. conj..

end[. usando op como comparação op Construtores contêiner(op) contêiner(beg.op) Mapeamento count(e) Número de elementos com o valor e find(e) Devolve a primeira posição com o valor e ou end() lower_bound(e) Devolve a primeira onde um elemento com o valor e k seria inserido lower_bound(e) Devolve a última posição onde um elemento com o valor e seria inserido equal_range(e) Devolve a primera e a última posição onde um elemento com o valor e seria inserido nov/2004 Renato Maia 235 .end.(Multi)Conjunto vazio.Operações do Cont. usando op como comparação op Os pares em [beg.

blue. count } bitset<count> bs. bs. bs. nov/2004 Renato Maia 236 .set(green). green.Contêiner Conjunto de Bits Conjunto de valores para verificação de pertinência Cabeçalho #include <bitset> Parâmetros Número de bits Exemplos enum RGB { red.set(red).

j[ da string str que tenham valor '1' Devolve o número de bits Devolve o número de bits ativos Informa se algum bit está ativo Informa se nenhum bit está ativo Informa se o bit de indice idx está ativo Acesso size() count() any() none() test(idx) nov/2004 Renato Maia 237 .i) Ativa os bits correspondentes aos caracteres nas posições após i da string str que tenham valor '1' bitset(str.Operações do Conjunto de Bits Construtores bitset(long) Ativa os bits do inteiro longo long bitset(str) Ativa os bits correspondentes aos caracteres '1' da string str bitset(str.i.j)Ativa os bits correspondentes aos caracteres nas posições em [i.

Operações do Conjunto de Bits Operadores (mesmo significado quando aplicado a inteiros) != | |= ^= <<= ^ << >> >>= ~ Relacionais == Boleanos & Atribuição &= [idx] Acessa o bit de índice idx Renato Maia 238 nov/2004 .

val) reset() reset(idx) reset(idx. val) flip() flip(idx) Conversão to_ulong() to_string() nov/2004 .Operações do Conjunto de Bits Ativa todos os bits Ativa o bit de indice idx Ativa o bit de indice idx de acondo com val Desativa todos os bits Desativa o bit de indice idx Desativa o bit de indice idx de acondo com val Alterna todos os bits Alterna o bit de indice idx Retorna um ulong com o mesmo padrão de bits Devolve uma string com o binário correspondente Renato Maia 239 Manipulação set() set(idx) set(idx.

Iteradores nov/2004 Renato Maia 240 .

Categorias Saída Entrada Unidirecional Bidirecional Alearório Renato Maia 241 nov/2004 .

== != == != == != == != < > >= <= Renato Maia 242 nov/2004 . Uni. Saíd. ++ ++ -.++ -.++ -. Escrita *p= Iteraç.Operações Bi. Entr. Leitura Acess.+ .+= -= Comp. =*p -> *p= =*p -> [ ] *p= Aleatório =*p -> *p= ++ -> =*p Categ.

Iteradores de Entrada Uso Acesso somente de leitura e unidirecional Operações construtor de cópia *i Leitura do elemento apontado i->membro Leitura de um membro do elemento apontado ++i Passo a frente (retorna a nova posição) i++ Passo a frente (retorna a posição antiga) i1 == i2 Testa se os iteradores apontam pro mesmo lugar i1 != i2 Testa se os iteradores não apontam pro mesmo lugar nov/2004 Renato Maia 243 .

Iteradores de Saída Uso Acesso somente de escrita e unidirecional Operações construtor de cópia *i Escrita no elemento apontado ++i Passo a frente (retorna a nova posição) i++ Passo a frente (retorna a posição antiga) nov/2004 Renato Maia 244 .

Iteradores Unidirecionais Uso Iteração unidirecional Operações construtor de cópia e default *i Acesso do elemento apontado i->membro Acesso a um membro do elemento apontado ++i Passo a frente (retorna a nova posição) i++ Passo a frente (retorna a posição antiga) i1 == i2 Testa se os iteradores apontam pro mesmo lugar i1 != i2 Testa se os iteradores não apontam pro mesmo lugar i1 = i2 Atribuição nov/2004 Renato Maia 245 .

Iteradores Bidirecionais Uso Iteração bidirecional Operações Mesmas operações de iterad. unidirecionais --i Passo a trás (retorna a nova posição) i-Passo a trás (retorna a posição antiga) nov/2004 Renato Maia 246 .

Iteradores de Acesso Aleatório Uso Iteração de acesso aleatório Operações Mesmas operações de iterad. bidirecionais i[off] Acesso ao n-ésimo elemento a partir da posição apontada i+=n Salta n elementos para frente i-=n Salta n elementos para trás i+n Iterador apontando para n posições para frente i-n Iterador apontando para n posições atrás i1-i2 Número de elementos entre iteradores i1<i2 Se i1 está antes de i2 i1>i2 Se i1 está depois de i2 i1<=i2 Se i1 está antes ou na mesma posição de i2 i1>=i2 Se i1 está depois na mesma posição de i2 Renato Maia 247 nov/2004 .

i2) iter_swap(i1.Funções Auxiliares Avança o iterador n posições Número de elementos entre os iteradores i1 e i2 Troca os valores dos elementos apontados por i1 e i2 Renato Maia 248 advance(pos. n) distance(i1. i2) nov/2004 .

inserter = front_inserter(contêiner). nov/2004 Renato Maia 249 . inserter = inserter(contêiner.Adaptadores de Iteradores Iteradores reversos Permitem iterar na seqüência na ordem inversa Iteradores de inserção (insersores) Permitem que a atribuição do valor apontado resulte na inserção de um novo elemento naquela posição Operações para obtenção de insersores inserter = back_inserter(contêiner). out_iter).

Algoritmos nov/2004 Renato Maia 250 .

Visão Geral Cabeçalho #include <algorithm> Categorias Sem modificação Com modificação De remoção De mutação De ordenação De Intervalo Ordenado nov/2004 Renato Maia 251 .

find_if Buscar n ocorrências seqüênciais de um valor Buscar dois elementos adjacentes seguindo um critério adjacent_find search_n nov/2004 Renato Maia 252 . count_if find_end Encontrar o menor ou o maior valor Buscar última ocorrência de uma subseqüência Buscar um os elementos de uma outra seqüência find_first_of min_element. max_element Buscar um elemento com um valor find.Busca Buscar uma subseqüência search Contar o número de elementos com um valor count.

Comparações Testar se duas seqüências são iguais equal Buscar a primeira diferença em duas seqüências mismatch Comparação lexicográfica lexicographical_compare Renato Maia 253 nov/2004 .

copy_backward Transforma os valores e armazena em outra transform Intercala ou troca valores entre duas seqüências merge. replace_if. swap_ranges Atribui valores os elementos fill. replace_copy_if nov/2004 Renato Maia 254 .Alterações Executar operação sobre os elementos for_each Copiar uma subseqüência copy. gerenate_n Substitui as ocorrências de um valor replace. generate. fill_n. replace_copy.

Remoções Remover elementos de uma sequência remove remove_if remove_copy remove_copy_if Remover repetições unique unique_copy Renato Maia 255 nov/2004 .

rotate_copy Permutar os elementos next_permutation. prev_permutation Aleatorizar a ordem dos elementos ramdom_shuffle Colocar no início os elementos que seguem um critério partition.Reordenação Inverter a ordem dos elementos reverse. stable_partition nov/2004 Renato Maia 256 . reverse_copy Rotacionar os elementos na seqüência rotate.

Ordenação Ordenar os elementos sort stable_sort partial_sort partial_sort_copy nth_element Manipulação de heaps make_heap push_heap pop_heap sort_heap nov/2004 Renato Maia 257 .

equal_range Combinação merge. lower_bound. inplace_merge nov/2004 Renato Maia 258 . includes. set_union. set_symetric_difference. set_intersection.Sobre Seqüências Ordenadas Buscas binary_search. upper_bound. set_difference.

j[ search(i.beg.Sem Modificação count(i.end[ em [i.j.end) Última subseqüência [beg.cmp) Elemento de maior valor com (comparação cmp) find(i.j.j[ find_end(i.end) Primeira subseqüência [beg.j.op) Última subseqüência [beg.beg.end[ em [i.j.j.j[ tal que op(elm.j.op) Primeiro elemento que op(elem)==true search_n(i.val) Primeiro elemento com valor val find_if(i.val) Primeiro de n elementos consecutivos de valor val search_n(i.j.j.beg.j.end[ em [i.val) Conta elementos com o valor val count_if(op) Conta elementos em que op(elem) == true min_element(i.j) Elemento de maior valor max_element(i.val.j) Elemento de menor valor (operador <) min_element(i.cmp) Elemento de menor valor com (comparação cmp) max_element(i.n. proc) nov/2004 Renato Maia 259 .op) Primeiro de n elementos consecutivos tal que op(elem)==true search(i.n.end.end. proc) find_end(i.j[ tal que op(elm.end[ em [i.j.beg.op) Primeira subseqüência [beg.j.

Objetos Função nov/2004 Renato Maia 260 .

Predicados == != < > <= >= ! && || Renato Maia 261 equal_to<type>() not_equal_to<type>() less<type>() greater<type>() less_equal<type>() greater_equal<type>() logical_not<type>() logical_and<type>() logical_or<type>() nov/2004 .

(unário) + * / % negate<type>() plus<type>() minus<type>() multiplies<type>() divides<type>() modulus<type>() nov/2004 Renato Maia 262 .Objetos Função Aritméticos .

y) nov/2004 Renato Maia 263 . not1(f) a = not1(f) a(f) not2(f) // !f(x. bind2nd(f.val) a = bind1st(f. // f(y. // f(x.Adaptadores de Função Associa val ao primeiro parâmetro da função Associa val ao segundo parâmetro da função Nega uma operação unária // !f(a) bind1st(f.y).y) Nega uma operação binária a = not2(f) a(x.val) a = bind2nd(f. a(y).x).x). a(y).x).

a(obj). mem_func(op) Cria objeto função que executa uma função membro do seu parâmetro a = mem_func(pmemb). nov/2004 Renato Maia 264 . // obj. // pfunc(obj). // obj->*pmemb().*pmemb(). a(obj).Adaptadores de Função Cria objeto função que executa a função ptr_fun(op) a = ptr_fun(pfunc). mem_func_ref(op) Cria objeto função que executa uma função membro do seu parâmetro a = mem_func_ref(pmemb). a(obj).

Strings nov/2004 Renato Maia 265 .

Usos do template: typedef basic_string<char> string...Template basic_string Similar ao contêiner vector Otimizado para cadeias de caracteres Apresenta apenas operações típicas de strings Declaração: template<class charT. /* . Renato Maia 266 nov/2004 . typedef basic_string<wchar_t> wstring. */> class basic_string.

Tipos Tipo do caracter Tipo do alocador usado Tipo do Tipo do Tipo do Tipo do iterador iterador constante iterador reverso iterador reverso constante Tipos parametrizados value_type allocator_type Tipos de iteradores iterator const_iterator reverse_iterator const_reverse_iterator Tipos ponteiro e referência Tipo ponteiro para o caracter Tipo ponteiro constante para o caracter Tipo referência para o caracter Tipo referência constante para o caracter pointer const_pointer reference const_reference nov/2004 Renato Maia 267 .

idx) Cópia da substring de str que inicia no índice idx string(str.end[ ~string() Destrói todos os caracteres e libera a memória nov/2004 Renato Maia 268 .len) Cópia da substring de str que inicia no índice idx e comprimento len string(cstr) String a partir de uma string C string(chars.idx.Construtores e Destrutores string() String vazia string(str) Cópia da string str string(str.len) String com os len primeiros caracteres do vetor chars string(num.end) String os os caracteres em [beg.c) String com num repetições do caracter c string(beg.

e.Conversão para Strings C Retorna um vetor com os caracteres da string (sem o '\0') Retorna uma string C com os mesmos caracteres (i. com o '\0') data() c_str() copy(buff) Copia os caracteres da string para um vetor fornecido Renato Maia 269 nov/2004 .

nov/2004 Renato Maia 270 .Comprimento e capacidade Número de caracteres Verifica se é a string vazia Número máximo de caracteres Número de caracteres que pode comportar sem realocar memória size(). length() empty() max_size() capacity() string s("Maia"). cout << s.length().

// s == " Marcela" // Cuidado char& r = s[5].Acesso aos Caracteres idx-ésimo caracter da string idem. mas com verificação [idx] at(idx) string s("Marcelo").at(6) = s[1]. // cuidado! r foi desalocado nov/2004 Renato Maia 271 . s = "Renato". s. // realocação libera vetor original r = 'a'.

Comparações Conteúdo de s1 é o mesmo de s2 s1 é lexicograf. maior que s2 s1 é lexicograf. menor que s2 s1 é lexicograf.compare("dcba"). // algum valor > 0 nov/2004 Renato Maia 272 . if (s1 == "abcd") cout << s1. menor ou igual que s2 s1 é lexicograf.compare(s2) string s1("abcd"). maior ou igual que s2 como o strcmp(s1.s2) para strings C s1 == s2 s1 < s2 s1 > s2 s1 <= s2 s1 >= s2 s1.

assign(aString.assign(aString).1. s.assign("two\nlines"). s = "two\nlines". s. string s.Atribuições const string aString("Othelo"). // atribui um único caracter s. // atribui "Othelo" s = aString.3). nov/2004 Renato Maia 273 . // atribui conteúdo de string C s = ' '.

s = "". s. s. nov/2004 Renato Maia 274 .erase().clear().Apagando string s = "Meu texto".

append('x'.append(aString. // apenda "the" a.3). 3). // apenda "xxxxx" nov/2004 Renato Maia 275 . a += '\n'. // apenda "nic" a.5).1. // apenda "othello" // apenda string C // apenda único caracter a += aString.append("nico". string s.Apendando const string aString("othello"). a += "world". a.

// "gente" s. // "gerente" s. s.replace("ger".aString). string s("g")."er"). // graficamente s.insert(1. // grafica nov/2004 Renato Maia 276 .12).erase(7.insert(1.Alterando const string aString("ente"). "graficam").

substring(5.5) + "ção". nov/2004 Renato Maia 277 .Subcadeias e Concatenação string s("interoperabilidade").substring(5.5). s. // retorna string("opera") cout << "in" + s.

strings e um intervalo defindindo uma subcadeia.Busca Funções sobrecarregadas para receber strings. Primeira ocorrência de val Última ocorrência de val Primeiro caracter de val Último caracter de val Primeiro caracter que não está em val Último caracter que não está em val find(val) rfind(val) find_first_of(val) find_last_of(val) find_first_not_of(val) find_last_not_of(val) nov/2004 Renato Maia 278 . etc. strings C.

Streams nov/2004 Renato Maia 279 .

Motivação Canal para transferência de dados como bytes (caracteres) Permite a conversão dos tipos de dados para bytes. Uma espécie de serialização nov/2004 Renato Maia 280 .

free store 0x500c nov/2004 Renato Maia 281 . free store " << p << '\n'. typedef basic_ostream<wchar_t> wostream. Funções put(c) write(cstr. // local 0x7fffead0. sz) Operadores // serializa valor e escreve no stream << Exemplos cout << "local " << &p << ".Streams de Saída Template Básico typedef basic_ostream<char> ostream. // escreve caracter c // escreve sz caracteres da string C cstr.

string expressao. cout >> prioridade >> comando >> expressao. nov/2004 Renato Maia 282 . sz) Operadores >> Exemplos int prioridade. // lê um caracter e armazena em c // lê sz caracteres para o buffer cstr de sz chars. // lê o valor do stream e escreve na variável Funções get(c) read(cstr. string comando.Streams de Entrada Template Básico typedef basic_istream<char> istream. typedef basic_istream<wchar_t> wistream.

streamsize n). streamsize n. streamsize n. basic_istream& ignore(streamsize n = 1.Ch term). basic_istream& getline(Ch* p. basic_istream& read(Ch* p. // newline is terminator basic_istream& getline(Ch* p. // read one Ch (or Tr::eof()) basic_istream& get(Ch& c).Ch term).Leitura não Formatada streamsize gcount() const. // read one Ch into c basic_istream& get(Ch* p. // read at most n char nov/2004 Renato Maia 283 . streamsize n). int_type t = Tr::eof()) . streamsize n). // number of char read by last get() int_type get(). // newline is terminator basic_istream& get(Ch* p.

bool eof() const. } nov/2004 Renato Maia 284 . void setstate(iostate f) {clear(rdstate()|f). void clear(iostate f = goodbit) . bool operator!() const { return fail() . bool fail() const.} operator void*() const.Estado do Stream // next operation will succeed // end of input seen // next operation will fail // stream is corrupted // get io state flags // set io state flags // add f to io state flags // nonzero if !fail() bool good() const. bool bad() const. iostate rdstate() const.

Exceções Por default os streams não lançam exceções Para lançar exceções em situações de erro usa-se a operação exception cout. cin.exceptions(ios_base::badbit|ios_base::failbit) nov/2004 Renato Maia 285 .exceptions(ios_base::badbit|ios_base::failbit|ios_base::eofbit) .

56789 << ´\n´. cout << "default:\t" << 1234. // volta ao default (ou seja.setf(ios_base::scientific. nov/2004 Renato Maia 286 . // formato científico cout. cout << "fixed:\t" << 1234. format genérico) cout.56789 << ´\n´. cout << "scientific:\t" << 1234.ios_base::floatfield).56789 << ´\n´.setf(ios_base::fixed.Formatação cout << "default:\t" << 1234.setf(0.56789 << ´\n´.ios_base::floatfield).ios_base::floatfield). // formato de ponto fixo cout.

World!" << endl. endl cout << "Hello. Renato Maia 287 nov/2004 . noskipwsnão ignora os espaços na entrada cin >> noskipws >> x.Manipuladores flush cout << x << flush << y << flush.

Formação Básica boolalpha // symbolic representation of true and // false (input and output) noboolalpha // s.unsetf(ios_base::showpos) nov/2004 Renato Maia 288 .unsetf(ios_base::boolalpha) showbase // on output prefix oct by 0 and hex by 0x noshowbase // s.unsetf(ios_base::showbase) showpoint // print trailing zeros noshowpoint // s.unsetf(ios_base::showpoint) showpos // explicit '+' for positive numbers noshowpos // s.

unsetf(ios_base::skipws) uppercase // X and E rather than x and e nouppercase // x and e rather than X and E nov/2004 Renato Maia 289 .Formatação Textual skipws // skip whitespace noskipws // s.

ddddEdd dec hex oct fixed scientific nov/2004 Renato Maia 290 .Formação Numérica // integer base is 10 // integer base is 16 // integer base is 8 // floatingpoint format dddd.dd // scientific format d.

Constantes // put ’\n’ and flush // put ’\0’ and flush // flush stream // eat whitespace (input) endl ends flush ws nov/2004 Renato Maia 291 .

make c the fill character setfill(int c). output integers in base b setbase(int b). nov/2004 Renato Maia 292 . set flags setiosflags(ios_base::fmtflags f). n digits after decimal point setprecision(int n). next field is n char setw(int n).Com Parâmetro clear flags resetiosflags(ios_base::fmtflags f).

typedef basic_fstream<wchar_t> wfstream. typedef basic_ifstream<wchar_t> wifstream. typedef basic_ofstream<wchar_t> wofstream.Streams de Arquivos Criados a partir de templates typedef basic_ifstream<char> ifstream. typedef basic_ofstream<char> ofstream. typedef basic_fstream<char> fstream. nov/2004 Renato Maia 293 .

// truncate file to 0 length } ofstream mystream(name. open for reading out.ios_base::app). dictionary. fstream dictionary("concordance".Modo de Abertura de Arquivos namespace io_base { app. // open and seek to end of file binary.close(). nov/2004 Renato Maia 294 .close().c_str() . // I/O to be done in binary mode in.ios_base::in|ios_base::out). mystream. // append ate. // open for writing trunc.

typedef basic_istringstream<wchar_t> wistringstream. nov/2004 Renato Maia 295 . typedef basic_ostringstream<wchar_t> wostringstream. typedef basic_stringstream<char> stringstream. typedef basic_stringstream<wchar_t> wstringstream. typedef basic_ostringstream<char> ostringstream.Streams de Strings Principais usos typedef basic_istringstream<char> istringstream.

} Renato Maia 296 nov/2004 .str() . const string& cs) { ostringstream ost.Escrevendo numa String extern const char* std_message[] . string compose(int n. return ost. ost << "error(" << n << ") " << std_message[n] << " (user comment: " << cs << ´)´.

Revisão nov/2004 Renato Maia 297 .

operadores Classes abstratas como interfaces Funções membro virtuais.Visão Geral do Curso Tratamento de erros regulares Lançamento e captura de exceções Extensão através de novos tipos Classes. templates de funções nov/2004 Renato Maia 298 . cabeçalhos. polimorfismo de inclusão Modularização de software em larga escala Espaços de nomes. controle de acesso Contêiners padrão e algoritmos Standard Template Library Software genérico fortemente tipado Strings padrão e streams de E/S Operações com strings. construtores. cópia. compilação por partes Hierarquia de classes para POO Herança. streams Templates de classe.

Fim nov/2004 Renato Maia 299 .

Sign up to vote on this title
UsefulNot useful