Buscar

Introdução à Linguagem C++

Prévia do material em texto

nov/2004 Renato Maia 1
A Linguagem C++
Renato Maia
maia@inf.puc-rio.br
TeCGraf/PUC-Rio
Renato Maia 2nov/2004
Hello, World!
#include <iostream>
int main()
{
std::cout << "Hello, world!" << "\n";
}
nov/2004 Renato Maia 3
MÓDULO I
Recursos Básicos
Renato Maia 4nov/2004
Recursos Básicos
n Parte 1:
¨ Tipos
¨ Declarações
¨ Ponteiros
¨ Vetores
¨ Estruturas
¨ Operadores
¨ Expressões
¨ Comandos
¨ Funções
n Exemplo
¨ Calculadora
n Parte 2:
¨ Espaços de Nomes
¨ Compilação e Ligação
nov/2004 Renato Maia 5
Tipos
Renato Maia 6nov/2004
Tipo Lógico
n Tipo: bool
n Literais: true , false
n Conversões:
¨ trueè 1
¨ falseè 0
¨0 è false
¨?0 è true
Renato Maia 7nov/2004
Tipo Caractere
n Tipo: char
n Modificadores: signed , unsigned
n Literais:
¨Letras: 'a', 'b', ..., 'Z'
¨Algarismos: '0', '1', ..., '9'
¨Especiais: '\n', '\t', '\0'
¨Números: 97 // o 'a' na tabela ASCII
Renato Maia 8nov/2004
Tipo Inteiro
n Tipo: int
n Modificadores:
¨ signed , unsigned
¨ short , long
n Literais:
¨ Decimal: 20
¨ Octal: 020
¨ Hexadecimal: 0x20f
Renato Maia 9nov/2004
Tipos Reais
n Tipos: float , double
n Modificadores: long (aplicável ao double)
n Literais: (não podem conter espaços)
¨ 1.23
¨ .23
¨ 1.
¨ 1.23e10
¨ 1.23e-10
Renato Maia 10nov/2004
Tipo Vazio
n Tipo: void
n Uso:
¨Como tipo de retorno de uma função
n Define funções que não retornam valores
¨Como tipo de ponteiro
n Define um ponteiro para tipo indefinido (ponteiro 
genérico)
Renato Maia 11nov/2004
Enumerações
n Exemplo:
enum DiaSem { DOM, SEG, TER, QUA, QUI, 
SEX, SAB };
n Uso
¨Definir um tipo que assume um conjunto de 
valores inteiros pré-definidos (enumerados).
nov/2004 Renato Maia 12
Declarações
Renato Maia 13nov/2004
Declarações
Especificador Tipo Declarador Iniciação/Definição
char ch ;
string s ;
int count = 1 ;
const double pi = 3.1415926535897932385 ;
extern int error_number ;
const char * name = "Najla" ;
const char * season[ ] = {"spring","summer", "fall","winter};
struct Date { int d, m, y } ;
int day(Date* p) { return p->d; } ;
double sqrt(double) ;
template<class T> T abs(T a) { return a<0 ? –a : a; }
typedef list<int> SmallNums ;
struct User ;
enum Beer { Carlsberg, Tuborg, Thor } ;
namespaceNS { int a; } ;
Renato Maia 14nov/2004
Declarações (observações)
n Declaração com vários nomes
¨ int a, b = 0; // apenas o 'b' é iniciado.
¨ int* pa, pb; // o 'pb' NÃO é um ponteiro.
n Nomes de identificadores
¨hello, DEFINED, var23, _123, __, 
um_nome_razoavelmente_GRANDE
n Iniciação (apenas estáticos)
¨Globais, namespace e static
Renato Maia 15nov/2004
Escopo
int x = 0;
{
int x = 1; cout << x;
{
int x = 2; cout << x;
}
x = 3; cout << x;
} cout << x;
Renato Maia 16nov/2004
Declaração de Tipos
n Exemplos:
typedef char *Pchar;
Pchar p1, p2;
char *p3 = p1;
n Na realidade a declaração de um typedef
define apenas um sinônimo para algum 
tipo.
nov/2004 Renato Maia 17
Ponteiros e Vetores
Renato Maia 18nov/2004
Ponteiros
n Uso < Outras Formas
char c = 'a'; char **ppc;
char *pc = &c; char *vetp[15];
char c2 = *pc; char (*fp)(char*);
pc:
c: 'a'
&c
Renato Maia 19nov/2004
Iniciação de Ponteiros
n A linguagem C++ não define uma palavra 
reservada para indicar um endereço de 
memória inválido ou nulo (e.g. null de 
Java). Ao invés disso usa-se o valor 0, 
que pode ser atribuído a ponteiros. 
Nenhum objeto é criado no endereço 0.
n int *pi = 0;
Renato Maia 20nov/2004
Vetores
n Dimensões
float d1[3];
float d2[10][20]; // não: float d2[10, 20];
n Iniciação
int v1[ ] = { 1, 2, 3, 4 }; // v1 é do tipo int[4]
char v3[3] = {'a','b',0}; // não: char v3[2] = {'a','b',0};
int v5[5] = {1,2,3} // equiv.: int v5[3] = {1,2,3,0,0};
int v7[5];
v7 = {1,2,3,4,5} // erro: apenas na iniciação
Renato Maia 21nov/2004
Literais de Cadeias de Caracteres
n Na iniciação de vetores de caracteres
char c2[ ] = "cadeia";
char c3[ ] = { 'c', 'a', 'd', 'e', 'i', 'a', '\0' };
sizeof("cadeia") == 7
n Acesso através de ponteiros irrestritos (vs. ponteiros para const.)
char *pc = "imutavel";
pc[0] = ' '; // erro: resultado indefinido
n Comparação de cadeias
const char *p = "C++";
const char *q = "C++";
if (p == q) cout << "one!\n"; // depende da implementação do C++
n Quebrando cadeias grandes
const char longa[ ] = "inconstitucional"
"issimamente\n" // "inconstitucionalissimamente\n"
Renato Maia 22nov/2004
Ponteiros e Vetores
n Conversão implícita para ponteiros
char v[ ] = "cadeia";
char *p;
p = v; // conversão implícita
v = p; // erro: não é possível atribuir um ponteiro a um vetor
'c' 'a' 'd' 'e' 'i' 'a' 0v:
p: p:
p+=5;
Renato Maia 23nov/2004
Aritmética de Ponteiros
n Iteração sobre uma cadeia de caracteres
char v[ ] = "uma cadeia\n"
for (int i = 0 ; v[i] != 0 ; i++ ) use(v[i]);
for (char *p = v ; *p != 0 ; p++ ) use(*p);
n Subtração de ponteiros (ou endereços)
int v1[10];
int v2[10];
int i1 = &v1[5] - &v1[3]; // i1 == 2
int i2 = &v1[5] - &v2[3]; // indefinido
Renato Maia 24nov/2004
Constantes
n Declaração
const int model = 90;
const int v[ ] = { 1, 2, 3, 4, 5 }; // v[i] é const
const int x; // erro: exige iniciação
n Ponteiros constantes
char*const cp; // ponteiro constante
const char*pc; // ponteiro para uma constante
char const*pc2; // ponteiro para uma constante
Renato Maia 25nov/2004
Referências
n Definição
int i = 1;
int& r = i; // r e i se referem ao mesmo elemento
n Uso
int x = r; // x = 1
r = 2; // i = 2
n Iniciação
int& r2; // erro: falta iniciação
extern int& r3; // ok: r3 é iniciado em outro módulo
Renato Maia 26nov/2004
Ponteiros Genéricos (void *)
n Recurso de baixo nível
n Operações
int* pi = &i;
void* pv = pi; // ok: conversão implicita de int* para void*
*pv; // erro: não é possível acessar um void*
pv++; // erro: não é possível incrementar um void*
n Conversões (cast)
int* pi2 = static_cast<int*>(pv); // conver. explíc.
double* pd1 = pv; // erro
double* pd2 = pi; // erro
double* pd3 = static_cast<double*>(pv); // inseguro
nov/2004 Renato Maia 27
Estruturas
Renato Maia 28nov/2004
Estruturas
n Declaração
struct address {
char *name; // "Jim Dandy"
long int number; // 61
char *street; // "South St"
char *town; // "New Providence"
char state[2] ; // ’N’ ’J’
long zip; // 7974
};
Renato Maia 29nov/2004
Estruturas (cont.)
n Uso
address jd;
jd.name = "Jim Dandy";
jd.number = 61;
n Iniciação
address jd = {
"Jim Dandy",
61, "South St",
"New Providence", {´N´,´J´}, 7974 };
Renato Maia 30nov/2004
Ponteiro para Estruturas
n Operador de acesso através de ponteiros
p->m è (*p).m
n 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´;
Renato Maia 31nov/2004
Cópia de Estruturas
address current;
address set_current(address next)
{
address prev = current;
current = next;
return prev;
}
Renato Maia 32nov/2004
Declaração Antecipada
struct Link {
Link* previous;
Link* successor;
};
struct List; // definido posterior.
struct Link {
Link* pre;
Link* suc;
List* member_of;
};
struct List {
Link* head;
};
nov/2004 Renato Maia 33
Operadores
Renato Maia 34nov/2004
Operadores Relacionais
n Igual ==
n Diferente !=
n Maior que >
n Menor que <
n Maior ou igual >=
n Menor ou igual <=
Renato Maia 35nov/2004
Operadores Aritiméticos
n Adição +
n Subtração -
n Multiplicação *
n Divisão /
n Módulo %
n Inversor de sinal -
n Incremento --
n Decremento ++
Renato Maia 36nov/2004
OperadoresLógicos
n E (and) &&
n Ou (or) ||
n Negação (not) !
Renato Maia 37nov/2004
Operadores sobre Bits
n E bit a bit &
n Ou inclusivo bit a bit |
n Ou exclusivo (xor) bit a bit ^
n Complemento ~
n Deslocamento a esquerda <<
n Deslocamento a direita >>
Renato Maia 38nov/2004
Operadores de Atribuição
n Atribuição simples =
n Multiplicação e atribuição *=
n Divisão e atribuição /=
n Módulo e atribuição %=
n Soma e atribuição +=
n Subtração e atribuição -=
n Deslocamento a esquerda e atribuição <<=
n Deslocamento a direita e atribuição >>=
n E bit a bit e atribuição &=
n Ou inclusivo bit a bit e atribuição |=
n Ou exclusivo bit a bit e atribuição ^=
Renato Maia 39nov/2004
Operadores Composicionais
n Seqüência <expr> , <expr>
n Condicional <cond> ? <true> : <false>
cout << ( (p1+p2+p3)/3 >= 5 ? "aprovado" : "reprovado" )
Renato Maia 40nov/2004
Operadores de Memória Dinâmica
n Alocação new
n Desalocação delete
n Desalocação de vetores delete[ ]
Renato Maia 41nov/2004
Operad. de Conversão de Tipos
n Conversão estática (tipos relacionados)
static_cast<tipo>(valor)
n Conversão estática (tipos não relacion.)
reinterpret_cast<tipo>(valor)
n Conversão dinâmica
dynamic_cast<tipo>(valor)
n Conversão de C
(tipo) valor
Renato Maia 42nov/2004
Operadores de Construção
n Construtor
tipo (valor)
n Exemplos
double d = 1.23;
int i = int(d);
complex c = complex(d); // tipo definido na 
biblioteca padrão do C++
Renato Maia 43nov/2004
Operadores (observações)
n Ordem de avaliação dos operandos é indefinida.
int a = f() + g() // g() pode executar primeiro
n Sempre use parênteses para garantir a 
precedência esperada.
if ( (i & mask) == 0 ) // ...
n Evite escrever expressões complexas e pouco 
legíveis. Conte com as otimizações do 
compilador.
nov/2004 Renato Maia 44
Comandos
Renato Maia 45nov/2004
Bloco de Comandos
{
<comando>;
<comando>;
<comando>;
...
<comando>;
}
Renato Maia 46nov/2004
Comandos de Seleção
n Condicional
if (<expr>) <comando>;
else <comando>;
n Seleção
switch (<expr>) {
case <const>:
<comandos>; break;
case <const>:
<comandos>; break;
default:
<comandos>; break;
}
Renato Maia 47nov/2004
Comandos de Iteração
n Laço com teste no início
while (<cond>) <comando>;
n Laço com teste no final
do <comando> while (<cond>);
n Laço com contador
for (<início>; <cond>; <increm>) <comando>;
for (;;) { /* ... */ } // para sempre
Renato Maia 48nov/2004
Comando de Salto
n O famigerado goto
int i;
int j;
for (i = 0; i<n; i++)
for (j = 0; j<m; j++) if (nm[i][j] == a) goto found;
// não encontrado
// ...
found:
// nm[i][j] == a
nov/2004 Renato Maia 49
Funções
Renato Maia 50nov/2004
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 51nov/2004
Funções inline
inline int fac(int n)
{
return (n<2) ? 1 : n*fac(n-1);
}
int i = f(6); è int i = 720;
int i = f(6); è int i = (int n = 6, (n<2) ? 1 : ...)
Renato Maia 52nov/2004
Variáveis Estáticas
void f(int a)
{
while (a--)
{
static int n = 0; // iniciada uma vez
int x = 0; // iniciada n vezes
cout << "n == " << n++ << ", x == " << x++ << '\n';
}
}
n == 0, x == 0
n == 1, x == 0
n == 2, x == 0
Renato Maia 53nov/2004
Passagem de Parâmetros
n Passagem por referência
void increment(int& aa) { aa++; };
int x = 1; increment(x); // x == 2
n Parâmetros constantes
void f(const int *p) { *p = 1; /* erro! */ }
n Parâmetros anônimos
void search(table* t, const char* key, const char*)
{
// não é possível utilizar o terceiro parâmetro
}
Renato Maia 54nov/2004
Constantes por Referência
n Referência para valores constantes
double& dr = 1; // error: não pode ser constante
const double& cdr = 1; // ok: double t = double(1) ;
const double& cdr = t;
n Valores constantes por referência
void update(float& i) ;
void g(double d, float r)
{
update(2.0f) ; // error: argumento constante
update(r) ; // passa uma referência a r
update(d) ; // error: necessária conversão de tipo
}
Renato Maia 55nov/2004
Valor de Retorno
n Retorno por referência
int vet[5];
int& getcounter(int i) { return vet[i]; }
getcounter(3)++;
n Retorno de variáveis automáticas
int* fp() { int local = 1; /* ... */ return &local; } // cuidado!
int& fr() { int local = 1; /* ... */ return local; } // cuidado!
Renato Maia 56nov/2004
Sobrecarga de Funções
void print(double);
void print(long);
void f()
{
print(1L); // print(long)
print(1.0); // print(double)
print(1); // erro: ambígua, print(long(1)) or
// print(double(1)) ?
}
Renato Maia 57nov/2004
Parâmetros Default
void print(int value, int base =10);
void f() {
print(31) ;
print(31,16) ;
print(31,2) ;
}
n Alternativa
void print(int value, int base) ;
inline void print(int value) { print(value,10) ; }
n Erros comuns
int h(int a = 0, int b, char* c = 0) ; // erro
Renato Maia 58nov/2004
Parâmetros Variáveis
#include <cstdarg>
void error(int severity, ...) { // "severidade" e mensagens
va_list ap;
va_start(ap, severity) ; // iniciação arg
for (;;) {
char* p = va_arg(ap,char*) ;
if (p == 0) break;
cerr << p << ' ';
}
va_end(ap) ; // limpa o conteúdo de ap
cerr << '\n';
if (severity) exit(severity) ;
}
// error(1, "Erro", "Faltal", "Econtrado", static_cast<char*>(0));
Renato Maia 59nov/2004
Ponteiros para Funções
void print(const char *s) { /* ... */ }
void (*pf)(const char*); // ponteiro para função
void f()
{
pf = print; // também: pf = &print;
pf("error"); // também: (*pf)("error");
}
Renato Maia 60nov/2004
Macros
n Substituições simples
#define PI 3.141593
n Macros razoáveis
#define CASE break;case
#define FOREVER for(;;)
n Macros perigosas
#define SQUARE(a) a * a
int m = SQUARE(2 + i++) // 2 + i++ * 2 + i++
nov/2004 Renato Maia 61
Exemplo
Calculadora
Renato Maia 62nov/2004
Exemplo
n Entrada
¨perimetro = 2 * pi * (r = 2.5)
¨area = pi * r * r
n Saída
¨15.708
¨19.635
Renato Maia 63nov/2004
Gramática da Calculadora
program:
END
expr_list END
expr_list:
expression ;
expression ; expr_list
expression:
expression + term
expression - term
term
term:
term / primary
term * primary
primary
primary:
NUMBER
NAME
NAME = expression
- primary
( expression )
Renato Maia 64nov/2004
Tokens
enum Token_value {
NAME, NUMBER, END,
PLUS = '+', MINUS = '-', MUL = '*', DIV = '/',
PRINT = ';', ASSIGN = '=', LP = '(', RP = ')'
};
Token_value curr_tok = PRINT;
double number_value;
string string_value;
Renato Maia 65nov/2004
Leitura de Tokens
Token_value get_token() {
char ch = 0;
do { // pula espaços em branco, exceto '\n'
if(!cin.get(ch)) return curr_tok = END;
} while (ch != '\n' && isspace(ch)) ;
…
Renato Maia 66nov/2004
Leitura de Tokens
…
switch (ch) {
case 0:
return curr_tok = END;
case ';': case '\n':
return curr_tok = PRINT;
case '*': case '/': case '+': case '-':
case '(': case ')': case '=':
return curr_tok = Token_value(ch) ;
…
Renato Maia 67nov/2004
Leitura de Tokens
…
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
cin.putback(ch) ;
cin >> number_value;
return curr_tok = NUMBER;
…
Renato Maia 68nov/2004
Leitura de Tokens
…
default: // NAME, NAME=, ou erro
if (isalpha(ch)) {
string_value = ch;
while (cin.get(ch) && isalnum(ch))
string_value += ch ;
cin.putback(ch) ;
return curr_tok = NAME;
}
error("bad token") ;
return curr_tok = PRINT;
}
}
Renato Maia 69nov/2004
Erros
double error(conststring& s)
{
no_of_errors++;
cerr << "error: " << s << '\n';
return 1;
}
Renato Maia 70nov/2004
Expressão
double expr(bool get) { // adiciona e subtrai
double left = term(get) ;
for(;;) switch (curr_tok) {
case PLUS:
left += term(true) ;
break;
case MINUS:
left -= term(true) ;
break;
default:
return left;
}
}
Renato Maia 71nov/2004
Termo
double term(bool get) { // multiplica e divide
double left = prim(get) ;
for (;;) switch (curr_tok) {
case MUL:
left *= prim(true) ;
break;
case DIV:
if (double d = prim(true)) {
left /= d;
break; }
return error("divide by 0") ;
default:
return left;
}
}
Renato Maia 72nov/2004
Variáveis
n Armazenar numa tabela que associe 
strings a números reais
n Sugestão: usar o template 'map' da 
biblioteca padrão do C++
¨std::map<string,double> table;
Renato Maia 73nov/2004
Primário
double prim(bool get) { // manipula primários
if (get) get_token() ;
switch (curr_tok) {
case NUMBER: // constante real
{ double v = number_value;
get_token() ;
return v;
}
case NAME:
{ double& v = table[string_value] ;
if (get_token() == ASSIGN) v = expr(true) ;
return v;
}
…
Renato Maia 74nov/2004
Primário
…
case MINUS: // menos unário
return -prim(true) ;
case LP:
{ double e = expr(true) ;
if (curr_tok != RP) return error(") expected") ;
get_token() ; // consome o ')'
return e;
}
default:
return error("primary expected") ;
}
}
Renato Maia 75nov/2004
Função main
int main(int argc, char* argv[])
{
table["pi"] = 3.1415926535897932385; // constantes predefinidas
table["e"] = 2.7182818284590452354;
while (cin) {
get_token() ;
if (curr_tok == END) break;
if (curr_tok == PRINT) continue;
cout << expr(false) << '\n';
}
return 0;
}
Renato Maia 76nov/2004
Exercícios
1. Compilar e executar o programa de exemplo mostrado 
previamente
2. 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).
¨ A codificação deve ser feita na forma c^chave[i], tal que chave 
é uma string dada pela linha de comando. Dessa forma quando 
um texto for novamente codificado com a mesma chave o texto 
original é recuperado.
¨ Os caracteres da chave devem ser utilizados de forma circular.
¨ Se nenhuma chave for fornecida, então nenhuma codificação 
deve ser feita.
Renato Maia 77nov/2004
Teste do Exercício 2
n Legenda:
¨ encrypt: nome do seu programa
¨ senha: chave de criptografia
¨ input.txt: um arquivo de texto qualquer
¨ output.dat: arquivo com o texto codificado
¨ back.txt: arquivo com o texto decodificado
n Comandos:
C:\>encrypt senha < input.txt > output.dat
C:\>encrypt senha < output.dat > back.txt
nov/2004 Renato Maia 78
Espaços de Nomes
Renato Maia 79nov/2004
Espaços de Nomes
namespace Parser {
double expr(bool) ;
double prim(bool get) { /* ... */ }
double term(bool get) { /* ... */ }
double expr(bool get) { /* ... */ }
}
namespace Lexer {
enum Token_value {
NAME, NUMBER, END,
PLUS=´+´, MINUS=´-´, MUL=´*´, DIV=´/´,
PRINT=´;´, ASSIGN=´=´, LP=´(´, RP=´)´
};
Token_value curr_tok;
double number_value;
string string_value;
Token_value get_token() { /* ... */ }
}
Renato Maia 80nov/2004
Nomes Qualificados
double Parser::term(bool get) // note a qualificação Parser::
{
double left = prim(get) ; // nenhuma qualificação necessária
for (;;)
switch (Lexer::curr_tok) { // note a qualificação Lexer::
case Lexer::MUL: // note a qualificação Lexer::
left *= prim(true) ; // nenhuma qualificação necessária
// ...
}
// ...
}
Renato Maia 81nov/2004
Utilizando Declarações
namespace Parser {
double term(bool get);
// ...
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 Lexer::MUL:
left *= prim(true) ;
// ...
}
// ...
}
Renato Maia 82nov/2004
Diretivas de Utilização
namespace Parser {
double term(bool get);
// ...
using namespace Lexer; // incorpora todas as declarações
}
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) ;
// ...
}
// ...
}
Renato Maia 83nov/2004
Espaços de Nomes Anônimos
namespace {
int a;
void f() { /* ... */ }
int g() { /* ... */ }
}
/* Equivalente a:
namespace $$$ {
int a;
void f() { /* ... */ }
int g() { /* ... */ }
}
using namespace $$$; */
Renato Maia 84nov/2004
Alias de Espaços de Nome
// nome muito longo
namespace American_Telephone_and_Telegraph { /* ... */ }
American_Telephone_and_Telegraph::String s3 = "Grieg";
American_Telephone_and_Telegraph::String s4 = "Nielsen";
// alias
namespace ATT = American_Telephone_and_Telegraph;
ATT::String s3 = "Grieg";
ATT::String s4 = "Nielsen";
Renato Maia 85nov/2004
Exercício
n Dividir o programa de exemplo da calculadora 
em módulos (usando espaços de nomes)
¨Módulo Léxico (namespace Lexer)
n Leitura e interpreção de tokens
¨Módulo Parser (namespace Parser)
n Interpretação e avaliação de expressões
¨Módulo de Erros (namespace Error)
n Contagem e exibição de erros
nov/2004 Renato Maia 86
Compilação e 
Ligação
Renato Maia 87nov/2004
Compilação Condicional
#ifdef NDEBUG
const bool ARG_CHECK = false; // desabilita verificações
#else
const bool ARG_CHECK = true; // habilita verificações
#endif
void f3(int* p)
{
assert(!ARG_CHECK || p!=0) ; // ou não faz verificação ou p!=0
// ...
}
Renato Maia 88nov/2004
Compilação em Partes
lexer.cppparser.cpp error.cppmain.cpp
<string><map>
lexer.hparser.h error.h
Renato Maia 89nov/2004
Cabeçalho do Módulo Lexer
#include <string>
namespace Lexer {
enum Token_value {
NAME, NUMBER, END,
PLUS = '+', MINUS = '-', MUL = '*', DIV = '/',
PRINT = ';', ASSIGN = '=', LP = '(', RP = ')'
};
extern Token_value curr_tok;
extern double number_value;
extern std::string string_value;
Token_value get_token();
}
Renato Maia 90nov/2004
Módulo Lexer
#include "lexer.h"
#include "error.h"
#include <iostream>
#include <cctype>
using std::cin;
Lexer::Token_value Lexer::curr_tok = Lexer::PRINT;
double Lexer::number_value;
std::string Lexer::string_value;
Lexer::Token_value Lexer::get_token() { /* ... */ }
Renato Maia 91nov/2004
Guardas de Inclusão
n 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 {
// ...
}
#endif // CALC_ERROR_H
Renato Maia 92nov/2004
Ligação com Código C
n A forma de chamada de funções C é diferente das chamadas de 
C++. É necessário informar ao compilador quando uma função deve 
ser ligada como uma função C.
extern "C" void funcao_c(int, int);
extern "C" {
void uma_funcao_c(int, int);
void outra_funcao_c(int, double);
void mais_outra_funcao_c(char*);
}
extern "C" {
#include "modulo_c.h"
}
Renato Maia 93nov/2004
Ponteiros para Funções C
typedef int (*FT)(const void*, const void*) ; // FT tem ligação C++
extern "C" {
typedef int (*CFT)(const void*, const void*) ; // CFT tem ligação C
void qsort(void* p, size_t n, size_t sz,CFT cmp) ; // cmp tem ligação C
}
void isort(void* p, size_t n, size_t sz,FT cmp) ; // cmp tem ligação C++
void xsort(void* p, size_t n, size_t sz,CFT cmp) ; // cmp tem ligação C
extern "C" void ysort(void* p, size_t n, size_t sz,FT cmp) ; // cmp tem ligação C++
int compare(const void*, const void*) ; // compare() tem ligação C++
extern "C" int ccmp(const void*, const void*) ; // ccmp() tem ligação C
void f(char* v,int sz) {
qsort(v,sz,1,&compare) ; // erro
qsort(v,sz,1,&ccmp) ; // ok
isort(v,sz,1,&compare) ; // ok
isort(v,sz,1,&ccmp) ; // erro
}
Renato Maia 94nov/2004
Exercício
n 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 lexer.h)
¨Módulo Parser (parser.cpp e parser.h)
¨Módulo de Erros (error.cpp e error.h)
¨Módulo Principal (main.cpp)
nov/2004 Renato Maia 95
MÓDULO II
Mecanismos de Abstração
Renato Maia 96nov/2004
Mecanismos de Abstração
n Parte 1:
¨ Classes
¨ Objetos
n Parte 2:
¨ Sobrecarga de 
Operadores
¨ Classes Derivadas
n Parte 3:
¨ Herança Múltipla
¨ Templates
n Parte 4:
¨ Exceções
¨ Informação de Tipo 
Dinâmica (RTTI)
nov/2004 Renato Maia 97
Classes
Renato Maia 98nov/2004
Classes
n As classes de C++ define um novo tipo 
que funcionam como um tipo básico da 
linguagem
n A forma de usar um objeto de uma classe 
não deve diferir do uso dos tipos básicos
n A única diferença deve ser na sua criação
Renato Maia 99nov/2004
Funções Membro
class Date {
int d,m,y;
void init(int dd, int mm, int yy) ;
void add_year(int n) { y += n; }
void add_month(int n) { m += n; }
void add_day(int n) { d += n; }
};
void Date::init(int dd, int mm, int yy) { // especifica a classe a que pertence
d = dd;
m = mm;
y = yy;
}
Renato Maia 100nov/2004
Controle de Acesso
class Date {
int d,m, y; // privado: acessível por funções membro
public: // público: acessível por qualquer cliente
void init(int dd, int mm, int yy) ;
void add_year(int n) { y += n; }
void add_month(int n) { m += n; }
void add_day(int n) { d += n; }
};
Renato Maia 101nov/2004
Classes e Estruturas
n Estruturas são equivalentes a classes, sendo que o 
controle de acesso padrão é o público.
struct X {
// ...
}
Equivalente a:
class X {
public:
// ...
}
Renato Maia 102nov/2004
Importância Controle Acesso
n Erros que causam inconsistência de dados 
privados são localizados na implementação das 
funções membro de acesso
n Alterações na implementação não são 
propagadas aos clientes
n Simplifica a utilização da classe, pois é 
necessário conhecer apenas a interface pública
Renato Maia 103nov/2004
Construtores
class Date {
int d,m, y;
public:
Date(int dd=0,int mm=0,int yy=0);
// ...
};
Date::Date(int dd, int mm, int yy)
{
d = dd ? dd : today.d;
m = mm ? mm : today.m;
y = yy ? yy : today.y;
// verifica de a data é válida
}
n Inicição de objetos Date
Date today(22) ;
Date july4(4, 7, 1983) ;
Date birthday(4, 12) ;
Date now;
Renato Maia 104nov/2004
Membros Estáticos
class Date {
int d,m, y;
static Date today;
public:
Date(int dd=0,int mm=0,int yy=0);
// ...
static void settoday(int, int, int);
};
Date Date::today(17, 11, 2004);
void Date::settoday(int d,int m,int y){
today = Date(dd, mm, yy)
}
n Acesso a membros estáticos
Date now;
now.settoday(22, 11, 2004);
ou
Date::settoday(22, 11, 2004);
Renato Maia 105nov/2004
Auto-Referência
n 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;
}
Renato Maia 106nov/2004
Funções Membro Constantes
n Não alteram os estado do objeto
class Date {
int d,m, y;
public:
int day() const { return d++; } // erro: tentativa de alteração do estado
int month() const;
// ...
};
inline int Date::month() const { return m; }
n Podem ser chamadas a partir de referências constantes
const Date my_date(12, 4, 1865);
cout << my_date.day() << "/"
<< my_date.month() << "/"
<< my_date.year()
Renato Maia 107nov/2004
Membros Mutáveis
n Alteração de membros através 
de funções membro 
constantes
string Date::string_rep() const
{
if (!cache_valid) {
compute_cache() ;
cache_valid = true;
}
return cache;
}
class Date {
mutable bool cache_valid;
mutable string cache;
void compute_cache() const;
// ...
public:
// ...
string string_rep() const;
};
Renato Maia 108nov/2004
Funções Auxiliares
n É possível definir funções auxiliares para manipular 
objetos
int diff(Date a,Date b) ;
bool leapyear(int y) ;
Date next_weekday(Date d) ;
Date next_saturday(Date d) ;
n Função membro vs. 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.
Renato Maia 109nov/2004
Funções Amigas
class Matrix;
class Vector {
float v[4] ;
// ...
friend Vector multiply(
const Matrix&,
const Vector&) ;
};
class Matrix {
Vector v[4] ;
// ...
friend Vector multiply(
const Matrix&,
const Vector&) ;
};
n Permite acessar a interface privada 
das classes
Vector multiply( const Matrix&m,
const Vector& v )
{
Vector r;
for (int i = 0; i<4; i++) { // r[i] = m[i] * v;
r.v[i] = 0;
for (int j = 0; j<4; j++)
r.v[i] +=m.v[i].v[j] * v.v[j] ;
}
return r;
}
Renato Maia 110nov/2004
Funções Amigas
n Funções Membro
class List_iterator {
// ...
int* next() ;
};
class List {
friend int* List_iterator::next() ;
// ...
};
n Classes Amigas
class List {
friend class List_iterator;
// ...
};
¨ Todas funções membro 
de List_iterator se tornam 
amigas da classe List
Renato Maia 111nov/2004
Exercício
n Implementar o tipo Date, como ilustrado nos 
exemplos anteriores:
¨ Construtor default
¨ Definir o valor da data default
n Use uma abordagem similar à função Date::settoday()
¨ Funções para acesso aos dados
n Dia, mês e ano
¨ Funções para adicionar dias, meses e anos
n Para simplificar, considere meses com exatos 30 dias.
nov/2004 Renato Maia 112
Objetos
Renato Maia 113nov/2004
Criação e Destruição
n Sempre que um objeto não é mais 
utilizado, ele deve ser destruído
n Assim como a inicialiação (ou construção) 
de objetos, a destruição pode ser feita 
automaticamente pelo compilador ou pode 
ser feita explicitamente
Renato Maia 114nov/2004
Destrutores
struct cache {
bool valid;
string rep;
};
class Date {
cache* c;
void compute_cache () const;
// ...
public:
Date(int dd=0,int mm=0,int yy=0);
~Date(); // destrutor
// ...
string string_rep() const;
};
n Libera os recursos alocados durante a 
construção do objeto
Date::Date(int dd,int mm,int yy)
{
c = new cache;
c->valid = false;
// ...
}
Date::~Date()
{
delete c;
}
Renato Maia 115nov/2004
Cópia Default
n Operação de cópia default
void apaga(Date *dia) {
Date copia = *dia;// copia.c = dia->c; copia.d = dia->d; ...
delete dia; // destrói o objeto, apaga 'c'
cout << "O dia " << copia.string_rep() << "foi apagado\n"; // erro
}
// ...
Renato Maia 116nov/2004
Variáveis Locais
n Construção:
¨ Fluxo de execução encontra a declaração da variável
n Destruição
¨ Variável sai do escopo
n Exemplo
void f(int i) {
if (i>0) {
Date aa;
// ...
}
Date bb;
// ...
}
Renato Maia 117nov/2004
Memória Dinâmica
n Construção
¨ Explicitamente através do operador new
Date *d = new Date(22, 11, 2004);
n Destruição
¨ Explicitamente através do operador delete
delete d;
n Cuidados
¨ Objetos destruídos
delete dia;
delete dia; // erro
¨ Brechas de memória (memory leaks)
void hoje() {
Date *dia = new Date();
cout << "Hoje é dia " << dia.string_rep() << "\n";
}
Renato Maia 118nov/2004
Membros de Classes
n Construção
¨ Na construção do objeto a que pertence, na ordem que aparecem na
declaração.
n Destruição
¨ Na destruição do objeto o que pertence , na ordem inversa da que
aparecem na declaração.
n Inicialização deMembros
class DaySequence {
const int days;
Date start;
public:
DaySequence(const Date& s, const int i) : days(i), start(s) { }
}
Renato Maia 119nov/2004
Vetores
n Construção
¨ Na criação do vetor
¨ Apenas é permitido para tipos com um construtor sem 
parâmetros
n Destruição
¨ Na destruição do vetor
n Exemplo
Date vds[10];// cria 10 objetos usando o construtor Date::Date()
Date vdd[10] = new Date[10];
delete[] vdd; // destroy os 10 objetos do vetor
Renato Maia 120nov/2004
Variáveis Locais Estáticas
n Construção
¨ Fluxo de execução encontra a declaração da variável pela primeira vez.
n Destruição
¨ Termino do programa
n Exemplo
// Declaração das variáveis // Construção dos objetos
void f(int i) { f(0); // d1 é construído
static Date d1; f(1); // apenas o d2 é contruído
// ... f(2); // nenhum dos objetos é criado
if (i) {
static Date d2;
// ...
}
}
Renato Maia 121nov/2004
Não Locais
n Variáveis não locais:
¨ Variáveis globais
¨ Variáveis em espaços de nomes
¨ Variáveis estáticas de classe
n Construção
¨ Antes no início da função main
¨ Na ordem que suas definições aparecem
n Destruição
¨ Após o término da função main
¨ Na ordem inversa que suas definições aparecem
n Exemplo
class X { static Date memdate; }; // apenas a definição do membro estático
Date date; // declaração de variável global
Date X::memdate; // declaração do membro estático da classe X
namespace Z { Date date2; } // delaração da varíavel no espaço de nomes
Renato Maia 122nov/2004
Objetos Temporários
n Construção
¨ Na avaliação da expressão que os criam
n Destruição
¨ Ao final da avaliação da expressão que os criam
n Exemplo
void f(string& s1, string& s2, string& s3)
{
const char* cs= (s1+s2).c_str() ;
cout << cs; // problema: cs aponta para uma área desalocada
if (strlen(cs=(s2+s3).c_str())<8 && cs[0]==´a´) { // ok
// qualquer uso de cs aqui é inválido
}
}
Renato Maia 123nov/2004
Exercício
n Implementar o tipo Table, que deve oferecer a seguinte interface:
struct Name {
enum Gender { male, female }
const char* s;
Gender g;
};
class Table {
Name* p;
size_t sz; int c;
public:
Table(size_t s = 15);
~Table();
Name* lookup(const char *) ;
bool insert(Name&) ;
};
nov/2004 Renato Maia 124
Sobrecarga de 
Operadores
Renato Maia 125nov/2004
Operadores Disponíveis
n Operadores que podem ser redefinidos
+- * / % ^ &
| ~ ! = < > +=
-= *= /= %= ^= &= |=
<< >> >>= <<= == != <=
>= && || ++ -- ->* ,
-> [] () new new[] delete delete[]
n Operadores que NÃO podem ser redefinidos
:: (Resolução de escopo)
. (Seleção de membros)
.* (Seleção de membros através de ponteiros para função)
Renato Maia 126nov/2004
Funções Operadoras
n Função Membro
class complex {
double re, im;
public:
complex(double r, double i=0) : re(r) , im(i) { }
complex operator+(complex) ;
};
n Função Auxiliar
complex operator+(complex, double) ;
Renato Maia 127nov/2004
Casamento de Função Operador
n Escolha da função operador para um 
operador @
¨Operadores Binários (a@b)
a.operator@(b) ou ::operator@(a, b)
¨Operadores Unários (a@)
a.operator@() ou ::operator@(a)
Renato Maia 128nov/2004
Exemplos de Sobrecarga de 
Operadores
class X {
// members (with implicit 'this' pointer):
X* operator&() ; // & unário (endereço de)
X operator&(X) ; // & binário (e bit a bit)
X operator++() ; // incremento prefixo
X operator&(X,X) ; // erro: ternário
X operator/() ; // erro: / unário
};
// nonmember functions:
X operator-(X) ; // menos unário
X operator-(X,X) ; // menos binário
X operator--(X&,int) ; // decremento posfixo
X operator-(); // erro: nenhum operando
X operator-(X,X,X) ; // erro: ternário
X operator%(X) ; // erro: % unário
Renato Maia 129nov/2004
Significados Predefinidos
n As funções operator=, operator[], operator() e operator-> devem 
ser definidas como funções membro não estáticas
n Apenas alguns operadores já possuem um significado predefinido
= (atribuição, faz cópia dos valores dos membros)
& (endereço de, retorna o endereço do objeto)
, (seqüência, retorna o valor do segundo parâmetro)
n Entretanto, esses significados podem ser redefinidos através da 
sobrecarga de operadores
Renato Maia 130nov/2004
Cópia de Objetos
n Construtor de cópia
Date::Date(const Date& other) { // exemplo:
c = new cache; // Date copia = data;
c->valid = false;
d = other.d; m = other.m; y = other.y;
}
n Operador de atribuição
Date::operator=(const Date& other) { // exemplo:
if (*this != other) { // Date copia(2, 4, 1876);
delete c; // copia = data;
c = new cache;
c->valid = false;
d = other.d; m = other.m; y = other.y;
}
}
Renato Maia 131nov/2004
Procura pela Implementação de 
Operadores
n Considere a expressão x@y, (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
n Procura por declarações de operator@ no contexto de x@y
n Adicinonalmente, se X é definido num espaço de nomes N, procura por 
declarações de @ em N
n Adicinonalmente, se Y é definido num espaço de nomes M, procura por 
declarações de @ em M.
Neste último caso, todas as declarações de operator@ são levadas em 
consideração para determinar a que se adequa a expressão.
n As mesmas regras para casamento de funções sobrecarregadas 
são aplicadas a operadores.
Renato Maia 132nov/2004
Conversões Implícitas
bool operator==(complex,complex) ;
void f(complex x, complex y)
{
x==y; // significa operator==(x,y)
x==3; // significa operator==(x,complex(3))
3==y; // significa operator==(complex(3),y)
}
n Essas conversão não se aplicam para funções operadoras membro
Renato Maia 133nov/2004
Operadores de Conversão 
Explícita
class Tiny {
char v;
void assign(int i) { if (i&~077) v=0; else v=i; }
public:
Tiny(int i) { assign(i) ; }
Tiny& operator=(int i) { assign(i) ; return *this; }
operator int() const { return v; } // conversão para int
};
n Atenção
Tiny::operator int() const { return v; } // certo
int Tiny::operator int() const { return v; } // errado
Renato Maia 134nov/2004
Ambigüidades
n Sempre que a combinação de construtores e operadores de conversão 
gerarem ambiguidade na resolução de funções sobrecarregadas, o 
compilador informará o erro.
n Tome cuidado com conversões inesperadas (ou a falta delas)
class Quad {
public:
Quad(double) ;
// ...
};
Quad operator+(Quad,Quad) ;
void f(double a1, double a2)
{
Quad r1 = a1+a2; // adição com precisão dupla
Quad r2 =Quad(a1)+a2; // força aritmética da classe quad
}
Renato Maia 135nov/2004
Construtores Explícitos
n Considere
complex z = 2; // inicializa z com complex(2)
String s = 'a'; // cria uma string com int('a') elementos
n Solução
class String {
// ...
explicit String(int n) ; // prealoca n bytes
String(const char* p) ; // valor inicial é uma string C
string p
};
Renato Maia 136nov/2004
Operador de Indexação
class Assoc {
struct Pair {
string name; double val;
Pair(string n ="", double v =0)
:name(n) , val(v) { }
};
vector<Pair> vec;
// privado para prevenir cópia
Assoc(const Assoc&) ;
Assoc& operator=(const Assoc&) ;
public:
Assoc() {}
double& operator[](const string&) ;
void print_all() const;
};
double& Assoc::operator[](const string& s) {
vector<Pair>::iterator p=vec.begin();
for (; p!=vec.end(); ++p)
if (s == p->name) return p->val;
vec.push_back(Pair(s,0)) ;
return vec.back().val;
}
void Assoc::print_all() const {
vector<Pair>::const_iterator p=vec.begin();
for (; p!=vec.end(); ++p)
cout << p->name << ": "
<< p->val << ´\n´;
}
Renato Maia 137nov/2004
Operador de Chamada de Função
class Add {
complex val;
public:
Add(complex c) { val= c; } // salva o valor
Add(double r, double i) { val = complex(r,i) ; }
void operator()(complex& c) const { c += val; } // adiciona valor
};
complex vc[10];
void for_each(Add& func) { for (int i = 0; i < 10; i++) func(vc[i]); }
void main() {
Add func(2, 3);
for_each(func);
}
Renato Maia 138nov/2004
Operador de Dereferência
n Declaração (operador unário)
class Ptr { /* ... */ X* operator->(); };
n Transformação
void f(Ptr p) {
p->m = 7; // (p.operator–>())–>m = 7
}
n Uso
void g(Ptr p) {
X* q1 = p->; // erro de sintaxe
X* q2 = p.operator->();// ok
}
Renato Maia 139nov/2004
Operadores Unários Posfixos
class Ptr_to_T {
T* p;
T* array;
int size;
public:
Ptr_to_T(T* p, T* v, int s) ; // associa a pos. p do vetor v de tam. s
Ptr_to_T& operator++() ; // prefixo
Ptr_to_T operator++(int) ; // posfixo
Ptr_to_T& operator--(); // prefixo
Ptr_to_T operator--(int) ; // posfixo
T&operator*() ; // prefixo
};
nov/2004 Renato Maia 140
Classes Derivadas
Renato Maia 141nov/2004
Classes Derivadas
class Employee {
string name;
Date hiring_date;
shot department;
// ...
public:
void print() const;
string get_name() const {
return name; }
// ...
};
class Manager : public Employee {
set<Employee*> group;
short level;
// ...
public:
void print() const;
// ...
};
Renato Maia 142nov/2004
Estrutura de Objetos
Employee:
name
department
...
name
department
...
group
level
...
Manager:
Renato Maia 143nov/2004
Polimorfismo
void f(Manager m1, Employee e1) {
list<Employee*> elist;
elist.push_front(&m1);
elist.push_front(&e1);
}
void g(Manager mm, Employee ee) {
Employee* pe= &mm; // ok: todo Gerente é um Empregado
Manager* pm= &ee; // erro: nem todo Empregado é um Gerente
pm->level = 2; // desastre: ee não tem um 'level'
pm = static_cast<Manager*>(pe) ; // força bruta, mas funciona
pm->level = 2; // ok: pm aponta para mm que tem um 'level'
}
Renato Maia 144nov/2004
Implement. de Funções Membro
n Não é possível acessar membros privados em classes derivadas
void Manager::print() const {
cout << "Name: "<< name << '\n'; // erro: name é privado
cout << "\tDept:\t"<< department << '\n'; // erro: department é privado
cout << "\tLevel:\t" << level << '\n';
cout << "\tTeam:\t" << group.size() << '\n';
}
n É necessário usar a interface pública (e protegida, i.e. protected)
void Manager::print() const {
Employee::print(); // cuidado: print() não qualificado causa recursão
cout << "\tLevel:\t" << level << '\n';
cout << "\tTeam:\t" << group.size() << '\n';
}
Renato Maia 145nov/2004
Controle de Acesso
n Escopo Privado (private)
¨ Nomes podem ser usados em funções membro e 
funções amigas da classe.
n 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.
n Escopo Público (public)
¨ Nomes podem ser usados em quaisquer funções.
Renato Maia 146nov/2004
Acesso a Membros Herdados 
n 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.
n 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.
n class Z : private B { /* ... */ };
¨ 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. 
Adicionalmente, o acesso aos membros protegidos de B só 
pode ser feito em funções membro e amigas de Z e de suas 
classes derivadas.
Renato Maia 147nov/2004
Construção
n Classe Base
Employee(const string& n, int d)
: name(n), department(d)
{
// …
}
n Classe Derivada
Manager(const string& n, int d, int lvl)
: Employee(n, d), level(lvl) // não é possível iniciar diretamente
// os membros de Employee
{
// …
}
Renato Maia 148nov/2004
Cópia Fatiada
n Exemplo
void f(const Manager& m) {
Employee e = m; // constrói e a partir da parte Employee de m
e = m; // atribui a parte Employee de m a e
}
n Cuidado
void slice_copy(Employee ee) {
ee.print(); 
}
// ...
Manager m("John Gee", 1, 4);
slice_copy(m); // objeto Employee criado com os dados de m
Renato Maia 149nov/2004
Funções Virtuais
n Definição
class Employee {
// ...
virtual void print() const;
};
n Exemplo
void virtual_call(Employee* ee) {
ee->print(); // a função print adequada é chamada
}
// ...
Manager m("John Gee", 1, 4);
virtual_call(&m);
Renato Maia 150nov/2004
Classes Abstratas
n Permite definir classes com 
funções sem implementação
class Shape {
public:
// funções virtuais puras
virtual void rotate(int) = 0;
virtual void draw() = 0;
virtual bool is_closed() = 0;
// ...
};
n Não é possível criar objetos de 
classes abstratas
Shape s; // erro: Shape é abstrata
n Classes abstratas somente são 
utilizadas como classe base
class Point { /* ... */ };
class Circle : public Shape {
public:
// define funções virtuais herdadas
void rotate(int) { }
void draw() ;
bool is_closed() { return true; }
Circle(Point p, int r) ;
private:
Point center;
int radius;
};
Renato Maia 151nov/2004
Ponteiros para Membros
struct Class {
const char* memb_data;
virtual void memb_func() = 0;
};
typedef void (Class::*PMF)() ; // tipo ponteiro para função membro
typedef const char* Class::*PMD; // tipo ponteiro para membro de dado
void f(Class* p) {
PMF pmf = &Class::memb_func();
p->memb_func() ; // chamada direta
(p->*pmf)() ; // chamada através de ponteiro para membro
PMD pmd = &Class::memb_data;
p->memb_data() ; // acesso direto
p->*pmd = "string" ; // acesso através de ponteiro para membro
}
Renato Maia 152nov/2004
Propósito de Classes Concretas 
n Classes concretas são usadas para definir novos tipo 
(e.g. classe Date) que façam tarefas simples e de forma 
eficiente.
n Se o comportamento de uma classe concreta não é 
adequado, uma nova classe deve ser construída. Se 
possível utilizando a classe concreta, da mesma forma 
se utiliza um int na classe Date.
n 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 153
Herança Múltipla
Renato Maia 154nov/2004
Problema
n Suponha um sistema de simulação onde cada 
elemento simulado realiza uma tarefa e possui 
uma representação visual dessa tarefa.
n Cada elemento tem o comportamento de uma 
tarefa e de algo visual.
n 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
Renato Maia 155nov/2004
Solução com Herança Múltipla
n Para cada elemento simulado 
a sua repesentação visual 
(Displayed) é muito 
dependente da sua tarefa 
(Task).
n 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. 
Task
dados
funções
Displayed
dados
funções
Satellite
dados
funções
Renato Maia 156nov/2004
Herança Múltipla
n Classe com herança múltipla
class Satellite : public Task, public Displayed {
// ...
};
n É possível acessar membros das duas classes base
void f(Satellite& s) {
s.draw() ; // Displayed::draw()
s.delay(10) ; // Task::delay()
s.transmit() ; // Satellite::transmit()
}
Renato Maia 157nov/2004
Herança Múltipla
n Objetos de classes com herança múltipla de comportam 
como um objeto de cada classe base
void highlight(Displayed*) ;
void suspend(Task*) ;
voidg(Satellite* p) {
highlight(p) ; // passa um ponteiro para a parte Displayed
suspend(p) ; // passa um ponteiro para a parte Task
}
Renato Maia 158nov/2004
Resolução de Ambigüidade
class Task {
// ...
virtual debug_info* get_debug() ;
};
class Displayed {
// ...
virtual debug_info* get_debug() ;
};
void f(Satellite* sp) {
debug_info* dip = sp->get_debug() ; // erro: ambíguo
dip = sp->Task::get_debug() ; // ok
dip = sp->Displayed::get_debug() ; // ok
}
Renato Maia 159nov/2004
Redefinição de Membros
n Definir na classe derivada o comportamento adequado
class Satellite : public Task, public Displayed {
// ...
debug_info* get_debug() // defefine Task::get_debug() e
// Displayed::get_debug()
{ 
debug_info* dip1 = Task::get_debug() ;
debug_info* dip2 = Displayed::get_debug() ;
return dip1->merge(dip2) ;
}
};
Renato Maia 160nov/2004
Classes Base Duplicadas
struct Link {
Link* next;
};
class Task : public Link {
// o Link é usado para manter
// a lista de todas Tasks.
// ...
};
class Displayed : public Link {
// o Link é usado para manter
// a lista de todos Displayed.
// ...
};
Task
dados
funções
Displayed
dados
funções
Satellite
dados
funções
Link
dados
funções
Link
dados
funções
Renato Maia 161nov/2004
Classes Base Duplicadas
n Atenção:
void insert_before(Satellite* s, Task* t, Displayed* d)
{
s->next = t.next; // erro: ambíguo
s->Task::next = t.next;
s->Displayed::next = d.next;
t.next = s;
d.next = s;
}
Renato Maia 162nov/2004
Classes Base Virtuais
n Classes base virtuais não 
são duplicadas quando 
herdadas
class Task
: public virtual Link {
// ...
};
class Displayed
: public virtual Link {
// ...
};
Task
dados
funções
Displayed
dados
funções
Satellite
dados
funções
Link
dados
funções
Renato Maia 163nov/2004
Controle de Acesso
struct B {
int m;
// ...
};
class D1 : public virtual B { /* ... */ } ;
class D2 : public virtual B { /* ... */ } ;
class DD : public D1, private D2 { /* ... */ };
DD* pd = new DD;
B* pb = pd; // ok: accessível através de D1
int i1 = pd->m; // ok: accessível através de D1
Renato Maia 164nov/2004
Usando Herança Múltipla
n Múltiplas interfaces
¨ Compor uma classe com uma interface composta da 
interface de duas outras classes.
n Classes intimamente dependentes
¨ Reduzir o uso de funções amigas juntando a 
implementação de duas classes intimamente 
dependentes numa única.
n Reutilização de código
¨ Permitir compor uma nova classe a partir da 
implementação de outras
nov/2004 Renato Maia 165
Templates
Renato Maia 166nov/2004
Declaração
template<class C> class String {
struct Srep;
Srep *rep;
public:
String();
String(const C*);
String(const String&);
C read(int i) const;
// ...
};
Renato Maia 167nov/2004
Definição
template<class C> struct String<C>::Srep {
C* s; // ponteiro para elementos
int sz; // número de elementos
// ...
};
template<class C> C String<C>::read(int i) const { return rep->s[i] ; }
template<class C> String<C>::String()
{
p = new Srep(0,C()) ;
}
Renato Maia 168nov/2004
Instanciação
n Versão com char
int main() {
String<char> buf;
map<String<char>,int> m;
while (cin>>buf) m[buf]++;
// escreve o resultado
}
n Versão com Jchar (tipo fictício para representar caracteres japoneses)
int main() {
String<Jchar> buf;
map<String<Jchar>,int> m;
while (cin>>buf) m[buf]++;
// escreve o resultado
}
Renato Maia 169nov/2004
Parâmetros
n Um tipo
template<class C> class String { /* … */ }
n Uma constante de um tipo básico (int, double, etc.)
template<class T, int i> class Buffer { T v[i]; int sz; /* … */ }
n Outros templates
template<class T, template<class> class C> class Xrefd {
C<T> mems;
C<T*> refs;
// ...
};
Xrefd<Entry,vector> x1;
Renato Maia 170nov/2004
Equivalência de Tipos
n Considere
¨ String<char> s1;
¨ String<unsigned char> s2;
¨ typedef unsigned char Uchar;
¨ String<Uchar> s3;
¨ String<char> s4;
¨ Buffer<char, 10> b2;
¨ Buffer<char, 20-10> b3; // o compilador pode avaliar expressões constantes.
n As seguintes variáveis são do mesmo tipo
¨ s1 ó s4
¨ s2 ó s3
¨ b1 ó b2
Renato Maia 171nov/2004
Corretude do Template
template<class T> class List {
struct Link {
Link* suc;
T val;
Link(Link* s, const T& v) : suc(s) , val(v) { }
} // erro de sintaxe: faltando um ponto e vírgula
Link* head;
public:
List() : head(7) { } // erro: ponteiro inicializado com int
void print_all() { for (Link* p = head; p; p=p->suc) cout << p->val << '\n'; }
};
void f(List<int>& li, List<Rec>& lr) {
li.print_all() ; // ok
lr.print_all() ; // erro: se Rec não define o operador <<
}
Renato Maia 172nov/2004
Template de Funções
template<class T> void sort(vector<T>& v) {
// Shell sort (Knuth, Vol. 3, pg. 84).
const size_t n = v.size() ;
for (int gap=n/2; 0<gap; gap/=2)
for (int i=gap; i<n; i++)
for (int j=i-gap; 0<=j; j-=gap)
if (v[j+gap]<v[j]) swap(v[j], v[j+gap]);
}
void f(vector<int>& vi, vector<string>& vs) {
sort(vi) ; // sort(vector<int>&);
sort(vs) ; // sort(vector<string>&);
}
Renato Maia 173nov/2004
Definição dos Parâmetros de Uma 
Função Template
template<class T, class U> T implicit_cast(U u) { return u; }
void g(int i)
{
implicit_cast(i) ; // error: não pode deduzir T
implicit_cast<double>(i) ; // T é double; U is int
implicit_cast<char, double>(i) ; // T é char; U is double
implicit_cast<char*, int>(i) ; // T é char*; U é int; erro
}
Renato Maia 174nov/2004
Parâmetros Default
template<class T = int, class U> T implicit_cast(U u) { return u; }
void g(int i)
{
implicit_cast(i) ; // T é int; U is int
implicit_cast<double>(i) ; // T é double; U is int
implicit_cast<char, double>(i) ; // T é char; U is double
implicit_cast<char*, int>(i) ; // T é char*; U é int; erro
}
Renato Maia 175nov/2004
Especializações
template<class T> class Vector<T*> : private Vector<void*> {
public:
typedef Vector<void*> Base;
Vector() : Base() {}
explicit Vector(int i) : Base(i) {}
T*& elem(int i) { return static_cast<T*&>(Base::elem(i)) ; }
T*& operator[](int i) { return static_cast<T*&>(Base::operator[](i)) ; }
// ...
};
Vector<Shape*> vps;
Vector<char*> vpc;
Vector<Node*> vpn;
Renato Maia 176nov/2004
Templates e Herança
class Shape { /* ... */ };
class Circle : public Shape { /* ... */ };
class Triangle : public Shape { /* ... */ };
void f(set<Shape*>& s) {
// ...
s.insert(new Triangle()) ;
// ...
}
void g(set<Circle*>& s) {
f(s) ; // erro, s é um set<Circle*>, não um set<Shape*>
}
nov/2004 Renato Maia 177
Exceções
Renato Maia 178nov/2004
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;
}
Renato Maia 179nov/2004
Captura
void g(int i)
{
try {
char c = to_char(i) ;
// ...
}
catch (Range_error) {
cerr << "oops\n";
}
}
Renato Maia 180nov/2004
Hierarquia de Exceções 
class Matherr{ };
class Overflow: public Matherr{ };
class Underflow: public Matherr{ };
class Zerodivide: public Matherr{ };
void f() {
try { /* ... */ }
catch (Overflow) {
// trata Overflow ou qualquer coisa que derive de Overflow
}
catch (Matherr) {
// trata qualquer Matherr que são seja Overflow
}
}
Renato Maia 181nov/2004
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
}
}
Renato Maia 182nov/2004
Captura de Qualquer Exceçãovoid m()
{
try {
// faz algo
}
catch (...) { // trata qualquer exceção
// limpeza
throw;
}
}
Renato Maia 183nov/2004
Ordem de Captura
void g()
{
try { /* ... */ }
catch (...) {
// 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
}
}
Renato Maia 184nov/2004
Exceções em Construtores 
class Vector {
public:
class Size{ };
enum {max = 32000 };
Vector::Vector(int sz)
{
if (sz<0 ||max<sz)
throw Size() ;
// ...
}
// ...
};
Vector* f(int i)
{
try {
Vector* p = new Vector(i) ;
// ...
return p;
}
catch(Vector::Size) {
// lida com erro de tamanho
}
}
Renato Maia 185nov/2004
Exceções na Iniciação de Membros 
class X {
Vector 
v;
// ...
public:
X(int) ;
// ...
};
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) {
// ...
}
Renato Maia 186nov/2004
Exceções em Destrutores
n Durante o lançamento de uma exceção os objetos que perdem seu 
escopo são destruídos
n Exceções lançadas por destrutores durante o lançamento de uma 
exceção causam o encerramento do programa
n Para evitar essa situação usa-se a função da biblioteca padrão 
uncaught_exception
X::~X()
try { f(); }
catch (...) {
if (uncaught_exception()) {
// faça algo
else throw; // re-lança
}
Renato Maia 187nov/2004
Especificação de Exceções
void f() throw (x2, x3) { /* ... */ }
n Equivalente a:
void f()
try { /* ... */ }
catch (x2) { throw; }
catch (x3) { throw; }
catch (...) {
std::unexpected() ; // encerra a aplicação
}
Renato Maia 188nov/2004
Exceções Não Capturadas
n Exceções não especificadas resultam na chamada de 
std::unexpected, que chama um tratador definido pela seguinte 
função:
¨ typedef void (*unexpected_handler)() ;
¨ unexpected_handler set_unexpected(unexpected_handler) ;
n Exceções não capturadas resultam na chamada de std::terminate, 
que chama um tratador definido pela seguinte função:
¨ typedef void (*terminate_handler)() ;
¨ terminate_handler set_terminate(terminate_handler) ;
Renato Maia 189nov/2004
Exceções Padrão
n Lançadas pela linguagem
bad_alloc lançada pelo operador new
bad_cast lançada pelo operador dynamic_cast
bad_typeid lançada pelo operador typeid
bad_exception lançada por uma função com especificação de exceções
n Lançadas pela bibioteca padrão
exception
logic_error runtime_error
length_error
domain_error
out_of_range
invalid_argument
range_error
overflow_error
underflow_error
out_of_range
bad_cast
bad_typeid
bad_alloc
bad_exception
nov/2004 Renato Maia 190
Run-Time Type
Information (RTTI)
Renato Maia 191nov/2004
Exemplo
class Component
: public virtual Storable
{ /* ... */ };
class Receiver
: public Component
{ /* ... */ };
class Transmitter
: public Component
{ /* ... */ };
class Radio
: public Receiver,
public Transmitter
{ /* ... */ };
Component Component
Radio
Storable
Receiver Transmisser
Renato Maia 192nov/2004
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()) ;
else {
// Opa! Não é possível ecoar
}
}
Renato Maia 193nov/2004
Classes Não-Polimórficas
class My_storable: public Storable {
// ... // base polimórfica (tem funções virtuais)
};
class My_date : public Date { 
// ... // base não polimórfica (não 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) ; // erro: Date não 
// é polimórfica
}
Renato Maia 194nov/2004
Conversão de Referências
n O operador dynamic_cast em referências lança
a exceção bad_cast
try
{
Transmitter& t = dynamic_cast<Transmitter&>(r);
t.send(r.receive());
}
catch (bad_cast){ /* ... */ }
Renato Maia 195nov/2004
Ambigüidades
n Objetos da classe Radio são compostos por dois objetos 
Component (de Receiver e Transmitter)
void h1(Radio& r)
{
Storable* ps = &r;
// ...
Component* pc = dynamic_cast<Component*>(ps) ; // pc = 0
}
Renato Maia 196nov/2004
Navegando na Hierarquia de 
Classes
void g(Radio& r)
{
Receiver* prec= &r; // Receiver é uma base de Radio
Radio* pr = static_cast<Radio*>(prec) ; // ok, sem verificação
pr = dynamic_cast<Radio*>(prec) ; // ok, verificação dinâmica
Storable* ps= &r; // Storable é base virtual
pr = static_cast<Radio*>(ps) ; // erro: conversão de base virtual
pr = dynamic_cast<Radio*>(ps) ; // ok, verificação dinâmica
}
Renato Maia 197nov/2004
Construção e Destruição de 
Objetos
n Durante a construção ou destruição de um 
objeto, 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, 
mesmo que seja a criação de um objeto de uma 
classe derivada.
Renato Maia 198nov/2004
Operador typeid
n Pseudo declaração
class type_info;
const type_info& typeid(type_name) throw(bad_typeid) ;
const type_info& typeid(expression) ;
.
Renato Maia 199nov/2004
Informações de Tipo
class type_info {
public:
virtual ~type_info() ; // é polimórfico
bool operator== (const type_info&) const; // pode ser comparado
bool operator!= (const type_info&) const;
bool before(const type_info&) const; // ordem
const char* name() const; // nome do tipo
private:
type_info(const type_info&) ; // evita cópia
type_info& operator=(const type_info&) ; // evita cópia
// ...
};
Renato Maia 200nov/2004
Mal Uso do RTTI
n Programadores de 
linguagems
procedurais
¨ C, Pascal, Modula-2 
e Ada
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
}
// ...
}
Renato Maia 201nov/2004
Mal Uso do RTTI
n Programadores de linguagens
altamente dependentes de 
verificação dinâmica de tipos
¨ Smaltalk, Lisp, Java(?)
class Object{ /* ... */ }; // polimórfico
class Container : public Object {
public:
void put(Object*) ;
Object* get() ;
// ...
};
class Ship : public Object{ /* ... */ };
Ship* f(Ship* ps,Container* c) {
c->put(ps) ;
// ...
Object* p = c->get() ;
if (Ship* q=dynamic_cast<Ship*>(p))
{
return q;
}
else
{
// faça algo (lança um erro)
}
}
nov/2004 Renato Maia 202
MODULO III
Biblioteca Padrão
Renato Maia 203nov/2004
Biblioteca Padrão
n Parte 1:
¨ Visão Geral
¨ Contêiners
n Parte 2:
¨ Iteradores
¨ Algoritmos
¨ Objetos Função
n Parte 3:
¨ Strings
¨ Streams
nov/2004 Renato Maia 204
Visão Geral
Renato Maia 205nov/2004
Organização
n Contêiners
¨ Estruturas de dados
n Utilidades
¨ Operadores, pares, objetos 
função, alocadores, etc.
n Iteradores
n Algoritmos
¨ Busca, ordenação, etc.
n Diagnóstico
¨ Exceções, assetivas, etc.
n Strings
n I/O
¨ Streams, buffers, arquivos, 
etc.
n Localização
¨ Configurações regionais
n Suporte C++
¨ Limites numéricos, RTTI, 
etc.
n Numérica
¨ Complexos, operações 
sobre vetores e matrizes, 
etc.
Renato Maia 206nov/2004
Standart Template Library
Contêiners
(estruturas de dados)
Algoritmos
(operações)
Iteradores
(acesso genérico)
nov/2004 Renato Maia 207
Contêiners
Renato Maia 208nov/2004
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 209nov/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 210nov/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;
}
Renato Maia 211nov/2004
Características Comuns
n Tipos parametrizados
¨ value_type Tipo dos elementos
¨ allocator_type Tipo do alocador usado
n Tipos de iteradores
¨ iterator Tipo do iterador
¨ const_iterator Tipo do iterador constante
¨ reverse_iterator Tipo do iterador reverso
¨ const_reverse_iterator Tipo do iterador reverso constante
n Tipos ponteiro e referência
¨ pointer Tipo ponteiro para o elemento
¨ const_pointer Tipo ponteiro constante para o elemento
¨ reference Tipo referência para o elemento
¨ const_reference Tipo referência constante para o elemento
Renato Maia 212nov/2004
Características Comuns
n Criação e destruição
¨ Construtor default Cria o contêiner vazio
¨ Construtor de cópia Copia um contêiner de mesmo tipo
¨ Construtor(begin, end) Cria um contêiner e copia em [begin, end[
¨ Destrutor Apaga todos os elementos e libera a memória
n 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
Renato Maia 213nov/2004
Características Comuns
n Acesso
¨ size() Devolve o número de elementos
¨ empty() Verifica se o contêiner está vazio
¨ max_size() Devolve o número máximo de elementos
¨ begin() Iterador para o início
¨ end() Iterador para um após o fim
¨ rbegin() Iterador para o início da iteração reversa
¨ rend() Iterador para um após o fim da iteração reversa
n Alteração
¨ swap(c) Troca o conteúdo com outro contêiner (::swap(c,c))
¨ insert(pos,elem) Insere uma cópia de elem (significado de pos varia)
¨ erase(beg,end) Remove todos os elementos em [beg,end[
¨ clear() Remove todos os elementos
Renato Maia 214nov/2004
Requisitos dos Elementos
n Cópia
¨ Os elementos devem poder ser copiados, pois os 
contêiners guardam cópias de elementos.
n Comparação
¨ Containers associativos fazem comparação dos 
elementos nas buscas (< e =)
n O que acontece no código abaixo?
std::map<char*,int> map;
char name[] = "Renato";
map[name] = 11;
cout << map["Renato"] << '\n';
Renato Maia 215nov/2004
Contêiner Vetor
n seqüência de elementos para acesso aleatório
¨ J Acesso aleatório
¨ L Alterações no meio ou no início
n Cabeçalho
¨ #include <vector>
n Parâmetros
¨ Tipo dos elementos armazenados
¨ Tipo do gerenciador de memória (opcional)
n Exemplos
¨ vector<int> vi;
¨ vector<MyClass> vobj;
¨ vector<vector<string> > mtrstr;
Renato Maia 216nov/2004
Operações do Contêiner Vetor
n Construtores
¨ vector(n) n posições com valor default
¨ vector(n,val) n posições com valor val
n Atribuição
¨ assign(beg, end) Atribui um vetor com os valores de [beg,end[
¨ assign(n,val) Atribui um vetor com n cópias de val
n Acesso
¨ [pos] Indexação sem verificação
¨ at(pos) Indexação com verificação
¨ front() Primeiro elemento
¨ back() Último elemento
Renato Maia 217nov/2004
Operações do Contêiner Vetor
n Capacidade
¨ capacity() Tamanho de posições alocadas
¨ reserve(n) Reserva espaço para um total de n elemetos
n Tamanho
¨ resize(n) Altera o número de elementos
¨ resize(n,val) Idem, val define o valor de inicialização
n Alteração no final
¨ push_back(val) Adiciona ao final
¨ pop_back() Remove o último elemento
n Alteração na seqüência
¨ insert(pos,val) Insere cópia de val antes de pos
¨ insert(pos,n,val) Insere n cópias de val antes de pos
¨ insert(pos,beg, end) Insere os valores de [beg,end[ antes de pos
¨ erase(pos) Apaga elemento em p
Renato Maia 218nov/2004
Contêiner Lista
n seqüência de elementos para acesso seqüêncial
¨ J Alterações na ordem dos elementos
¨ J Inserções em quaisquer pontos da seqüência
¨ L Acesso aleatório
n Cabeçalho
¨ #include <list>
n Parâmetros
¨ Tipo dos elementos armazenados
¨ Tipo do gerenciador de memória (opcional)
n Exemplos
¨ list<int> li;
¨ list<MyClass> lobj;
¨ list<vector<string> > lvet;
Renato Maia 219nov/2004
Operações do Contêiner Lista
n Construtores
¨ list(n) n posições com valor default
¨ list(n,val) n posições com valor val
n Atribuição
¨ assign(beg, end) Atribui um vetor com os valores de [beg,end[
¨ assign(n,val) Atribui um vetor com n cópias de val
n Acesso
¨ front() Primeiro elemento
¨ back() Último elemento
Renato Maia 220nov/2004
Operações do Contêiner Lista
n Alteração nas extremindades
¨ push_back(val) Adiciona ao final
¨ pop_back() Remove o último elemento
¨ push_front(val) Adiciona um novo primeiro elemento
¨ pop_front() Remove o primeiro elemento
n Alteração na seqüência
¨ insert(pos,val) Insere cópia de val antes de pos
¨ insert(pos,n,val) Insere n cópias de val antes de pos
¨ insert(pos,beg, end) Insere os valores de [beg,end[ antes de pos
¨ erase(pos) Apaga elemento em p
Renato Maia 221nov/2004
Operações do Contêiner Lista
n Remoção
¨ remove(val) Remove todos os elementos com valor val
¨ remove_if(op) Remove os elementos que op(elem)==true
¨ unique() Remove duplicatas
¨ unique(op) Remove duplicatas que op(elem)==true
n Alterações sem cópia
¨ splice(pos,list) incorpora todos os elementos de list para antes de pos
¨ splice(pos,list,p) move *p de list para antes de pos
¨ splice(pos,list,beg,end) move os elementos de list em [beg,end[ ... idem
¨ sort() Ordena usando operador <
¨ sort(op) Ordena usando comparação cmp
¨ merge(list) Internala com list mantendo a ordenação (<)
¨ merge(list,op) Internala com list mantendo a ordenação (op)
¨ reverse() Inverte a ordem dos elementos
Renato Maia 222nov/2004
Contêiner Fila Dupla
n seqüência de elementos para acesso nas extremidades
¨ J Acesso nas extremidades
¨ L Alterações no meio da seqüência
n Cabeçalho
¨ #include <deque>
n Parâmetros
¨ Tipo dos elementos armazenados
¨ Tipo do gerenciador de memória (opcional)
n Exemplos
¨ deque<int> dqi;
¨ deque<MyClass> dqobj;
¨ deque<vector<string> > dqvet;
Renato Maia 223nov/2004
Operações do Contêiner Fila Dupla
n Construtores
¨ deque(n) n posições com valor default
¨ deque(n,val) n posições com valor val
n Atribuição
¨ assign(beg, end) Atribui um vetor com os valores de [beg,end[
¨ assign(n,val)Atribui um vetor com n cópias de val
n Acesso
¨ [pos] Indexação sem verificação
¨ at(pos) Indexação com verificação
¨ front() Primeiro elemento
¨ back() Último elemento
Renato Maia 224nov/2004
Operações do Contêiner Fila Dupla
n Tamanho
¨ resize(n) Altera o número de elementos
¨ resize(n,val) Idem, val define o valor de inicialização
n Alteração nas extremindades
¨ push_back(val) Adiciona ao final
¨ pop_back() Remove o último elemento
¨ push_front(val) Adiciona um novo primeiro elemento
¨ pop_front() Remove o primeiro elemento
n Alteração na seqüência
¨ insert(pos,val) Insere cópia de val antes de pos
¨ insert(pos,n,val) Insere n cópias de val antes de pos
¨ insert(pos,beg, end) Insere os valores de [beg,end[ antes de pos
¨ erase(pos) Apaga elemento em p
Renato Maia 225nov/2004
Contêiner Pilha
n Adaptador de contêiner seqüencial para acesso FIFO
n Cabeçalho
¨ #include <stack>
n Parâmetros
¨ Tipo dos elementos armazenados
¨ Tipo dos contêiner seqüêncial utilizado (default deque<T>)
n Exemplos
¨ stack<int> si;
¨ stack<MyClass, vector<MyClass>> stkobj;
Renato Maia 226nov/2004
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() ; }
};
Renato Maia 227nov/2004
Contêiner Fila
n Adaptador de contêiner seqüencial para acesso LIFO
n Cabeçalho
¨ #include <queue>
n Parâmetros
¨ Tipo dos elementos armazenados
¨ Tipo dos contêiner seqüêncial utilizado (default deque<T>)
n Exemplos
¨ queue<int> qi;
¨ queue<MyClass, vector<MyClass>> queobj;
Renato Maia 228nov/2004
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 229nov/2004
Contêiner Fila de Prioridades
n Adaptador de contêiner seqüêncial para acesso de elementos de 
maior prioridade
n Cabeçalho
¨ #include <queue>
n 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
n Exemplos
¨ priority_queue<int> qi;
¨ qi.push(2);
¨ qi.push(4);
¨ cout << qi.pop();
Renato Maia 230nov/2004
Operações da Fila de Prioridades
template <class T, class C = vector<T>, class Cmp = less<typename C::value_type> >
class priority_queue {
protected:
C c;
Cmp cmp;
public:
typedef typename C::value_type value_type;
typedef typename C::size_type size_type;
typedef C container_type;
explicit priority_queue(const Cmp& a1 =Cmp() , const C& a2 =C())
: c(a2) , cmp(a1) { }
template <class In>
priority_queue(In first, In last, const Cmp& =Cmp() , const C& =C()) ;
bool empty() const { return c.empty() ; }
size_type size() const { return c.size() ; }
const value_type& top() const { return c.front() ; }
void push(const value_type&) ;
void pop() ;
};
Renato Maia 231nov/2004
Utilitário Pares
template <class T1, class T2> struct std::pair {
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() : first(T1()) , second(T2()) { }
pair(const T1& x, const T2& y) : first(x) , second(y) { }
template <class U, class V>
pair(const pair<U,V>& p) : first(p.first) , second(p.second) { }
};
Renato Maia 232nov/2004
Contêiners Mapa e Multimapa
n Conjunto de pares (chave,valor) para acesso baseado na chave
n Cabeçalho
¨ #include <map>
n Parâmetros
¨ Tipo dos elementos da chave
¨ Tipo dos elementos armazenados
¨ Tipo do comparador dos elementos (opcional)
¨ Tipo do gerenciador de memória (opcional)
n Exemplos
¨ map<string,int> m;
¨ ++m["int"];
¨ cout << m["int"];
Renato Maia 233nov/2004
Operações do Cont. (Multi)Mapa
n Construtores
¨ contêiner(op) vazio, usando op como comparação op
¨ contêiner(beg,end,op) Os pares em [beg,end[, usando op como
comparação op
n Acesso
¨ [k] Apenas para o contêiner mapa.
Devolve uma referência para o valor mapeado por k
Se não houver o elemento este é inserido com o valor default
n Mapeamento
¨ count(k) Número de elementos com a chave k
¨ find(k) Devolve a primeira posição com a chave k ou end()
¨ lower_bound(k) Devolve a primeira onde um elemento com
a chave k seria inserido
¨ lower_bound(k) Devolve a última posição onde um elemento
com a chave k seria inserido
¨ equal_range(k) Devolve a primera e a última posição onde um
elemento com a chave k seria inserido
Renato Maia 234nov/2004
Contêiners Conjunto e Multiconjunto
n Conjunto de valores para verificação de pertinência
n Cabeçalho
¨ #include <set>
n Parâmetros
¨ Tipo dos elementos armazenados
¨ Tipo do comparador dos elementos (opcional)
¨ Tipo do gerenciador de memória (opcional)
n Exemplos
¨ set<int> conj;
¨ conj.insert(4);
¨ conj.insert(1);
¨ if (conj.find(2) == conj.end()) /* ... */ ;
Renato Maia 235nov/2004
Operações do Cont.(Multi)Conjunto
n Construtores
¨ contêiner(op) vazio, usando op como comparação op
¨ contêiner(beg,end,op) Os pares em [beg,end[, usando op como
comparação op
n 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
Renato Maia 236nov/2004
Contêiner Conjunto de Bits
n Conjunto de valores para verificação de pertinência
n Cabeçalho
¨ #include <bitset>
n Parâmetros
¨ Número de bits
n Exemplos
¨ enum RGB { red, green, blue, count }
¨ bitset<count> bs;
¨ bs.set(red);
¨ bs.set(green);
Renato Maia 237nov/2004
Operações do Conjunto de Bits
n 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) Ativa os bits correspondentes aos caracteres nas
posições após i da string str que tenham valor '1'
¨ bitset(str,i,j)Ativa os bits correspondentes aos caracteres nas
posições em [i,j[ da string str que tenham valor '1'
n Acesso
¨ size() Devolve o número de bits
¨ count() Devolve o número de bits ativos
¨ any() Informa se algum bit está ativo
¨ none() Informa se nenhum bit está ativo
¨ test(idx) Informa se o bit de indice idx está ativo
Renato Maia 238nov/2004
Operações do Conjunto de Bits
n Operadores (mesmo significado quando 
aplicado a inteiros)
¨ Relacionais
n == !=
¨ Boleanos
n & | ^ << >> ~
¨ Atribuição
n &= |= ^= <<= >>=
n [idx] Acessa o bit de índice idx
Renato Maia 239nov/2004
Operações do Conjunto de Bits
n Manipulação
¨ set() Ativa todos os bits
¨ set(idx) Ativa o bit de indice idx
¨ set(idx, val) Ativa o bit de indice idx de acondo com val
¨ reset() Desativa todos os bits
¨ reset(idx) Desativa o bit de indice idx
¨ reset(idx, val) Desativa o bit

Continue navegando