30
1 Aula 5 Instâncias dinâmicas

1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

Embed Size (px)

Citation preview

Page 1: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

1

Aula 5

Instâncias dinâmicas

Page 2: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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.

Page 3: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automá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!

Page 4: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

2003/2004 Programação Orientada para

Objectos4

Instâncias (I)

Características: Tipo

Valor

Variáveis Constantes

Valor alterável Valor fixo

Page 5: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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.

Page 6: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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}

Page 7: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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_;}

Page 8: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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}

Page 9: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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.

Page 10: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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

Page 11: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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

Page 12: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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

Page 13: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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);

Page 14: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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*

Page 15: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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.

Page 16: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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!

Page 17: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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_;}

Page 18: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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!

Page 19: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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;

Page 20: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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

Page 21: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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.

Page 22: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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;

Page 23: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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;

Page 24: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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();

Page 25: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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;};

Page 26: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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());}

Page 27: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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());}

Page 28: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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;}

Page 29: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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;

Page 30: 1 Aula 5 Instâncias dinâmicas. 2003/2004 Programação Orientada para Objectos 2 Instâncias… int j = 20; int f() { int const i = 10; // … } Constante automática

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