101
Aula 11 Tipos Abstractos de Dados II

Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

Embed Size (px)

Citation preview

Page 1: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

Aula 11

Tipos Abstractos de Dados II

Page 2: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação2

Estrutura global do programa

#include <iostream>#include <cassert>

using namespace std;

int mdc(int const m, int const n) {…}

class Racional {…};

Racional::Racional(int const n) {…}

Racional::Racional(int const n, int const d) {…}

void Racional::escreve() {…}

Racional Racional::somaCom(Racional const& r2) {…}

void Racional::lê() {…}

void Racional::reduz() {…}

bool Racional::cumpreInvariante() {…}

int main() {…}

Diferente!Porquê?

Page 3: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação3

TAD Racional (I)

/** Representa números racionais. @invariant 0 < denominador mdc(numerador, denominador) = 1. */class Racional { public: /** Constrói racional com valor inteiro. @pre V. @post *this = n. */ Racional(int const n = 0);

/** Constrói racional correspondente a n/d. @pre d ≠ 0. @post *this = n/d. */ Racional(int const n, int const d);

/** Escreve um racional no ecrã no formato de uma fracção. @pre V. @post cout.fail() ou cout contém n/d (ou simplesmente n, se d = 1) em que n e d são os valores de numerador e denominador. */ void escreve();

(continua)

Page 4: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação4

TAD Racional (II)

(continuação)

/** Devolve a soma de dois racionais. @pre V. @post somaDe = *this + r2. */ Racional somaCom(Racional const& r2);

/** Lê do teclado um racional, na forma de dois inteiros sucessivos. @pre *this = r. @post Se cin.good() cin tem dois inteiros n e d disponíveis para leitura, com d <> 0, então *this = n/d cin.fail(), senão *this = r cin.fail(). */ void lê();

(continua)

Diferente!

Page 5: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação5

TAD Racional (III)

(continuação)

private: /** Indica se a CIC se verifica.      @pre V.      @post  cumpreInvariante = 0 < denominador mdc(numerador, denominador) = 1. */ bool cumpreInvariante();

/** Reduz a fracção que representa o racional. @pre denominador ≠ 0 *this = r. @post denominador ≠ 0 mdc(numerador, denominador) = 1 *this = r. */ void reduz();

    int numerador;    int denominador; };

Page 6: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação6

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

Page 7: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação7

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

main()

Page 8: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação8

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

Introduza …

main()

Page 9: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação9

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

Introduza …

main()

r1: Racional

Page 10: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação10

Traçado

Racional::Racional(int const n) : numerador(n), denominador(1){

assert(cumpreInvariante()); }

Introduza …

Racional::Racional()

main()

r1: Racional

n: int {frozen}

0

*this: Racional&

Page 11: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação11

Traçado

Racional::Racional(int const n) : numerador(n), denominador(1){

assert(cumpreInvariante()); }

Introduza …

Racional::Racional()

main()

r1: Racional

n: int {frozen}

0

numerador: int

0

*this: Racional&

Page 12: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação12

Traçado

Racional::Racional(int const n) : numerador(n), denominador(1){

assert(cumpreInvariante()); }

Introduza …

Racional::Racional()

main()

r1: Racional

n: int {frozen}

0

numerador: int

0

denominador: int

1

*this: Racional&

Page 13: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação13

Traçado

Racional::Racional(int const n) : numerador(n), denominador(1){

assert(cumpreInvariante()); }

Introduza …

Racional::Racional()

main()

r1: Racional

n: int {frozen}

0

numerador: int

0

denominador: int

1

*this: Racional&

Page 14: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação14

Traçado

bool Racional::cumpreInvariante() { return 0 < denominador and

mdc(numerador, denominador) == 1;}

Introduza …

Racional::cumpreInvariante()

main()

r1: Racional

numerador: int

0

denominador: int

1

*this: Racional&

Page 15: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação15

Traçado

bool Racional::cumpreInvariante() { return 0 < denominador and

mdc(numerador, denominador) == 1;}

Introduza …

Racional::cumpreInvariante()

main()

r1: Racional

numerador: int

0

denominador: int

1

*this: Racional&

Devolve verdadeiro.

Page 16: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação16

Traçado

Racional::Racional(int const n) : numerador(n), denominador(1){

assert(cumpreInvariante()); }

Introduza …

Racional::Racional()

