OO Engenharia Eletrnica Orientao a Objetos Programao em
OO – Engenharia Eletrônica Orientação a Objetos - Programação em C++ 3 o Slides: Relações entre objetos em C++ e UML Prof. Jean Marcelo SIMÃO – DAELN / UTFPR 1
Engenharia de Software Visão Clássica Levantamento de Requisitos Análise e Projeto Implementação ou Codificação Testes 2
Engenharia de Software OO Exemplos de Técnicas . . . Levantamento de Requisitos em Texto/Tabelas, ---------podendo relacioná-los Diagramas de Casos de Uso da UML Modelagem ( Análise & Projeto ) Diagramas UML de: - CLASSES - Objetos/Sequência - Colaboração - Estados / - Atividades - Componentes / - etc Implementação ou Codificação Código em Linguagem de Programação Orientada a Objetos, por exemplo C++, Java ou C# Diagramas da UNIFIED MODELING LANGUAGE (UML). Testes . . . Testes utilizando o software gerado, utilizando registro em arquivos, usando debugger. Linguagem e ambiente de Programação OO. Obs. : Além da UML, há também a Sys. ML (System Modeling Language). . . 3
Engenharia de Software OO Exemplos de Ferramentas Implementação ou Codificação Levantamento de Requisitos Análise e Projeto TEXTO / TABELAS -----------Diagramas de Casos de Uso da UML Diagramas UML de: - CLASSES - Objetos - Sequência -Colaboração -Estados -Atividades. . . Ferramentas CASE: Star. UML (versão 5. 0. 2. 1517), Astah, Jude, Visual. Paradigm, Rational Rose, System Architect, Together, Rhapsody. . . Código em Linguagem de Programação OO, por exemplo C++, Java ou C# Testes utilizando o software gerado, utilizando registro em arquivos, usando debugger. Ambiente de Programação OO (integráveis as Ferramentas CASE): Microsoft Visual Studio (C++), Microsoft Visual C++. net Express Edition, Microsoft Visual C++. net, Microsoft Visual C++, Borland Builder C++, Borland C++, Code. Blocks C++, Dev C++, G++. . . 4
Bibliografias: - Pressman, R. S. Software Engineering – A Practitioner’s Approach. 6 th Edition Mc. Graw Hill (Higher Education). 2005. ISBN 0 -07 -285318 -2. - RUMBAUGH, J. ; JACOBSON, I. ; BOOCH, G. The Unified Modeling Language Reference Manual. 2 nd Edition. Addison-Wesley. 2005. ISBN 0 -321 -26797 -4. - Bezerra, E. Princípios de Análise e Projeto de Sistemas com UML. Editora Campus. 2003. ISBN 85 -352 -1032 -6. - RUMBAUGH, J. ; JACOBSON, I. ; BOOCH, G. The Unified Software Development Process. 1 st Edition. Addison-Wesley. 2005. ISBN 0 -201 -57169 -2. Outras bibliografias: - GAMMA, E. ; HELM, R. ; Johnson, R. ; Vlissides, J. Design Patterns: Elements of Reusable Object-oriented Software. Addison Wesley Longman, 1995. - Largman, G. Applying UML and Patterns – An Introduction to Object-Oriented Analysis and Design. Prentice Hall. 1998. ISBN 0 -13 -748880 -7. 5
Primeiramente: Qual será ou tem sido nosso exemplo para estudos? Um sistema acadêmico! 6
Definindo Requisitos Funcionais (e Gerais) do Sistema Acadêmico • Registrar no sistema um conjunto de Universidades. • Registrar no sistema um conjunto de Departamentos relacionados a Universidades. • Registrar no sistema um conjunto relacionados a Departamento. de Disciplinas • Registrar um conjunto de Professores relacionados a entidades pertinentes como Departamento e Disciplinas. • Registrar um conjunto de Alunos relacionados a entidades pertinentes como Departamento e Disciplinas. • . . . Obs. : Estes são requisitos funcionais (e gerais) que serão expandidos e refinados (inclusive em termos técnicos) nos enunciados de exercícios. Isto porque estamos no âmbito de uma disciplina aprendendo conceitos progressivamente. Em um sistema real, os requisitos deveriam ser definidos e estabelecidos o quanto antes (dentro do ciclo de engenharia de software). 7
Requisitos Funcionais x Técnicos • Simplificadamente, requisitos podem ser classificados em Requisitos Funcionais e Requisitos Técnicos. • Os Requisitos Funcionais são os que definem quais funcionalidade terão o sistemas (sem definir como estas se darão tecnicamente). • Os Requisitos Técnicos são os que definem como as funcionalidades se darão tecnicamente, salientando meios ou formas. • Certamente, baseando-se nos requisitos funcionais (sejam gerais ou específicos), pode-se derivar requisitos técnicos. 8
Retomando a última aula, na qual havia os seguintes requisitos técnicos: • Criar uma classe chamada Universidade que terá como atributo um nome. • Relacionar a classe Pessoa para com a classe Universidade. Cada objeto de Pessoa poderá ser associado a um objeto de Universidade. – A classe Pessoa terá um ponteiro para um objeto ou “variável” da classe Universidade. • A classe Pessoa, por sua vez, terá uma função-membro (i. e. um método) que permitirá a cada objeto (de Pessoa) informar seu nome e em que universidade trabalha. . . 9
Classe Universidade em C++ Universidade. h Universidade. cpp #ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Universidade. h" #include <stdio. h> class Universidade { private: char nome[30]; Universidade: : Universidade ( ) { strcpy ( nome, “” ); } public: // Construtor Universidade ( ); // Destrutor ~Universidade ( ); void set. Nome ( char* n ); char* get. Nome ( ); }; #endif Obs. : O construtor inicializa elementos, como atributos. O destrutor “zera” alguns elementos. . . Universidade: : ~Universidade ( ) { } void Universidade: : set. Nome ( char* n ) { strcpy ( nome, n ); } char* Universidade: : get. Nome ( ) { return nome; } 10
Classe Universidade em UML Antes de implementar uma classe, pode-se modelar (planejar/projetar) esta classe em UML (Unified Modeling Language – Linguagem de Modelagem Unificada). Isto contribui para respeitar o ciclo de Engenharia de Software: Análise de Requisitos, Análise/Projeto, Implementação e Teste. 11
Classe Pessoa em C++ - associada à Universidade #ifndef _PESSOA_H_ #define _PESSOA_H_ #include “Universidade. h”. . . class Pessoa { private: int dia. P; int mes. P; int ano. P; int idade. P; char nome. P[30]; // p. Univ. Filiado é apenas uma referência a um objeto associado. Universidade* p. Univ. Filiado; public: Pessoa ( int dia. Na, int mes. Na, int ano. Na, char* nome = "" ); Pessoa ( ) ; ~Pessoa ( ) ; void Inicializa ( int dia. Na, int mes. Na, int ano. Na, char* nome = "" ); void Calc_Idade ( int dia. AT, int mes. AT, int ano. AT ); int informa. Idade ( ); void set. Nome ( char* n ); char* get. Nome ( ); // Este método abaixo permite associar // uma Univ. à Pessoa. void set. Univ. Filiado ( Universidade* pu ); void Onde. Trabalho ( ); }; #endif #include "Pessoa. h". . . void Pessoa: : set. Univ. Filiado ( Universidade* pu ) { p. Univ. Filiado = pu; } void Pessoa: : Onde. Trabalho ( ) { // Um método da referência p. Univ. Filiado é chamado. cout << nome. P <<" trabalha para a " << p. Univ. Filiado->get. Nome() << endl; } 12
Classe Pessoa em UML Por exemplo, pode-se utilizar a ferramenta Star. UML para planejar/projetar classes 13
Associação entre Objetos #ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa. h" #include "Universidade. h“ #include "Principal. h" Principal: : Principal() { Simao. Inicializa ( 3, 10, 1976, "Jean Simão"); Einstein. Inicializa ( 14, 3, 1879, "Albert Einstein"); Newton. Inicializa ( 4, 1, 1643, "Isaac Newton"); class Principal { private: Pessoa Simao; Pessoa Einstein; Pessoa Newton; UTFPR. set. Nome ("UTFPR"); // Aqui os objetos UTFPR e Simao são associados. // Na verdade, UTFPR é associado ao Simão via uma // passagem por referência do ‘endereço’ dela. Simao. set. Univ. Filiado(&UTFPR); // UTFPR é agregada ao(s) objeto(s) desta classe!!! Universidade UTFPR; int dia. Atual; int mes. Atual; int ano. Atual; public: Executar(); } void Principal: : Executar() {. . . Simao. Calc_Idade ( dia. Atual, mes. Atual, ano. Atua); Einstein. Calc_Idade (dia. Atual, mes. Atual, ano. Atual); Newton. Calc_Idade (dia. Atual, mes. Atual, ano. Atual); Principal(); void Executar(); }; #endif Simao. Onde. Trabalho(); } 14
Associação entre Objetos em C++ #include "Principal. h" Principal: : Principal() { Simao. Inicializa ( 3, 10, 1976, "Jean Simão"); Einstein. Inicializa ( 14, 3, 1879, "Albert Einstein"); Newton. Inicializa ( 4, 1, 1643, "Isaac Newton"); UTFPR. set. Nome ("UTFPR"); Simao. set. Univ. Filiado ( &UTFPR ); } Objeto da Classe Pessoa SIMAO nome. P – “Jean Simão” dia. P – 3 mes. P – 10 ano. P – 1976 idade. P - ? Objeto da Classe Universidade UTFPR Nome – “UTFPR” p. UNIVFILIADO - ENDEREÇO 15
Diagrama de Classes que modela (analisa) o relacionamento de associação entre objetos de Pessoa e de Universidade (por meio de suas classes). Pessoa Universidade -dia. P: int -mes. P: int -ano. P: int -idade. P: int -nome. P: char[30] -id: int <<create>>+Pessoa(dia. Na: int, mes. Na: int, ano. Na: int, nome: char*) <<create>>+Pessoa() <<destroy>>+Pessoa() +Inicializa(dia. Na: int, mes. Na: int, ano. Na: int, nome: char): void +Calc_Idade(dia. AT: int, mes. AT: int, ano. AT: int): void +informa. Idade(): int +set. Nome(n: char*): void +get. Nome(): char* +set. Id(i: int): void +get. Id(): int -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +set. Nome(char* n): void +get. Nome(): char* 0. . 1 Conhecer Isto é um Diagrama de Classes da UML Obs. : Tendo em vista que o Diagrama oculta detalhes de implementação, ficando mais próximo do sistema real analisado, ele pode ser considerado como um Diagrama de Classes de Análise. 16
Diagrama de Classes que modela (analisa) o relacionamento de associação entre objetos de Pessoa e de Universidade (por meio de suas classes). Pessoa Universidade -dia. P: int -mes. P: int -ano. P: int -idade. P: int -nome. P: char[30] -id: int <<create>>+Pessoa(dia. Na: int, mes. Na: int, ano. Na: int, nome: char*) <<create>>+Pessoa() <<destroy>>+Pessoa() +Inicializa(dia. Na: int, mes. Na: int, ano. Na: int, nome: char): void +Calc_Idade(dia. AT: int, mes. AT: int, ano. AT: int): void +informa. Idade(): int +set. Nome(n: char*): void +get. Nome(): char* +set. Id(i: int): void +get. Id(): int -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +set. Nome(char* n): void +get. Nome(): char* 0. . 1 Conhecer Isto é um Diagrama de Classes da UML Obs. : Tendo em vista que o Diagrama oculta detalhes de implementação, ficando mais próximo do sistema real analisado, ele pode ser considerado como um Diagrama de Classes de Análise. 17
Diagrama de Classes que modela (projeta) o relacionamento de associação entre objetos de Pessoa e de Universidade (por meio de suas classes). Pessoa Universidade -dia. P: int -mes. P: int -ano. P: int -idade. P: int -nome. P: char[30] -id: int +p. Univ. Filiado: Universidade* <<create>>+Pessoa(dia. Na: int, mes. Na: int, ano. Na: int, nome: char*) Conhecer 0. . * <<create>>+Pessoa() <<destroy>>+Pessoa() +Inicializa(dia. Na: int, mes. Na: int, ano. Na: int, nome char*) +Calc_Idade(dia. AT: int, mes. AT: int, ani. AT: int): void +informa. Idade(): int +set. Nome(n: char*): void +get. Nome(): char* +set. Id(i: int): void +get. Id(): int +set. Univ. Filiado(pu: Universidade*): void Implementação +Onde. Trabalho(): void via Ponteiro -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +set. Nome(char* n): void +get. Nome(): char* 0. . 1 Obs. : Tendo em vista que o Diagrama traz alguns detalhes de implementação, ele pode ser considerado como um Diagrama de Classes de Projeto. 18
Exercício 1 • Criar dois objetos de Universidade associando um para Einstein e outro para Newton. – Einstein trabalhou como professor de física em Princeton (Nova Jersey - Estados Unidos da América). – Newton trabalhou como professor de matemática em Cambridge (Inglaterra). 19
Solução - Agregação #ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa. h" #include "Universidade. h“ #include "Principal. h" Principal: : Principal( ) { Simao. Inicializa ( 3, 10, 1976, "Jean Simão" ); Einstein. Inicializa ( 14, 3, 1879, "Albert Einstein" ); Newton. Inicializa ( 4, 1, 1643, "Isaac Newton" ); class Principal { private: Pessoa Simao; Pessoa Einstein; Pessoa Newton; // UTFPR é agregada ao(s) objeto(s) desta classe!!! Universidade UTFPR; Universidade Princeton; Universidade Cambridge; int dia. Atual; int mes. Atual; int ano. Atual; public: UTFPR. set. Nome ( "UTFPR" ); Princeton. set. Nome ( "Princeton" ); Cambridge. set. Nome( "Cambridge" ); // Aqui os objetos Universidade e Pessoa são associados. Simao. set. Univ. Filiado ( &UTFPR ); Einstein. set. Univ. Filiado ( &Princeton ); Newton. set. Univ. Filiado ( &Cambridge ); . . . } Principal: : ~Principal( ) { } void Principal: : Executar() { Simao. Calc_Idade ( dia. Atual, mes. Atual, ano. Atua ); Einstein. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Newton. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Principal(); ~Principal(); void Executar(); Simao. Onde. Trabalho ( ); Einstein. Onde. Trabalho ( ); Newton. Onde. Trabalho ( ); }; #endif } 20
Agregação-forte Classe Principal Objeto. Principal Classe Pessoa Simao Classe Pessoa Einstein Classe Pessoa Newton Classe Universidade UTFPR Classe Universidade Princeton Classe Universidade Cambridge O objeto da classe Principal agrega-fortemente (efetivamente) os objeto Simao, Einstein e Newton. Uma agregação-forte, comumente chamada de COMPOSIÇÃO, é caracterizada pelo fato do objeto agregado só poder ser agregado (efetivamente) por um agregador. 21
Agregação-forte em UML A agregação-forte também é chamada de “composição”. 22
Agregação-forte em UML - O “ 0. . *” é a cardinalidade da agregação-forte (ou composição). - Um objeto de Principal se compõe de zero ou mais objeto de Pessoa. - Um objeto de Principal se compõe de zero ou mais objeto de Universidade 23
Exercício 2 • Criar uma classe Departamento (em UML e depois em C++) que permita agregar um objeto (de Departamento) na classe Universidade. • A classe Pessoa deve possuir uma referência ao departamento que trabalha, ou seja: – Ela deve possuir uma associação com a Classe Departamento, permitindo que cada objeto Pessoa tenha a referência de um objeto Departamento. 24
Exercício 2 • Criar uma classe Departamento (em UML e depois em C++) que permita agregar um objeto (de Departamento) na classe Universidade. • A classe Pessoa deve possuir uma referência ao departamento que trabalha, ou seja: – Ela deve possuir uma associação com a Classe Departamento, permitindo que cada objeto Pessoa tenha a referência de um objeto Departamento. 25
Modelo em UML - Análise Universidade -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +set. Nome(char* n): void +get. Nome(): char* Conhecer 0. . 1 É uma agregação-forte (composição) nesta análise porque assim o é no sistema real analisado. 0. . * 1 Pessoa Departamento -id: int -nome: char[100] <<create>>+Departamento(i: int) <<destroy>>+Departamento() +get. Id(): int +set. Nome(n: char*): void +get. Nome(): char* 0. . 1 -dia. P: int -mes. P: int -ano. P: int Conhecer -idade. P: int 0. . * -nome. P: char[30] -id: int <<create>>+Pessoa(dia. Na: int, mes. Na: int, ano. Na: int, nome: char*) <<create>>+Pessoa() <<destroy>>+Pessoa() +Inicializa(dia. Na: int, mes. Na: int, ano. Na: int, nome: char): void +Calc_Idade(dia. AT: int, mes. AT: int, ano. AT: int): void +informa. Idade(): int +set. Nome(n: char*): void +get. Nome(): char* +set. Id(i: int): void +get. Id(): int 26
Modelo em UML - Projeto Universidade -nome: char[30] -dpto: Departamento 0. . 1 Conhecer <<create>>+Universidade() <<destroy>>+Universidade() +set. Nome(char* n): void +get. Nome(): char* +set. Nome. Dep(nomedep: char*): void 0. . * Pessoa -dia. P: int -mes. P: int -ano. P: int -idade. P: int -nome. P: char[30] -id: int +p. Univ. Filiado: Universidade* +p. Dpto. Filiado: Departamento* Em termos de projeto, é uma composição (ou agregação-forte) porque será implementada assim. 1 Departamento -id: int -nome: char[100] <<create>>+Departamento(i: int) <<destroy>>+Departamento() +get. Id(): int +set. Nome(n: char*): void +get. Nome(): char* 0. . 1 Conhecer 0. . * <<create>>+Pessoa(dia. Na: int, mes. Na: int, ano. Na: int, nome: char*) <<create>>+Pessoa() <<destroy>>+Pessoa() +Inicializa(dia. Na: int, mes. Na: int, ano. Na: int, nome char*) +Calc_Idade(dia. AT: int, mes. AT: int, ani. AT: int): void +informa. Idade(): int +set. Nome(n: char*): void +get. Nome(): char* +set. Id(i: int): void +get. Id(): int +set. Univ. Filiado(pu: Universidade*): void +set. Departamento(pdpto: Departamento*): void +Onde. Trabalho(): void +Qual. Departamento. Trabalho(): void 27
Modelo em UML – Projeto - Classe Universidade V 0 Universidade - Solução por agregaçãoforte ou composição. - A composição é caracterizada pelo fato do agregado só poder pertencer efetivamente a um agregador. -nome: char[30] -dpto: Departamento <<create>>+Universidade() <<destroy>>+Universidade() +set. Nome(char* n): void +get. Nome(): char* +set. Nome. Dep(nomedep: char*): void 1 Em termos de projeto, é uma composição (ou agregação-forte) porque será implementada assim. 1 Departamento -id: int -nome: char[100] <<create>>+Departamento(i: int) <<destroy>>+Departamento() +get. Id(): int +set. Nome(n: char*): void +get. Nome(): char* Obs. : Agregação-forte ou Composição – losango preenchido 28
Classe Departamento #ifndef _DEPARTAMENTO_H_ #define _DEPARTAMENTO_H_ #include "Departamento. h" //. . . #include <string. h> class Departamento { private: char nome[130]; Departamento: : Departamento ( ) { strcpy ( nome, “” ); public: Departamento(); ~Departamento(); void set. Nome(char* n); char* get. Nome(); }; #endif } Departamento: : ~Departamento ( ) { } void Departamento: : set. Nome ( char* n ) { strcpy ( nome, n ); } char* Departamento: : get. Nome ( ) { return nome; } 29
Classe Universidade V 0 #ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento. h" class Universidade { private: char nome[130]; Departamento Dpto; // Objeto Dpto public: Universidade (); ~Universidade (); void set. Nome (char* n); char* get. Nome (); void set. Nome. Dep (char* nome_dep); }; #endif #include "Universidade. h" #include <stdio. h> Universidade: : Universidade () { strcpy ( nome, “” ); //Dpto. set. Nome("Teste"); } Universidade: : ~Universidade () { } char* Universidade: : get. Nome () { return nome; } void Universidade: : set. Nome (char* n) { strcpy ( nome, n ); } void Universidade: : set. Nome. Dep (char* nome_dep) { Dpto. setnome ( nome_dep ); Solução boa, mas inflexível. } 30
Classe Universidade V 0 #ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa. h" #include "Universidade. h" class Principal { private: Pessoa Simao; Pessoa Einstein; Pessoa Newton; Universidade UTFPR; Universidade Princeton; Universidade Cambridge; int dia. Atual; int mes. Atual; int ano. Atual; public: Principal (); ~Principal (); void Executar(); }; #endif Objeto da Classe Universidade UTFPR. . . Departamento Dpto Objeto da Classe Universidade Princeton. . . Departamento Dpto Objeto da Classe Universidade Cambridge. . . Departamento Dpto 31
Modelo em UML – Projeto - Classe Universidade V 1 - Solução por agregaçãosimples ou fraca. - A agregação-simples é caracterizada pelo fato do agregado poder eventualmente pertencer (fracamente) a mais de um agregador. Obs. : Agregação-fraca ou simples – losango vazio O uso de agregação forte ou fraca causa, por vezes, polêmica. Mesmo o entender do que é um e outro causa certa polêmica. 32
Classe Universidade V 1 #ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Universidade. h" #include <stdio. h> #include "Departamento. h" Universidade: : Universidade () { class Universidade { private: char nome[130]; Departamento* p. Dpto; p. Dpto = NULL; } // Ponteiro para departamento public: Universidade (); ~Universidade (); void set. Nome (char* n); char* get. Nome (); void set. Departamento (Departamento* pdep); }; #endif Universidade: : ~Universidade () { } char* Universidade: : get. Nome () { return nome; } void Universidade: : set. Nome (char* n) { strcpy ( nome, n ); } void Universidade: : set. Departamento (Departamento* pdep) { // Agregação via ponteiros p. Dpto = pdep; } Solução boa. Ela é “flexível”. . . 33
Classe Universidade V 1 #ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa. h" #include "Universidade. h" class Principal { private: Pessoa Simao; Pessoa Einstein; Pessoa Newton; Universidade UTFPR; Universidade Princeton; Universidade Cambridge; Departamento DAELN; Departamento Fisica. Princeton; Departamento Matematica. Cambridge; int dia. Atual; int mes. Atual; int ano. Atual; public: Principal (); void Executar(); }; #endif #include "Principal. h" #include <stdio. h> Principal: : Principal () {. . . // Registro do(s) nome(s) do(s) departamento(s) DAELN. set. Nome ("Eletronica"); Fisica. Princeton. set. Nome ("Fisica"); Matematica. Cambridge. set. Nome ("Matematica"); //"Agregação" do(s) Departamento(s) a(s) Univesidade(s). UTFPR. set. Departamento (&DAELN); Princeton. set. Departamento (&Fisica. Princeton); Cambridge. set. Departamento (&Matematica. Cambridge); } Assim sendo, se um objeto tem ponteiro para outro objeto, isto pode representar: - uma associação ou - uma agregação (fraca) Isto depende do que ele está representando no sistema real. Entretanto, se um objeto tem explicitamente outro objeto dentro de si (como na V 0), então é uma agregação. Apesar do objeto UTFPR tecnicamente estar associado ao objeto DAELN, teoricamente esta associação representa uma agregação uma vez que no sistema (mundo) real o DAELN está agregado na UTFPR Universidade UTFPR. . . Universidade Princeton. . . Universidade Cambridge. . . Departamento DAELN Departamento Fisica. Princeton Departamento Matematica Cambridge 34
Exercício 2 • Criar uma classe Departamento (em UML e depois em C++) que permita agregar um objeto (de Departamento) na classe Universidade. • A classe Pessoa deve possuir uma referência ao departamento que trabalha, ou seja: – Ela deve possuir uma associação com a Classe Departamento, permitindo que cada objeto Pessoa tenha a referência de um objeto Departamento. 35
Classe Pessoa #ifndef _PESSOA_H_ #define _PESSOA_H_ #include "Pessoa. h" #include <stdio. h> #include "Universidade. h" Pessoa: : Pessoa (int dia. Na, int mes. Na, int ano. Na, char* nome) {. . . } class Pessoa { private: int dia. P; int mes. P; int ano. P; int idade. P; char nome. P[30]; Universidade* p. Univ. Filiado; Departamento* p. Dpto. Filiado; public: Pessoa (int dia. Na, int mes. Na, int ano. Na, char* nome = ""); Pessoa ( ); ~Pessoa ( ); void Inicializa (int dia. Na, int mes. Na, int ano. Na, char* nome = ""); void Calc_Idade (int dia. AT, int mes. AT, int ano. AT); int informa. Idade (); void set. Univ. Filiado (Universidade* pu); void set. Departamento (Departamento* pdep); void Onde. Trabalho (); void Qual. Departamento. Trabalho (); }; #endif Pessoa: : Pessoa() { } void Pessoa: : Inicializa (int dia. Na, int mes. Na, int ano. Na, char* nome) {. . . } void Pessoa: : Calc_Idade (int dia. AT, int mes. AT, int ano. AT) {. . . } int Pessoa: : informa. Idade () {. . . } void Pessoa: : set. Univ. Filiado (Universidade* pu) {. . . } void Pessoa: : set. Departamento (Departamento* pdep) { // Aqui é uma associação porque é armazenado um apontamento // para o Departamento. p. Dpto. Filiado = pdep; } void Pessoa: : Onde. Trabalho () { cout << nome. P << “trabalha para a“ << p. Univ. Filiado->get. Nome() << endl; } void Pessoa: : Qual. Departamento. Trabalho () { cout << nome. P << “trabalha para a“ << p. Univ. Filiado->get. Nome() << p. Dpto. Filiado->get. Nome() << endl; } 36
Classe Principal #ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa. h" #include "Universidade. h" class Principal { private: Pessoa Simao; Pessoa Einstein; Pessoa Newton; #include "Principal. h" #include <stdio. h> Principal: : Principal () {. . . // Registro do(s) nome(s) do(s) departamento(s) DAELN. set. Nome ("Eletronica"); Fisica. Princeton. set. Nome ("Fisica"); Matematica. Cambridge. set. Nome ("Matematica"); // "Agregação" do(s) Departamento(s) a(s) Univesidade(s). UTFPR. set. Departamento (&DAELN); Princeton. set. Departamento (&Fisica. Princeton); Cambridge. set. Departamento (&Matematica. Cambridge); Universidade UTFPR; Universidade Princeton; Universidade Cambridge; printf ("n"); // "Filiação" a universidade. Simao. set. Univ. Filiado (&UTFPR); Einstein. set. Univ. Filiado (&Princeton); Newton. set. Univ. Filiado (&Cambridge); Departamento DAELN; Departamento Fisica. Princeton; Departamento Matematica. Cambridge; printf("n"); // "Filiação" ao departamento. Simao. set. Departamento (&DAELN); Einstein. set. Departamento (&Fisica. Princeton); Newton. set. Departamento (&Matematica. Cambridge); int dia. Atual; int mes. Atual; int ano. Atual; public: Principal ( ); ~Principal ( ) { } void Executar(); }; #endif } void Principal: : Executar () {. . . printf("n"); // Universidade que a Pessoa trabalha. Simao. Onde. Trabalho(); Einstein. Onde. Trabalho(); Newton. Onde. Trabalho(); printf("n"); // Departamento que a Pessoa trabalha. Simao. Qual. Departamento. Trabalho (); Einstein. Qual. Departamento. Trabalho (); Newton. Qual. Departamento. Trabalho (); } 37
Atenção As próximas duas versões (V 2 e V 3) são ruins: queira entender o porquê. 38
Classe Universidade V 2 #ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Universidade. h" #include <stdio. h> #include "Departamento. h" Universidade: : Universidade () { //Dpto. set. Nome("Teste"); } class Universidade { private: char nome[130]; Departamento Dpto; public: Universidade (); ~Universidade (); void set. Nome (char* n); char* get. Nome (); void set. Departamento (Departamento* dep); }; #endif Universidade: : ~Universidade () { } char* Universidade: : get. Nome () { return nome; } void Universidade: : set. Nome (char* n) { strcpy ( nome, n ); } void Universidade: : set. Departamento (Departamento* dep) { Dpto = *dep; // Neste caso, o objeto Dpto será um cópia (um clone) do dep passado por // parâmetro (por “valor”). . . Isto pode ser feito quando o objeto apontado por dep // não precisa ser sincronizado com o Dpto ou não mudará de valor. . . // Mas muito cuidado com este tipo de construção! //printf("Departamento %s está filiado a Universidade %s n n", Dpto. get. Nome(), nome); Solução ruim. . . } 39
Classe Universidade V 3 #ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Universidade. h" #include <stdio. h> #include "Departamento. h" Universidade: : Universidade () { //Dpto. set. Nome("Teste"); } class Universidade { private: char nome[130]; Departamento Dpto; public: Universidade (); ~Universidade (); void set. Nome (char* n); char* get. Nome (); void set. Departamento (Departamento dep); }; #endif Universidade: : ~Universidade () { } char* Universidade: : get. Nome () { return nome; } void Universidade: : set. Nome (char* n) { strcpy ( nome, n ); } void Universidade: : set. Departamento (Departamento dep) { Dpto = dep; // Neste caso, o objeto Dpto será um cópia (um clone) do dep passado por // parâmetro (por valor). . . Isto pode ser feito quando o objeto dep não precisa // ser sincronizado com o Dpto ou não mudará de valor. . . // Mas muito cuidado com este tipo de construção! //printf("Departamento %s está filiado a Universidade %s n n", Dpto. get. Nome(), nome); Solução ruim. . . } 40
Exercício 3 UML / C++ 41
Exercício 3 Em diagrama de classe da UML e depois em C++ • Fazer com que uma Universidade possa ter até 50 Departamentos, tendo pelos menos um. • Fazer com que cada Departamento referencie a Universidade a qual está filiada. • Criar mais Departamentos Universidades. . . filiando-os as 42
Modelo em UML - Análise 43
Modelo em UML - Projeto 44
Solução para Exercício 1 #ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento. h" class Universidade { private: char nome [ 130 ]; Departamento* p. Dptos [ 50 ]; public: Universidade ( ); ~Universidade ( ); void set. Nome ( char* n ); char* get. Nome ( ); void set. Departamento ( Departamento* pdep, int ctd ); }; #endif 45
Solução para Exercício 1 #ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento. h" class Universidade { private: char nome [ 130 ]; Departamento* p. Dptos [ 50 ]; public: Universidade ( ); ~Universidade ( ); void set. Nome ( char* n ); char* get. Nome ( ); void set. Departamento ( Departamento* pdep, int ctd ); Um problema desta implementação é que o número de departamentos é fixo, o que pode gerar desperdício ou subdimensionamento. Há soluções para isto, como uso de lista encadeada ou o uso de alocação dinâmica de vetor com expansão (e. g. desalocação e nova alocação) quando se fizer necessário. }; #endif 46
#include "stdafx. h" #include "Universidade. h" Universidade: : Universidade ( ) { for ( int i = 0 ; i < 50; i++) { p. Dptos [ i ] = NULL; } } Universidade: : ~Universidade ( ) { } char* Universidade: : get. Nome ( ) { return nome; } void Universidade: : set. Nome ( char* n ) { strcpy ( nome, n ); } void Universidade: : set. Departamento ( Departamento* Universidade: : set. Departamento* pdep , int ctd ) { p. Dptos [ ctd ] = pdep; } 47
Solução para Exercício 1 #ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento. h" class Universidade { private: char nome [ 130 ]; Departamento* p. Dptos [ 50 ]; public: Universidade ( ); ~Universidade ( ); void set. Nome ( char* n ); char* get. Nome ( ); void set. Departamento ( Departamento* pdep, int ctd ); void imprime. Dptos ( ) ; }; #endif 48
#include "stdafx. h" #include "Universidade. h" Universidade: : Universidade ( ) { for ( int i = 0 ; i < 50; i++) { p. Dptos [ i ] = NULL; } } Universidade: : ~Universidade ( ) { } char* Universidade: : get. Nome ( ){ return nome; } void Universidade: : set. Nome ( char* n ) { strcpy ( nome, n ); } void Universidade: : set. Departamento ( Departamento* Universidade: : set. Departamento* pdep , int ctd ){ p. Dptos [ ctd ] = pdep; } void Universidade: : imprime. Dptos ( ) { Departamento* p. Dep = NULL; for ( int i = 0 ; i < 50; i++) { p. Dep = p. Dptos [ i ]; if ( p. Dep != NULL ) cout << p. Dep->get. Nome() << endl; } } 49
#include "stdafx. h" #include "Universidade. h" Universidade: : Universidade ( ) { for ( int i = 0 ; i < 50; i++) { p. Dptos [ i ] = NULL; } } Universidade: : ~Universidade ( ) { } char* Universidade: : get. Nome ( ){ return nome; } void Universidade: : set. Nome ( char* n ) { strcpy ( nome, n ); } void Universidade: : set. Departamento ( Departamento* Universidade: : set. Departamento* pdep , int ctd ){ p. Dptos [ ctd ] = pdep; } void Universidade: : imprime. Dptos ( ) { // versão 2 // Departamento* p. Dep = NULL; for ( int i = 0 ; i < 50; i++) { p. Dep = p. Dptos [ i ]; if ( p. Dptos [ i ] != NULL ) // ( p. Dep != NULL ) cout << p. Dptos[ i ]->get. Nome() << endl; } } 50
#ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa. h" #include "Universidade. h" class Principal { private: . . . Pessoa Christiano; Pessoa Diego, Simao; Pessoa Einstein; Pessoa Newton; Universidade UTFPR, Princeton, Cambridge; Departamento Moda. UFTPR, Tecnologia. UTFPR, DAELN, Fisica. Princeton, Matematica. Cambridge; int dia. Atual, mes. Atual, ano. Atual; public: Principal ( ); void Executar ( ); . . . }; #endif 51
#include "stdafx. h“ #include "Principal. h" Principal: : Principal ( ) {. . . // leitura da data atual // Inicialização do(s) ojeto(s) da classe Pessoa Christiano. Inicializa ( 17, 8, 1989, "Zé Maria"); Diego. Inicializa ( 6, 10, 1989, "Diego"); Simao. Inicializa ( 3, 10, 1976, "Jean Simão"); Einstein. Inicializa ( 14, 3, 1879, "Albert Einstein"); Newton. Inicializa ( 4, 1, 1643, "Isaac Newton"); // Registro do(s) nome(s) da(s) universidade(s) UTFPR. set. Nome ( "Universidade Tecnologica Federal do Paraná"); Princeton. set. Nome ( "University of Princeton" ); Cambridge. set. Nome ( "University of Cambridge" ); // Registro do(s) nome(s) do(s) departamento(s) Moda. UFTPR. set. Nome ( "Moda" ); Tecnologia. UTFPR. set. Nome ( "Tecnologia da UTFPR" ); DAELN. set. Nome ( "Eletronica da UTFPR" ); Fisica. Princeton. set. Nome ( "Fisica de Princenton" ); Matematica. Cambridge. set. Nome ( "Matematica de Cambridge" ); // "Agregação" do(s) Departamento(s) a(s) Univesidade(s). UTFPR. set. Departamento ( &DAELN, 0 ); UTFPR. set. Departamento ( &Moda. UTFPR, 1 ); UTFPR. set. Departamento ( &Tecnologia. UTFPR, 2 ); Princeton. set. Departamento ( &Fisica. Princeton, 0 ); Cambridge. set. Departamento ( &Matematica. Cambridge, 0 ); // "Filiação" a universidade. Christiano. set. Univ. Filiado ( &UTFPR ); Diego. set. Univ. Filiado ( &UTFPR ); Simao. set. Univ. Filiado ( &UTFPR ); Einstein. set. Univ. Filiado ( &Princeton ); Newton. set. Univ. Filiado ( &Cambridge ); printf ("n"); // "Filiação" ao departamento. Christiano. set. Departamento ( &Moda. UFTPR ); Diego. set. Departamento ( &Tecnologia. UTFPR ); Simao. set. Departamento ( &DAELN ); Einstein. set. Departamento ( &Fisica. Princeton ); Newton. set. Departamento ( &Matematica. Cambridge ); printf ("n") } void Principal: : Executar ( ) { // Cálculo da idade. Christiano. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Diego. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Simao. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Einstein. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Newton. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); printf ("n"); // Universidade que a Pessoa trabalha. Christiano. Onde. Trabalho ( ); Diego. Onde. Trabalho ( ); Simao. Onde. Trabalho ( ); Einstein. Onde. Trabalho ( ); Newton. Onde. Trabalho ( ); printf("n"); // Departamento que a Pessoa trabalha. Christiano. Qual. Departamento. Trabalho ( ); Diego. Qual. Departamento. Trabalho ( ); Simao. Qual. Departamento. Trabalho ( ); Einstein. Qual. Departamento. Trabalho ( ); Newton. Qual. Departamento. Trabalho ( ); } 52
Falta Ainda • . Fazer com que uma Universidade possa ter até 50 Departamentos • Fazer com que um Departamento referencie a Universidade a qual está filiado • Criar mais Departamentos filiando-os as Universidades. . 53
Atenção: evite includes recursivos! Universidade. h Departamento. h #ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #ifndef _DEPARTAMENTO_H_ #define _DEPARTAMENTO_H_ #include "Departamento. h" class Universidade; class Universidade {. . . }; #endif class Departamento { … }; #endif Universidade. cpp Departamento. cpp #include "Universidade. h" #include <stdio. h> #include <string. h> #include "Departamento. h“ Universidade: : Universidade ( ) { } #include "Universidade. h" Universidade: : ~Universidade ( ) { }. . . Departamento: : Departamento ( ) { } Departamento: : ~Departamento ( ) { } … 54
#include "stdafx. h“ #include "Principal. h" // "Filiação" a universidade. Christiano. set. Univ. Filiado ( &UTFPR ); Diego. set. Univ. Filiado ( &UTFPR ); Simao. set. Univ. Filiado ( &UTFPR ); Einstein. set. Univ. Filiado ( &Princeton ); Newton. set. Univ. Filiado ( &Cambridge ); printf ("n"); // "Filiação" ao departamento. Christiano. set. Departamento ( &Moda. UFTPR ); Diego. set. Departamento ( &Tecnologia. UTFPR ); Simao. set. Departamento ( &DAELN ); Einstein. set. Departamento ( &Fisica. Princeton ); Newton. set. Departamento ( &Matematica. Cambridge ); printf ("n"); Principal: : Principal ( ) {. . . // leitura da data atual // Inicialização do(s) ojeto(s) da classe Pessoa Christiano. Inicializa Diego. Inicializa Simao. Inicializa Einstein. Inicializa Newton. Inicializa ( 17, 8, 1989, "Zé Maria"); ( 6, 10, 1989, "Diego"); ( 3, 10, 1976, "Jean Simão"); ( 14, 3, 1879, "Albert Einstein"); ( 4, 1, 1643, "Isaac Newton"); // Registro do(s) nome(s) da(s) universidade(s) UTFPR. set. Nome ( "Universidade Tecnologica Federal do Paraná"); Princeton. set. Nome ( "University of Princeton" ); Cambridge. set. Nome ( "University of Cambridge" ); // Registro do(s) nome(s) do(s) departamento(s) Moda. UFTPR. set. Nome ( "Moda" ); Tecnologia. UTFPR. set. Nome ( "Tecnologia da UTFPR" ); DAELN. set. Nome ( "Eletronica da UTFPR" ); Fisica. Princeton. set. Nome ( "Fisica de Princenton" ); Matematica. Cambridge. set. Nome ( "Matematica de Cambridge" ); // "Agregação" do(s) Departamento(s) a(s) Univesidade(s). UTFPR. set. Departamento ( &DAELN, 0 ); UTFPR. set. Departamento ( &Moda. UTFPR, 1 ); UTFPR. set. Departamento ( &Tecnologia. UTFPR, 2 ); Princeton. set. Departamento ( &Fisica. Princeton, 0 ); Cambridge. set. Departamento ( &Matematica. Cambridge, 0 ); } void Principal: : Executar ( ) { // Cálculo da idade. Christiano. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Diego. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Simao. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Einstein. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); Newton. Calc_Idade ( dia. Atual, mes. Atual, ano. Atual ); printf ("n"); // Universidade que a Pessoa trabalha. Christiano. Onde. Trabalho ( ); Diego. Onde. Trabalho ( ); Simao. Onde. Trabalho ( ); Einstein. Onde. Trabalho ( ); Newton. Onde. Trabalho ( ); printf("n"); // Departamento que a Pessoa trabalha. Christiano. Qual. Departamento. Trabalho ( ); Diego. Qual. Departamento. Trabalho ( ); Simao. Qual. Departamento. Trabalho ( ); Einstein. Qual. Departamento. Trabalho ( ); Newton. Qual. Departamento. Trabalho ( ); DAELN. set. Universidade ( &UTFPR ); . . } 55
- Slides: 55