1 aula 5 instâncias dinâmicas. 2003/2004 programação orientada para objectos 2 instâncias…...
TRANSCRIPT
1
Aula 5
Instâncias dinâmicas
2003/2004 Programação Orientada para
Objectos2
Instâncias…
int j = 20;
int f(){ int const i = 10; // … } Constante automática.
Variável estática.
2003/2004 Programação Orientada para
Objectos3
Instâncias…
Racional operator+(Racional um_racional, Racional const& outro_racional){ um_racional += outro_racional; return um_racional;}
int main(){ Racional r1(1, 3); Racional r2(2, 3);
cout << r1 + r2 << endl;}
Aparece 1 no ecrã.
Valor devolvido é variável temporária!
2003/2004 Programação Orientada para
Objectos4
Instâncias (I)
Características: Tipo
Valor
Variáveis Constantes
Valor alterável Valor fixo
2003/2004 Programação Orientada para
Objectos5
Instâncias (II)
Declaradas Não-declaradas
Características: nome tipo valor
Características: sem nome tipo valor
Automáticas Estáticas Temporárias Dinâmicas
Construídas quando a instrução de definição é atingida e destruídas no final do respectivo bloco.
Construídas no início do programa ou quando a sua instrução de definição é atingida pela primeira vez e destruídas no final do programa.
Construídas durante o cálculo de uma expressão e destruídas no final da expressão completa em que são criadas.
Construídas e destruídas sob o domínio integral do programador.
2003/2004 Programação Orientada para
Objectos6
int* p = new int(10);
int const* p = new int const(10);
Criação de instâncias dinâmicas (I)
p: int*
10
: int
p: int const*
10
: int {frozen}
2003/2004 Programação Orientada para
Objectos7
Aluno
class Aluno { public: Aluno(string const& nome, int número);
string const& nome() const; int número() const;
private: string nome_; int número_;};
Aluno::Aluno(string const& nome, int const número) : nome_(nome), número_(número) {}
string const& Aluno::nome() const{ return nome_;}
int Aluno::número() const{ return número_;}
2003/2004 Programação Orientada para
Objectos8
Aluno* pa = new Aluno(“Zé”, 77);
Aluno const* pac = new Aluno const(“Zé”, 77);
Criação de instâncias dinâmicas (II)
pa: Aluno*
nome_ = “Zé”número_ = 77
: Aluno
pac: Aluno const*
nome_ = “Zé”número_ = 77
: Aluno {frozen}
2003/2004 Programação Orientada para
Objectos9
Utilização e destruição de instâncias dinâmicas
Como escrever o aluno no ecrã?
cout << pa->nome() << ‘ ‘ << pa->número() << endl;
Como destruir uma instância dinâmica?
delete pa;delete pac;
A partir deste momento pa e pac contêm lixo.
2003/2004 Programação Orientada para
Objectos10
Qual a duração da instância dinâmica?
Exemplo de código, conceptualmente incorrecto:
void f(int* p) { cout << *p << endl; delete p; }
int main() { int* pi = new int(10); f(pi); }
Construção
Destruição
2003/2004 Programação Orientada para
Objectos11
Regras
1. Todas as instâncias dinâmicas têm de ser destruídas uma e uma só vez!
2. Quem constrói, destrói
2003/2004 Programação Orientada para
Objectos12
Políticas de gestão de instâncias dinâmicas
Quem constrói destrói ou, posse única da instância dinâmica
Quem possui destrói, ou posse única mas transferível da instância dinâmica
O último fecha a porta, ou posse partilhada da instância dinâmica
2003/2004 Programação Orientada para
Objectos13
Erros mais comuns (I)
Fugas de memória instâncias dinâmicas construídas e nunca
destruídas
for(int i = 0; i != 1000000; ++i) int* p = new int(i);
2003/2004 Programação Orientada para
Objectos14
Fuga de memória
int const* p = new int const(10);p = new int const(20);
24 28 52
10
: int
24
p: int*
2003/2004 Programação Orientada para
Objectos15
Fuga de memória
int const* p = new int const(10);p = new int const(20);
24 28 52
10
: int
20
: int
28
p: int*
Memória ocupadanão acessível.
2003/2004 Programação Orientada para
Objectos16
Erros mais comuns (II)
Outros casos:
double* p = new double(1.1);delete p;delete p;
24 52
1.1
: double
24
p: double*
Erro!
2003/2004 Programação Orientada para
Objectos17
Aluno
class Aluno { public: Aluno(string const& nome, int número); ~Aluno();
string const& nome() const; int número() const;
private: string nome_; int número_;};
Aluno::Aluno(string const& nome, int const número) : nome_(nome), número_(número) {}
Aluno::~Aluno() { cout << “Arghhh!” << endl;}
string const& Aluno::nome() const { return nome_;}
int Aluno::número() const { return número_;}
2003/2004 Programação Orientada para
Objectos18
Destruição
int main(){ Aluno* pa = new Aluno; delete pa;}
Erro: o contrutor de alunotem dois parâmetros.
Deveria ser (por exemplo):Aluno* pa = new Aluno(“Zé”, 1);
Aparece no ecrã: Arghhh!
2003/2004 Programação Orientada para
Objectos19
Matrizes dinâmicas:operadores new[] e delete[]
int* p = new int[10];
for(int i = 0; i != 10; ++i) p[i] = i;
for(int i = 0; i != 10; ++i) cout << p[i] << endl;
delete[] p;
2003/2004 Programação Orientada para
Objectos20
Criação de matriz dinâmica
Como são construídos os elementos da matriz? Construtor por omissão Excepto se forem de tipos básicos
Tipos básicos não são inicializados
2003/2004 Programação Orientada para
Objectos21
E quando não há memória?
Lançamento de excepção Alternativa (a evitar):
#include <new>…int* p = new(nothrow) int(20);if(p == 0) { cerr << “Não havia memória!” << endl; …}
Nenhum objectotem o endereço 0.
2003/2004 Programação Orientada para
Objectos22
PilhaDeInt: interface
/** Representa pilhas de double. @invariant (questão de implementação). */ class PilhaDeInt { public: typedef double Item;
/** Constrói pilha vazia. @pre V. @post estaVazia(). */ PilhaDeInt();
/** Devolve o item que está no topo da pilha. @pre ¬estaVazia(). @post topo idêntico ao item no topo de *this. */ Item const& topo() const;
2003/2004 Programação Orientada para
Objectos23
PilhaDeInt: interface
/** Indica se a pilha está vazia.
@pre V.
@post estaVazia = *this está vazia. */ bool estáVazia() const;
/** Devolve altura da pilha.
@pre V.
@post altura = altura de *this. */ int altura() const;
2003/2004 Programação Orientada para
Objectos24
PilhaDeInt: interface
/** Põe um novo item na pilha (no topo).
@pre V.
@post *this contém um item adicional no topo igual a novo_item. */ void põe(Item const& novo_item);
/** Tira o item que está no topo da pilha.
@pre ¬estaVazia(). @post *this contém os itens originais menos o do topo. */ void tiraItem();
2003/2004 Programação Orientada para
Objectos25
Memória dinâmica em classes (I)
class PilhaDeInt { public: typedef int Item; … private: static int const capacidade_inicial = 32; int capacidade_actual; Item* itens; int número_de_itens;
bool cumpreInvariante() const;};
2003/2004 Programação Orientada para
Objectos26
Memória dinâmica em classes (II)
Construtor:
inline PilhaDeInt::PilhaDeInt() : capacidade_actual(capacidade_inicial), itens(new Item[capacidade_actual]), número_de_itens(0){ assert(cumpreInvariante());}
2003/2004 Programação Orientada para
Objectos27
Memória dinâmica em classes (III)
void PilhaDeInt::põe(Item const& novo_item){ assert(cumpreInvariante());
if(número_de_itens == capacidade_actual) { Item* novos_itens = new Item[capacidade_actual * 2]; for(int i = 0; i != número_de_itens; ++i) novos_itens[i] = itens[i]; capacidade_actual *= 2; delete[] itens; itens = novos_itens; } itens[número_de_itens] = novo_item; ++número_de_itens;
assert(cumpreInvariante());}
2003/2004 Programação Orientada para
Objectos28
Memória dinâmica em classes (IV)
Evitar fuga de memória: é necessário um destrutor
inline PilhaDeInt::~PilhaDeInt(){ assert(cumpreInvariante());
delete[] itens;}
2003/2004 Programação Orientada para
Objectos29
Problemas
PilhaDeInt p;
p.põe(2); p.põe(3); p.põe(4);
PilhaDeInt cópia = p;
cópia.tira();
PilhaDeInt outra;
outra = p;
2003/2004 Programação Orientada para
Objectos30
Aula 5: Sumário
Memória livre e instâncias dinâmicas Criação de instâncias dinâmicas Destruição de instâncias dinâmicas Problemas comuns Matrizes dinâmicas
Introdução à memória dinâmica em classes: Construtores e destrutores Problema da cópia e da atribuição