main()

r1: Racional

n: int

0

numerador: int

0

denominador: int

1

*this: Racional&

Page 17: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação17

Traçado

Racional::Racional(int const n) : numerador(n), denominador(1){

assert(cumpreInvariante()); }

Introduza …

Racional::Racional()

main()

r1: Racional

n: int

0

numerador: int

0

denominador: int

1

*this: Racional&

Page 18: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação18

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

Introduza …

main()

r1: Racional

numerador: int

0

denominador: int

1

r2: Racional

numerador: int

0

denominador: int

1

Page 19: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação19

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

Introduza …

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Page 20: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação20

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Page 21: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação21

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Page 22: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação22

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Racional::lê()

Sem asserções, para encurtar.

*this: Racional&

Page 23: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação23

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

?

d: int

?

*this: Racional&

Page 24: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação24

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

?

d: int

?

n: int

6

d: int

9

*this: Racional&

Page 25: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação25

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

6

d: int

9

*this: Racional&

Page 26: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação26

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

6

d: int

9

*this: Racional&

Page 27: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação27

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

6

d: int

9

*this: Racional&

Page 28: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação28

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

6

d: int

9

*this: Racional&

Page 29: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação29

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

6

d: int

9

*this: Racional&

Page 30: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação30

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

6

d: int

9

*this: Racional&

r1: Racional

numerador = 6denominador = 1

Page 31: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação31

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

6

d: int

9

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 6denominador = 9

Page 32: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação32

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

6

d: int

9

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 6denominador = 9

Page 33: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação33

Traçado

void Racional::reduz() { assert(denominador != 0);

int const divisor = mdc(numerador, denominador); numerador /= divisor; denominador /= divisor;

assert(denominador != 0); assert(mdc(numerador,

denominador) == 1);}

Introduza …6 9 7 3

main()

r2: Racional

numerador = 0denominador = 1

Racional::reduz()

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 6denominador = 9

Page 34: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação34

Traçado

void Racional::reduz() { assert(denominador != 0);

int const divisor = mdc(numerador, denominador); numerador /= divisor; denominador /= divisor;

assert(denominador != 0); assert(mdc(numerador,

denominador) == 1);}

Introduza …6 9 7 3

main()

r2: Racional

numerador = 0denominador = 1

Racional::reduz()

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 6denominador = 9

divisor: int {frozen}

3

Ignoram-se asserções, para encurtar.

Page 35: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação35

Traçado

void Racional::reduz() { assert(denominador != 0);

int const divisor = mdc(numerador, denominador); numerador /= divisor; denominador /= divisor;

assert(denominador != 0); assert(mdc(numerador,

denominador) == 1);}

Introduza …6 9 7 3

main()

r2: Racional

numerador = 0denominador = 1

Racional::reduz()

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 6denominador = 9

divisor: int {frozen}

3

r1: Racional

numerador = 2denominador = 9

Page 36: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação36

Traçado

void Racional::reduz() { assert(denominador != 0);

int const divisor = mdc(numerador, denominador); numerador /= divisor; denominador /= divisor;

assert(denominador != 0); assert(mdc(numerador,

denominador) == 1);}

Introduza …6 9 7 3

main()

r2: Racional

numerador = 0denominador = 1

Racional::reduz()

*this: Racional&

r1: Racional

numerador = 2denominador = 9

divisor: int {frozen}

3

r1: Racional

numerador = 2denominador = 3

Page 37: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação37

Traçado

void Racional::reduz() { assert(denominador != 0);

int const divisor = mdc(numerador, denominador); numerador /= divisor; denominador /= divisor;

assert(denominador != 0); assert(mdc(numerador,

denominador) == 1);}

Introduza …6 9 7 3

main()

r2: Racional

numerador = 0denominador = 1

Racional::reduz()

*this: Racional&

divisor: int {frozen}

3

r1: Racional

numerador = 2denominador = 3

Page 38: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação38

Traçado

void Racional::lê() { int n, d;

cin >> n >> d; if(not cin.fail()) if(d == 0) cin.setstate(ios_base::failbit); else { if(d < 0) { numerador = -n; denominador = -d; } else { numerador = n; denominador = d; } reduz(); } }

Introduza …6 9 7 3

main()

r2: Racional

numerador = 0denominador = 1

Racional::lê()

n: int

6

