1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias…...

Preview:

Citation preview

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