d: int

9

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 2denominador = 3

Page 39: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação39

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

Introduza …6 9 7 3

main()

r1: Racional

numerador = 2denominador = 3

r2: Racional

numerador = 0denominador = 1

r2: Racional

numerador = 7denominador = 3

Page 40: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação40

Traçado

int main() { // Ler fracções: cout << "Introduza duas fracções (numer… Racional r1, r2; r1.lê(); r2.lê();

if(cin.fail()) { cout << "Opps! A leitura dos racion… return 1; }

(continua)

Introduza …6 9 7 3

main()

r1: Racional

numerador = 2denominador = 3

r2: Racional

numerador = 7denominador = 3

Page 41: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação41

Traçado

(continuação)

// Calcular racional soma: Racional r = r1.somaCom(r2);

// Escrever resultado: cout << "A soma de "; r1.escreve(); cout << " com "; r2.escreve(); cout << " é "; r.escreve(); cout << '.' << endl; }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 2denominador = 3

r2: Racional

numerador = 7denominador = 3

Medonho…

Page 42: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação42

Traçado

Racional Racional::somaCom(Racional const& r2) { assert(cumpreInvariante()); assert(r2.cumpreInvariante());

Racional r; r.numerador = numerador * r2.denominador + r2.numerador * denominador; r.denominador = denominador * r2.denominador;

r.reduz();

assert(cumpreInvariante()); assert(r.cumpreInvariante());

return r; }

Introduza …6 9 7 3

main()

r2: Racional

numerador = 7denominador = 3

Racional::somaCom()

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 2denominador = 3

r2: Racional const&

Page 43: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação43

Traçado

Racional Racional::somaCom(Racional const& r2) { assert(cumpreInvariante()); assert(r2.cumpreInvariante());

Racional r; r.numerador = numerador * r2.denominador + r2.numerador * denominador; r.denominador = denominador * r2.denominador;

r.reduz();

assert(cumpreInvariante()); assert(r.cumpreInvariante());

return r; }

Introduza …6 9 7 3

main()

r2: Racional

numerador = 7denominador = 3

Racional::somaCom()

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 2denominador = 3

r2: Racional const&

r: Racional

numerador = 0denominador = 1

Page 44: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação44

Traçado

Racional Racional::somaCom(Racional const& r2) { assert(cumpreInvariante()); assert(r2.cumpreInvariante());

Racional r; r.numerador = numerador * r2.denominador + r2.numerador * denominador; r.denominador = denominador * r2.denominador;

r.reduz();

assert(cumpreInvariante()); assert(r.cumpreInvariante());

return r; }

Introduza …6 9 7 3

main()

r2: Racional

numerador = 7denominador = 3

Racional::somaCom()

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 2denominador = 3

r2: Racional const&

r: Racional

numerador = 0denominador = 1

r: Racional

numerador = 27denominador = 1

Page 45: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação45

Traçado

Racional Racional::somaCom(Racional const& r2) { assert(cumpreInvariante()); assert(r2.cumpreInvariante());

Racional r; r.numerador = numerador * r2.denominador + r2.numerador * denominador; r.denominador = denominador * r2.denominador;

r.reduz();

assert(cumpreInvariante()); assert(r.cumpreInvariante());

return r; }

Introduza …6 9 7 3

main()

r2: Racional

numerador = 7denominador = 3

Racional::somaCom()

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 2denominador = 3

r2: Racional const&

r: Racional

numerador = 27denominador = 1

r: Racional

numerador = 27denominador = 9

Page 46: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação46

Traçado

Racional Racional::somaCom(Racional const& r2) { assert(cumpreInvariante()); assert(r2.cumpreInvariante());

Racional r; r.numerador = numerador * r2.denominador + r2.numerador * denominador; r.denominador = denominador * r2.denominador;

r.reduz();

assert(cumpreInvariante()); assert(r.cumpreInvariante());

return r; }

Introduza …6 9 7 3

main()

r2: Racional

numerador = 7denominador = 3

Racional::somaCom()

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 2denominador = 3

r2: Racional const&

r: Racional

numerador = 27denominador = 9

Qual será a instância implícita?

r: Racional

numerador = 3denominador = 1

Page 47: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação47

Traçado

Racional Racional::somaCom(Racional const& r2) { assert(cumpreInvariante()); assert(r2.cumpreInvariante());

Racional r; r.numerador = numerador * r2.denominador + r2.numerador * denominador; r.denominador = denominador * r2.denominador;

r.reduz();

assert(cumpreInvariante()); assert(r.cumpreInvariante());

return r; }

Introduza …6 9 7 3

main()

r2: Racional

numerador = 7denominador = 3

Racional::somaCom()

*this: Racional&

r1: Racional

numerador = 6denominador = 1

r1: Racional

numerador = 2denominador = 3

r2: Racional const&

r: Racional

numerador = 3denominador = 1

Page 48: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação48

Traçado

(continuação)

// Calcular racional soma: Racional r = r1.somaCom(r2);

// Escrever resultado: cout << "A soma de "; r1.escreve(); cout << " com "; r2.escreve(); cout << " é "; r.escreve(); cout << '.' << endl; }

Introduza …6 9 7 3

main()

r1: Racional

numerador = 2denominador = 3

r2: Racional

numerador = 7denominador = 3

r: Racional

numerador = 3denominador = 1

É igual ao racional devolvido por Racional::somaCom(), mas não é a mesma instância!

Page 49: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação49

Traçado

Etc…..

Page 50: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação50

O nosso objectivo

#include <iostream>

using namespace std;

int main() { cout << "Introduza duas fracções (numerador denominador): "; Racional r1, r2; cin >> r1 >> r2; if(cin.fail()) { cout << "Opps! A leitura dos racionais falhou!" << endl; return 1; } Racional r = r1 + r2; cout << "A soma de " << r1 << " com " << r2 << " é " << r << '.' << endl; }

Hoje ficaremos mais próximos…

Page 51: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação51

Sobrecarga de operadores

Sobrecarga de rotinas possível: int soma() int soma(int const a) int soma(int const a, int const b)

Sobrecarga de operadores também!

Page 52: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação52

Operação Racional::operator+()/** … */class Racional { public: …

/** Devolve a soma de dois racionais. @pre V. @post somaDe = *this + r2. */ Racional operator+(Racional const& r2);

private: …

};

Page 53: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação53

Método Racional::operator+()Racional Racional::operator+(Racional const& r2) { assert(cumpreInvariante()); assert(r2.cumpreInvariante());

Racional r; r.numerador = numerador * r2.denominador + r2.numerador * denominador; r.denominador = denominador * r2.denominador;

r.reduz();

assert(cumpreInvariante()); assert(r.cumpreInvariante());

return r; }

Page 54: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação54

Função main()

int main(){ …

// Calcular racional soma:

Racional r = r1.operator+(r2);

… }

Page 55: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação55

Função main()

int main(){ …

// Calcular racional soma:

Racional r = r1 + r2;

… }

Page 56: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação56

Sobrecarga de operadores

Como membro de classe: Primeiro operando é instância implícita! Outros operandos são passados como argumentos

Racional Racional::operator+(Racional const& r2)

Como rotina “livre”: Todos os operandos passados como argumentos

Racional operator+(Racional const& r1, Racional const& r2)

Page 57: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação57

Operadores a sobrecarregar

Aritméticos: Binários: *, /, + e - Unários: + e -

Relacionais: <, <=, > e >=

Igualdade e diferença: == e !=

Incrementação: Prefixo: ++ e -- Sufixo: ++ e --

Especiais de atribuição: *=, /=, += e -=

Vamos começar por aqui.

Page 58: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação58

Um problema

Que devolve o operador ++ prefixo?

Exemplo:

int i = 0;++(++i);cout << i << endl;

2

Tem de resultar no próprio i, e não numa cópia.

É um exemplo do que é possível fazer, e não uma sugestão de que é recomendável!

Page 59: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação59

Um caso bicudo

int main(){ int i = 0; ++(++i); cout << i << endl;}

Page 60: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação60

E um regresso às origens

void incrementa(int& v){ v = v + 1;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

Invocação impossível!incrementa() não devolve nada.

Page 61: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação61

Correcção…

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

Page 62: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação62

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

Page 63: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação63

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

Page 64: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação64

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

0

Page 65: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação65

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

0

Page 66: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação66

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

0

incrementa()

v: int&

Page 67: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação67

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

0

incrementa()

v: int&

i: int

1

Page 68: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação68

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

incrementa()

v: int&

i: int

1

: int

1

Valor devolvido é cópia de v, i.e., é cópia de i. É instância temporária!

Page 69: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação69

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

: int

1

Page 70: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação70

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

: int

1

incrementa()

v: int&

Page 71: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação71

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

: int

1

incrementa()

v: int&

: int

2

Page 72: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação72

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

incrementa()

v: int&

: int

2

: int

2

Valor devolvido é cópia de v, i.e., é cópia da cópia alterada de i.

Page 73: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação73

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

: int

2

: int

2

Page 74: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação74

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

1

Page 75: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação75

Funcionará?

int incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

1

Page 76: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação76

Moral da história

Segunda incrementação falhou

Ou melhor, incrementou cópia

Porque devolução faz-se por valor

Necessário devolver por referência

Page 77: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação77

Em abono da verdade…

… o código nem sequer compila!

C++ proíbe referência (não constante) para instância temporária!

Page 78: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação78

Outra correcção…

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

Page 79: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação79

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

Page 80: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação80

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

Page 81: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação81

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

0

Page 82: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação82

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

0

Page 83: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação83

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

0

incrementa()

v: int&

Page 84: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação84

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

0

incrementa()

v: int&

i: int

1

Page 85: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação85

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

incrementa()

v: int&

i: int

1

: int&

Page 86: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação86

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

: int&

Page 87: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação87

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

incrementa()

v: int&

: int&

Page 88: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação88

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

1

incrementa()

v: int&

: int&

i: int

2

Page 89: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação89

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

2

incrementa()

v: int&

: int&

: int&

Page 90: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação90

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

2

: int&

: int&

Page 91: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação91

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

2

2

Page 92: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação92

E agora?

int& incrementa(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; incrementa(incrementa(i)); cout << i << endl;}

main()

i: int

2

2

Page 93: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação93

Finalmente… sobrecarga!

int& operator++(int& v){ v = v + 1;

return v;}

int main(){ int i = 0; ++(++i); cout << i << endl;}

Era doce… Não se pode redefinir os operadores dos tipos básicos!

Mas para um TAD pode-se sobrecarregar!

Page 94: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação94

Operação Racional::operator++()/** … */class Racional { public: …

/** Incrementa o racional.

@pre *this = r.

@post operator++ = ? *this = r + 1. */ Racional& operator++();

private: …

};

Page 95: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação95

Método Racional::operator++()Racional& Racional::operator++() { assert(cumpreInvariante());

numerador += denominador;

assert(cumpreInvariante());

return ?; }

Porque não é necessário reduzir a fracção?

Os TAD devem ter comportamente semelhante aos tipos básicos.Por isso, devia-se devolver o racional incrementado. Como?

Page 96: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação96

Método Racional::operator++()Racional& Racional::operator++() { assert(cumpreInvariante());

numerador += denominador;

assert(cumpreInvariante());

return *this; }

Page 97: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação97

Operação Racional::operator++()/** … */class Racional { public: …

/** Incrementa o racional.

@pre *this = r.

@post operator++ ≡ *this *this = r + 1. */ Racional& operator++();

private: …

};

O que se devolve é a instância implícita ela própria, e não uma instância temporária com igual valor.

Page 98: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação98

Igualdade vs. identidade

Duas instâncias

São idênticas se forem a mesma instância São iguais se tiverem o mesmo valor Se são idênticas, são também iguais. Podem ser iguais, mas não ser idênticas

Page 99: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação99

Igualdade vs. identidade

int cópia(int const& v){ return v;}

int& mesmo(int& v){ return v;}

int main(){ int i = 0;

mesmo(i) = 10;

cópia(i) = 20;}

Ok.

Erro!

Page 100: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação100

lvalue

Lvalue é uma entidade à qual se pode atribuir um valor

Instâncias temporárias não são lvalues, são rvalues

Page 101: Aula 11 Tipos Abstractos de Dados II. 2003/2004 Introdução à Programação 2 Estrutura global do programa #include using namespace std; int mdc(int const

2003/2004Introdução à Programação101

Aula 11: Sumário

Revisões sobre a aula anterior *this como referência Construção dos atributos: lista de

inicializadores Devolução por valor e por referência Noções de identidade e igualdade Diferença entre lvalue e rvalue Introdução à sobrecarga de operadores para

TAD: operadores + binário e ++ prefixo