1
Orientação a Objetos
-Programação em C++
3
o
Slides: Relações entre
objetos em C++ e UML
OO – Engenharia Eletrônica
Engenharia de Software
Levantamento
de
Requisitos
Análise
e
Projeto
Implementação
ou
Codificação
Testes
Visão Clássica
3
Engenharia de Software OO
Levantamento
de
Requisitos
Análise
e
Projeto
Implementação
ou
Codificação
Testes
Texto
---Diagramas de
Casos de Uso
da UML
Exemplos de Técnicas
Diagramas UML de:
- CLASSES
- Objetos/Seqüência
-Colaboração
-Estados
-Atividades
-Componentes
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.
Diagramas da UNIFIED MODELING LANGUAGE (UML).
Linguagem e ambiente de Programação OO.
Engenharia de Software OO
Levantamento
de
Requisitos
Análise
e
Projeto
Implementação
ou
Codificação
Testes
Diagramas de Casos de Uso da UMLExemplos de Ferramentas
Diagramas UML de: - CLASSES - Objetos - Seqüência -Colaboração -Estados -Atividades 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.
Ferramentas CASE: StarUML, Jude,
Rational
Rose,
System
Architect,
Together, VisualParadigm, Rhapsody
. . .
Ambiente
de
Programação
OO
(integráveis
as
Ferramentas CASE): Microsoft Visual C++ .net Express
Edition,
Microsoft Visual C++ .net, Microsoft Visual C++, Borland Builder C++, Borland C++, Dev C++, G++.5
Bibliografias:
-
Pressman, R. S. Software Engineering – A Practitioner’s Approach. 6th Edition McGraw
Hill (Higher Education). 2005. ISBN 0-07-285318-2.
-
RUMBAUGH, J.; JACOBSON, I.; BOOCH, G. The Unified Modeling Language Reference
Manual. 2nd 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. 1st 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.
Primeiramente: Qual será ou tem sido
nosso exemplo para estudos?
7
Definindo Requisitos Funcionais
(e Gerais) do Sistema Acadêmico
• Registrar no sistema um conjunto de Universidades.
• Registrar no sistema um conjunto de Departamento
relacionados a Universidades.
• Registrar
no
sistema
um
conjunto
de
Disciplinas
relacionados a Departamento.
• 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 sistemas real, os requisitos deveriam ser
definidos e estabelecidos o quanto antes (dentro do ciclo de engenharia de software).
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.
9
Retomando a última aula, onde 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...
Classe Universidade em C++
#ifndef _UNIVERSIDADE_H_
#define _UNIVERSIDADE_H_
class
Universidade
{
private:
char
nome[30]
;
public:
// Construtor
Universidade
( );
// Destrutor
~Universidade
( );
void
setNome
( char*
n
);
char*
getNome
( );
};
#endif
#include "Universidade.h"
#include <stdio.h
>
Universidade
::
Universidade
( )
{
strcpy (
nome
,
“”
);
}
Universidade
::~
Universidade
( )
{
}
void
Universidade
::
setNome
( char*
n
)
{
strcpy (
nome
,
n
);
}
char*
Universidade
::
getNome
( )
{
return
nome
;
}
Universidade.h Universidade.cpp
Obs. : O construtor inicializa elementos, como atributos. O destrutor “zera” alguns elementos...
11
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.
Universidade
-char nome[30]
<<create>>+Universidade()
<<destroy>>+Universidade()
+setNome(char* n): void
+getNome(): char*
Classe Pessoa em C++ - associada à Universidade
#ifndef _PESSOA_H_ #define _PESSOA_H_ #include “Universidade.h” . . . class Pessoa { private:intdiaP; int mesP; intanoP; intidadeP; charnomeP[30];
// pUnivFiliado é apenas uma referência a um objeto associado.
Universidade*pUnivFiliado; public:
Pessoa ( intdiaNa, intmesNa, intanoNa, char*nome = "" );
Pessoa ( ) ;
~Pessoa ( ) ;
voidInicializa ( int diaNa, intmesNa, intanoNa, char*nome = "" ); voidCalc_Idade ( intdiaAT, intmesAT, int anoAT );
intinformaIdade ( ); voidsetNome ( char*n ); char*getNome ( );
// Este método abaixo permite associar // uma Univ. à Pessoa.
voidsetUnivFiliado ( Universidade*pu ); voidOndeTrabalho ( );
}
;
#endif
#include "Pessoa.h"
. . .
voidPessoa::setUnivFiliado ( Universidade*pu ) {
pUnivFiliado =pu; }
voidPessoa::OndeTrabalho ( ) {
// Um método da referência pUnivFiliado é chamado.
cout << nomeP<<
"
trabalha para a"
<<pUnivFiliado->getNome() << endl; }13
Classe Pessoa em UML
Por exemplo, pode-se utilizar a ferramenta StarUML para planejar/projetar classes
Pessoa
-diaP: int
-mesP: int
-anoP: int
-idadeP: int
-nomeP: char[30]
-id: int
<<create>>+Pessoa(diaNa: int, mesNa: int, anoNa: int, nome: char*)
<<create>>+Pessoa()
<<destroy>>+Pessoa()
+Inicializa(diaNa: int, mesNa: int, anoNa: int, nome: char): void
+Calc_Idade(diaAT: int, mesAT: int, anoAT: int): void
+informaIdade(): int
+setNome(n: char*): void
+getNome(): char*
+setId(i: int): void
+getId(): int
Associação entre Objetos
#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
.
setNome
("
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
.
setUnivFiliado
(&
UTFPR
);
Executar
();
}
void
Principal
::
Executar
()
{
. . .
Simao
.
Calc_Idade
(
diaAtual
,
mesAtual
,
anoAtua
);
Einstein
.
Calc_Idade
(
diaAtual, mesAtual
,
anoAtual
);
Newton
.
Calc_Idade
(
diaAtual
,
mesAtual
,
anoAtual
);
Simao
.
OndeTrabalho
();
}
#ifndef _PRINCIPAL_H_
#define _PRINCIPAL_H_
#include "Pessoa.h"
#include "Universidade.h“
class
Principal
{
private:
Pessoa Simao
;
Pessoa Einstein
;
Pessoa Newton
;
// UTFPR é agregada ao(s) objeto(s) desta classe!!!
Universidade UTFPR;
int
diaAtual
;
int
mesAtual
;
int
anoAtual
;
public:
Principal
();
void
Executar
();
};
#endif
15
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
.
setNome
("
UTFPR
");
Simao
.
setUnivFiliado
( &
UTFPR
);
}
UTFPR
Nome – “UTFPR”
Objeto da Classe Universidade Objeto da Classe Pessoa
SIMAO
nomeP – “Jean Simão” diaP – 3
mesP – 10 anoP – 1976 idadeP - ?
Diagrama de Classes que modela (analisa) o
relacionamento de associação entre objetos de Pessoa e
de Universidade (por meio de suas classes).
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.
Pessoa -diaP: int -mesP: int -anoP: int -idadeP: int -nomeP: char[30] -id: int
<<create>>+Pessoa(diaNa: int, mesNa: int, anoNa: int, nome: char*) <<create>>+Pessoa()
<<destroy>>+Pessoa()
+Inicializa(diaNa: int, mesNa: int, anoNa: int, nome: char): void +Calc_Idade(diaAT: int, mesAT: int, anoAT: int): void
+informaIdade(): int +setNome(n: char*): void +getNome(): char* +setId(i: int): void +getId(): int Conhecer 0..1 Universidade -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char*
17
Diagrama de Classes que modela (analisa) o
relacionamento de associação entre objetos de Pessoa e
de Universidade (por meio de suas classes).
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.
Pessoa -diaP: int -mesP: int -anoP: int -idadeP: int -nomeP: char[30] -id: int
<<create>>+Pessoa(diaNa: int, mesNa: int, anoNa: int, nome: char*) <<create>>+Pessoa()
<<destroy>>+Pessoa()
+Inicializa(diaNa: int, mesNa: int, anoNa: int, nome: char): void +Calc_Idade(diaAT: int, mesAT: int, anoAT: int): void
+informaIdade(): int +setNome(n: char*): void +getNome(): char* +setId(i: int): void +getId(): int Conhecer 0..* 0..1 Universidade -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char*
Diagrama de Classes que modela (projeta) o
relacionamento de associação entre objetos de Pessoa e
de Universidade (por meio de suas classes).
Obs.: Tendo em vista que o Diagrama traz alguns detalhes de implementação,
ele pode ser considerado como um Diagrama de Classes de Projeto.
Implementação via Ponteiro Pessoa -diaP: int -mesP: int -anoP: int -idadeP: int -nomeP: char[30] -id: int +pUnivFiliado: Universidade*
<<create>>+Pessoa(diaNa: int, mesNa: int, anoNa: int, nome: char*) <<create>>+Pessoa()
<<destroy>>+Pessoa()
+Inicializa(diaNa: int, mesNa: int, anoNa: int, nome char*) +Calc_Idade(diaAT: int, mesAT: int, aniAT: int): void +informaIdade(): int
+setNome(n: char*): void +getNome(): char* +setId(i: int): void +getId(): int
+setUnivFiliado(pu: Universidade*): void +OndeTrabalho(): void Conhecer 0..1 0..* Universidade -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char*
19
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).
Solução - Agregação
#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.setNome ( "UTFPR" );
Princeton.setNome ( "Princeton" );
Cambridge.setNome( "Cambridge" );
// Aqui os objetos Universidade e Pessoa são associados.
Simao.setUnivFiliado ( &UTFPR ); Einstein.setUnivFiliado ( &Princeton ); Newton.setUnivFiliado (&Cambridge ); . . .
}
Principal::~Principal( ) {
}
voidPrincipal::Executar() {
Simao.Calc_Idade ( diaAtual, mesAtual, anoAtua );
Einstein.Calc_Idade ( diaAtual, mesAtual, anoAtual );
Newton.Calc_Idade ( diaAtual, mesAtual, anoAtual );
Simao.OndeTrabalho ( ); Einstein.OndeTrabalho ( ); Newton.OndeTrabalho( ); } #ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa.h" #include "Universidade.h“ classPrincipal { private: Pessoa Simao; Pessoa Einstein; Pessoa Newton;
// UTFPR é agregada ao(s) objeto(s) desta classe!!!
Universidade UTFPR; Universidade Princeton; Universidade Cambridge; int diaAtual; int mesAtual; int anoAtual; public: Principal(); ~Principal(); void Executar(); }; #endif
21
Agregação-forte
ObjetoPrincipal
Simao
Einstein
Newton
UTFPR
Princeton
Cambridge
Classe Principal Classe Pessoa Classe PessoaClasse Pessoa Classe Universidade Classe Universidade Classe Universidade
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.
Agregação-forte em UML
A agregação-forte também é chamada de “composição”.
Universidade -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char* Pessoa -diaP: int -mesP: int -anoP: int -idadeP: int -nomeP: char[30] -id: int
<<create>>+Pessoa(diaNa: int, mesNa: int, anoNa: int, nome: char*) <<create>>+Pessoa()
<<destroy>>+Pessoa()
+Inicializa(diaNa: int, mesNa: int, anoNa: int, nome: char): void +Calc_Idade(diaAT: int, mesAT: int, anoAT: int): void
+informaIdade(): int +setNome(n: char*): void +getNome(): char* +setId(i: int): void +getId(): int 3 3 Principal -mesatual: int -diaatual: int -anoatual: int <<create>>+Principal() <<destroy>>+Principal() +Executar()
23
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
Pessoa -diaP: int -mesP: int -anoP: int -idadeP: int -nomeP: char[30] -id: int
<<create>>+Pessoa(diaNa: int, mesNa: int, anoNa: int, nome: char*) <<create>>+Pessoa()
<<destroy>>+Pessoa()
+Inicializa(diaNa: int, mesNa: int, anoNa: int, nome: char): void +Calc_Idade(diaAT: int, mesAT: int, anoAT: int): void
+informaIdade(): int +setNome(n: char*): void +getNome(): char* +setId(i: int): void +getId(): int Universidade -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char* 0..* 0..* Principal -mesatual: int -diaatual: int -anoatual: int <<create>>+Principal() <<destroy>>+Principal() +Executar()
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
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.
Modelo em UML - Análise
Pessoa -diaP: int -mesP: int -anoP: int -idadeP: int -nomeP: char[30] -id: int<<create>>+Pessoa(diaNa: int, mesNa: int, anoNa: int, nome: char*) <<create>>+Pessoa()
<<destroy>>+Pessoa()
+Inicializa(diaNa: int, mesNa: int, anoNa: int, nome: char): void +Calc_Idade(diaAT: int, mesAT: int, anoAT: int): void
+informaIdade(): int +setNome(n: char*): void +getNome(): char* +setId(i: int): void +getId(): int Departamento -id: int -nome: char[100] <<create>>+Departamento(i: int) <<destroy>>+Departamento() +getId(): int
+setNome(n: char*): void +getNome(): char* Universidade -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char* Conhecer 0..* 0..1 1 Conhecer 0..1 0..* É uma agregação-forte
(composição) nesta análise porque assim o é no sistema real analisado.
27
Modelo em UML - Projeto
Departamento -id: int -nome: char[100] <<create>>+Departamento(i: int) <<destroy>>+Departamento() +getId(): int
+setNome(n: char*): void +getNome(): char* Em termos de projeto,
é uma composição (ou agregação-forte) porque será implementada assim.
Universidade -nome: char[30] -dpto: Departamento <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char*
+setNomeDep(nomedep: char*): void
Conhecer 0..1 0..* Conhecer 0..1 0..* Pessoa -diaP: int -mesP: int -anoP: int -idadeP: int -nomeP: char[30] -id: int +pUnivFiliado: Universidade* +pDptoFiliado: Departamento*
<<create>>+Pessoa(diaNa: int, mesNa: int, anoNa: int, nome: char*) <<create>>+Pessoa()
<<destroy>>+Pessoa()
+Inicializa(diaNa: int, mesNa: int, anoNa: int, nome char*) +Calc_Idade(diaAT: int, mesAT: int, aniAT: int): void +informaIdade(): int
+setNome(n: char*): void +getNome(): char* +setId(i: int): void +getId(): int
+setUnivFiliado(pu: Universidade*): void
+setDepartamento(pdpto: Departamento*): void +OndeTrabalho(): void
+QualDepartamentoTrabalho(): void 1
Modelo em UML – Projeto - Classe Universidade V0
- Solução por
agregação-forte ou composição.
-
A
composição
é
caracterizada pelo fato
do agregado só poder
pertencer efetivamente a
um agregador.
Obs.: Agregação-forte ou Composição – losango preenchido
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() +getId(): int
+setNome(n: char*): void +getNome(): char* Universidade -nome: char[30] -dpto: Departamento <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char*
+setNomeDep(nomedep: char*): void 1
29
Classe Departamento
#ifndef _DEPARTAMENTO_H_
#define _DEPARTAMENTO_H_
class
Departamento
{
private:
char
nome[130];
public:
Departamento
();
~
Departamento
();
void
setNome
(char*
n
);
char*
getNome
();
};
#endif
#include "Departamento.h"
// . . .
#include <string.h>
Departamento
::
Departamento
( )
{
strcpy
(
nome
,
“”
);
}
Departamento
::~
Departamento
( )
{
}
void
Departamento
::
setNome
( char*
n
)
{
strcpy
(
nome
,
n
);
}
char*
Departamento
::
getNome
( )
{
return
nome
;
}
Classe Universidade V0
#ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento.h" classUniversidade { private: charnome[130];Departamento Dpto; // Objeto Dpto
public:
Universidade(); ~Universidade();
void setNome(char*n); char*getNome();
void setNomeDep(char*nome_dep); }; #endif #include "Universidade.h" #include <stdio.h> Universidade::Universidade() { strcpy(nome,“”); //Dpto.setNome("Teste"); } Universidade::~Universidade() { }
char*Universidade::getNome() {
returnnome; }
voidUniversidade::setNome(char*n) {
strcpy(nome,n); }
voidUniversidade::setNomeDep(char*nome_dep) {
Dpto.setnome(nome_dep); }
31
#ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa.h" #include "Universidade.h" classPrincipal { private: Pessoa Simao; Pessoa Einstein; Pessoa Newton; Universidade UTFPR; Universidade Princeton; Universidade Cambridge; intdiaAtual; intmesAtual; intanoAtual; public: Principal(); ~Principal (); voidExecutar(); }; #endifUTFPR
. . .Objeto da Classe Universidade
Dpto
Departamento
Princeton
. . .
Objeto da Classe Universidade
Dpto
Departamento
Cambridge
. . .
Objeto da Classe Universidade
Dpto
Departamento
Modelo em UML – Projeto - Classe Universidade V1
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.
Departamento -id: int -nome: char[100] <<create>>+Departamento(i: int) <<destroy>>+Departamento() +getId(): int
+setNome(n: char*): void +getNome(): char* Em termos de projeto,
é uma agregração-simples porque será implementada por meio de ponteiros
1 1 Universidade -nome: char[30] -pdpto: Departamento* <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char*
+setDepartamento(pdep: Departamento*): void
- Solução por
agregação-simples ou fraca.
- A agregação-simples é
caracterizada pelo fato
do
agregado
poder
eventualmente pertencer
(fracamente) a mais de
um agregador.
33
Classe Universidade V1
#ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento.h" classUniversidade { private: charnome[130];Departamento* pDpto; // Ponteiro para departamento
public:
Universidade(); ~Universidade();
voidsetNome(char*n); char*getNome();
voidsetDepartamento(Departamento*pdep); }; #endif #include "Universidade.h" #include <stdio.h> Universidade::Universidade() { pDpto = NULL; } Universidade::~Universidade() { }
char*Universidade::getNome() {
returnnome; }
voidUniversidade::setNome(char*n) {
strcpy(nome,n); }
voidUniversidade::setDepartamento(Departamento*pdep) {
// Agregação via ponteiros
pDpto = pdep;
}
Classe Universidade V1
#ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa.h" #include "Universidade.h" classPrincipal { private: Pessoa Simao; Pessoa Einstein; Pessoa Newton; Universidade UTFPR; Universidade Princeton; Universidade Cambridge; Departamento DAELN; Departamento FisicaPrinceton; Departamento MatematicaCambridge; intdiaAtual; intmesAtual;intanoAtual; public: Principal(); voidExecutar(); }; #endif #include "Principal.h" #include <stdio.h> Principal::Principal() { . . .// Registro do(s) nome(s) do(s) departamento(s) DAELN.setNome ("Eletronica");
FisicaPrinceton.setNome("Fisica");
MatematicaCambridge.setNome("Matematica");
//"Agregação" do(s) Departamento(s) a(s) Univesidade(s). UTFPR.setDepartamento(&DAELN);
Princeton.setDepartamento(&FisicaPrinceton);
Cambridge.setDepartamento(&MatematicaCambridge);
} UTFPR . . . Universidade DAELN Departamento Princeton . . . Universidade FisicaPrinceton Departamento Cambridge . . . Universidade Matematica Cambridge Departamento
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
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 V0), então é uma agregação.
35
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.
Classe Pessoa
#ifndef _PESSOA_H_ #define _PESSOA_H_ #include "Universidade.h" classPessoa { private: intdiaP; intmesP; intanoP; intidadeP; charnomeP[30]; Universidade*pUnivFiliado; Departamento*pDptoFiliado; public:Pessoa(intdiaNa, intmesNa, intanoNa, char*nome= "");
Pessoa( );
~Pessoa( );
voidInicializa(intdiaNa, intmesNa, intanoNa, char*nome= ""); voidCalc_Idade(intdiaAT, intmesAT, intanoAT);
int informaIdade();
voidsetUnivFiliado(Universidade*pu); voidsetDepartamento(Departamento* pdep); voidOndeTrabalho(); voidQualDepartamentoTrabalho(); }; #endif #include "Pessoa.h" #include <stdio.h>
Pessoa::Pessoa(intdiaNa, intmesNa, intanoNa, char*nome) {...}
Pessoa::Pessoa() { }
voidPessoa::Inicializa(intdiaNa, intmesNa, intanoNa, char*nome) { ...}
voidPessoa::Calc_Idade(intdiaAT, intmesAT, intanoAT) { ...}
intPessoa::informaIdade() {...}
voidPessoa::setUnivFiliado(Universidade*pu) {...}
voidPessoa::setDepartamento(Departamento*pdep)
{ //Aqui é uma associação porque é armazenado um apontamento
//para o Departamento.
pDptoFiliado=pdep; }
voidPessoa::OndeTrabalho() {
cout <<nomeP<< “trabalha para a“ <<pUnivFiliado->getNome() << endl; }
voidPessoa::QualDepartamentoTrabalho() {
cout <<nomeP<< “trabalha para a“ <<pUnivFiliado->getNome() <<pDptoFiliado->getNome() << endl;
37
Classe Principal
#ifndef _PRINCIPAL_H_ #define _PRINCIPAL_H_ #include "Pessoa.h" #include "Universidade.h" classPrincipal { private: Pessoa Simao; Pessoa Einstein; Pessoa Newton; Universidade UTFPR; Universidade Princeton; Universidade Cambridge; Departamento DAELN; Departamento FisicaPrinceton; Departamento MatematicaCambridge; intdiaAtual; intmesAtual; intanoAtual; public: Principal( ); ~Principal( ) { } voidExecutar(); }; #endif #include "Principal.h" #include <stdio.h> Principal::Principal() { . . .// Registro do(s) nome(s) do(s) departamento(s) DAELN.setNome("Eletronica");
FisicaPrinceton.setNome("Fisica");
MatematicaCambridge.setNome("Matematica");
// "Agregação" do(s) Departamento(s) a(s) Univesidade(s). UTFPR.setDepartamento(&DAELN);
Princeton.setDepartamento(&FisicaPrinceton);
Cambridge.setDepartamento(&MatematicaCambridge); printf ("\n");
// "Filiação" a universidade. Simao.setUnivFiliado(&UTFPR);
Einstein.setUnivFiliado(&Princeton);
Newton.setUnivFiliado(&Cambridge); printf("\n");
// "Filiação" ao departamento. Simao.setDepartamento(&DAELN);
Einstein.setDepartamento(&FisicaPrinceton);
Newton.setDepartamento(&MatematicaCambridge);
}
voidPrincipal::Executar() { . . .
printf("\n");
// Universidade que a Pessoa trabalha. Simao.OndeTrabalho();
Einstein.OndeTrabalho();
Newton.OndeTrabalho(); printf("\n");
// Departamento que a Pessoa trabalha. Simao.QualDepartamentoTrabalho();
Einstein.QualDepartamentoTrabalho();
Newton.QualDepartamentoTrabalho(); }
Atenção
As próximas duas versões (V2 e V3)
são ruins: queira entender o porquê.
39
Classe Universidade V2
#ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento.h" classUniversidade { private: charnome[130]; Departamento Dpto; public: Universidade(); ~Universidade(); voidsetNome(char*n); char*getNome();voidsetDepartamento(Departamento*dep); }; #endif #include "Universidade.h" #include <stdio.h> Universidade::Universidade() { //Dpto.setNome("Teste"); } Universidade::~Universidade() { }
char*Universidade::getNome() {
returnnome; }
voidUniversidade::setNome(char*n) {
strcpy(nome,n); }
voidUniversidade::setDepartamento(Departamento*dep) {
Dpto = *dep;
// Neste caso, o objeto Dpto será um cópia (um clone) do Dep passado por // parâmetro (por “valo”r)... Isto pode ser feito quando o objeto Dep não precisa // ser sincronizado com o Depto 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.getNome(), nome);
}
Classe Universidade V3
#ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento.h" classUniversidade { private: charnome[130]; Departamento Dpto; public: Universidade(); ~Universidade(); voidsetNome(char*n); char*getNome();voidsetDepartamento(Departamento dep); }; #endif #include "Universidade.h" #include <stdio.h> Universidade::Universidade() { //Dpto.setNome("Teste"); } Universidade::~Universidade() { }
char*Universidade::getNome() {
returnnome; }
voidUniversidade::setNome(char*n) {
strcpy(nome,n); }
voidUniversidade::setDepartamento(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 Depto 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.getNome(), nome);
}
41
Exercício 3
UML / C++
Exercício 3
• Fazer com que uma Universidade possa ter até
50 Departamentos, tendo pelos menos um.
• Fazer com que um Departamento referencie a
Universidade
a qual está filiada.
• Criar
mais
Departamentos
filiando-os
as
Universidades...
43
Em termos de análise, é uma compisção (ou agregação-forte) porque assim o é no sistema real considerado. 1 1..50 Departamento -id: int -nome: char[100] <<create>>+Departamento(i: int) <<destroy>>+Departamento() +getId(): int
+setNome(n: char*): void +getNome(): char* Universidade -nome: char[30] <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char*
+setDepartamento(pdeo: Departamento*, ctd: int)
Modelo em UML - Projeto
Departamento -id: int -nome: char[100] -pUniv: Universidade* <<create>>+Departamento(i: int) <<destroy>>+Departamento() +getId(): int+setNome(n: char*): void +getNome(): char*
+setUniv(pu: Universidade*): void Em termos de projeto,
é uma agregagação-simples porque será implementada via ponteiros. 1 1..50 Universidade -nome: char[30] -pdpto: Departamento*[50] <<create>>+Universidade() <<destroy>>+Universidade() +setNome(char* n): void +getNome(): char*
45
Solução para Exercício 1
#ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento.h" class Universidade { private: char nome [ 130 ];
Departamento* pDptos [ 50 ];
public: Universidade ( ); ~Universidade ( );void setNome ( char* n ); char* getNome ( );
void setDepartamento ( Departamento* pdep, int ctd ); };
Solução para Exercício 1
#ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento.h" class Universidade { private: char nome [ 130 ];Departamento* pDptos [ 50 ];
public: Universidade ( ); ~Universidade ( );void setNome ( char* n ); char* getNome ( );
void setDepartamento ( Departamento* pdep, int ctd ); };
#endif
Um
problema
desta
implementação é que o número
de departamentos é fixo, o que
pode gerar desperdício ou
sub-dimensionamento.
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,,
47
#include "stdafx.h"
#include "Universidade.h" Universidade::Universidade ( ) {
for ( int i = 0 ; i < 50; i++) { pDptos [ i ] = NULL; } } Universidade::~Universidade ( ) { } char* Universidade::getNome ( ) { return nome; }
void Universidade::setNome ( char* n ) {
strcpy ( nome, n ); }
void Universidade::setDepartamento ( Departamento* pdep , int ctd ) {
pDptos [ ctd ] = pdep; }
Solução para Exercício 1
#ifndef _UNIVERSIDADE_H_ #define _UNIVERSIDADE_H_ #include "Departamento.h" class Universidade { private: char nome [ 130 ];Departamento* pDptos [ 50 ];
public: Universidade ( ); ~Universidade ( );void setNome ( char* n ); char* getNome ( );
void setDepartamento ( Departamento* pdep, int ctd );
void imprimeDptos ( ) ;
}; #endif
49
#include "stdafx.h"
#include "Universidade.h"
Universidade::Universidade ( ) { for ( int i = 0 ; i < 50; i++) { pDptos [ i ] = NULL; } }
Universidade::~Universidade ( ) { }
char* Universidade::getNome ( ){ return nome;
}
void Universidade::setNome ( char* n ) { strcpy ( nome, n ); }
void Universidade::setDepartamento ( Departamento* pdep , int ctd ){ pDptos [ ctd ] = pdep;
}
void Universidade::imprimeDptos ( ) { Departamento* pDep = NULL; for ( int i = 0 ; i < 50; i++) {
pDep = pDptos [ i ]; if ( pDep != NULL )
cout << pDep->getNome() << endl; }
#include "stdafx.h"
#include "Universidade.h"
Universidade::Universidade ( ) { for ( int i = 0 ; i < 50; i++) { pDptos [ i ] = NULL; } }
Universidade::~Universidade ( ) { }
char* Universidade::getNome ( ){ return nome;
}
void Universidade::setNome ( char* n ) { strcpy ( nome, n ); }
void Universidade::setDepartamento ( Departamento* pdep , int ctd ){ pDptos [ ctd ] = pdep;
}
void Universidade::imprimeDptos ( ) { // versão 2 // Departamento* pDep = NULL;
for ( int i = 0 ; i < 50; i++) { pDep = pDptos [ i ];
if ( pDptos [ i ] != NULL ) // ( pDep != NULL ) cout << pDptos[ i ]->getNome() << endl; }
51
#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 ModaUFTPR, TecnologiaUTFPR, DAELN, FisicaPrinceton, MatematicaCambridge; int diaAtual, mesAtual, anoAtual;
public: Principal ( ); void Executar ( ); . . . }; #endif
#include "stdafx.h“ #include "Principal.h" Principal::Principal ( ) {
. . . // leitura da dat 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.setNome ( "Universidade Tecnologica Federal do Paraná"); Princeton.setNome ( "University of Princeton" );
Cambridge.setNome ( "University of Cambridge" ); // Registro do(s) nome(s) do(s) departamento(s) ModaUFTPR.setNome ( "Moda" );
TecnologiaUTFPR.setNome ( "Tecnologia da UTFPR" ); DAELN.setNome ( "Eletronica da UTFPR" );
FisicaPrinceton.setNome ( "Fisica de Princenton" );
MatematicaCambridge.setNome ( "Matematica de Cambridge" ); // "Agregação" do(s) Departamento(s) a(s) Univesidade(s). UTFPR.setDepartamento ( &DAELN, 0 ); UTFPR.setDepartamento ( &ModaUTFPR, 1 ); UTFPR.setDepartamento ( &TecnologiaUTFPR, 2 ); Princeton.setDepartamento ( &FisicaPrinceton, 0 ); Cambridge.setDepartamento ( &MatematicaCambridge, 0 ); } void Principal::Executar ( ) { // Cálculo da idade.
Christiano.Calc_Idade ( diaAtual, mesAtual, anoAtual ); Diego.Calc_Idade ( diaAtual, mesAtual, anoAtual ); Simao.Calc_Idade ( diaAtual, mesAtual, anoAtual ); Einstein.Calc_Idade ( diaAtual, mesAtual, anoAtual ); Newton.Calc_Idade ( diaAtual, mesAtual, anoAtual ); printf ("\n"); // "Filiação" a universidade. Christiano.setUnivFiliado ( &UTFPR ); Diego.setUnivFiliado ( &UTFPR ); Simao.setUnivFiliado ( &UTFPR ); Einstein.setUnivFiliado ( &Princeton ); Newton.setUnivFiliado ( &Cambridge ); printf ("\n"); // "Filiação" ao departamento. Christiano.setDepartamento ( &ModaUFTPR ); Diego.setDepartamento ( &TecnologiaUTFPR ); Simao.setDepartamento ( &DAELN ); Einstein.setDepartamento ( &FisicaPrinceton ); Newton.setDepartamento ( &MatematicaCambridge ); printf ("\n");
// Universidade que a Pessoa trabalha. Christiano.OndeTrabalho ( );
Diego.OndeTrabalho ( ); Simao.OndeTrabalho ( ); Einstein.OndeTrabalho ( );
Newton.OndeTrabalho ( ); printf("\n"); // Departamento que a Pessoa trabalha. Christiano.QualDepartamentoTrabalho ( ); Diego.QualDepartamentoTrabalho ( ); Simao.QualDepartamentoTrabalho ( ); Einstein.QualDepartamentoTrabalho ( ); Newton.QualDepartamentoTrabalho ( );
53
Falta Ainda
• Fazer com que uma Universidade possa ter até 50 Departamentos
.
• Fazer com que um Departamento referencie a
Universidade
a qual está filiado
#ifndef _UNIVERSIDADE_H_
#define _UNIVERSIDADE_H_
#include "Departamento.h"
class
Universidade
{
. . .
};
#endif
#ifndef _DEPARTAMENTO_H_
#define _DEPARTAMENTO_H_
class Universidade;
class
Departamento
{
…
};
#endif
#include <string.h>
#include "Departamento.h“
#include "Universidade.h"
Departamento
::
Departamento
( )
{
}
Departamento
::~
Departamento
( )
{
}
…
#include "Universidade.h"
#include <stdio.h>
Universidade
::
Universidade
( )
{
}
Universidade
::~
Universidade
( )
{
}
...
Universidade.h
Universidade.cpp
Departamento.h
Departamento.cpp
55
#include "stdafx.h“ #include "Principal.h" Principal::Principal ( ){
. . . // leitura da dat 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.setNome ( "Universidade Tecnologica Federal do Paraná"); Princeton.setNome ( "University of Princeton" );
Cambridge.setNome ( "University of Cambridge" ); // Registro do(s) nome(s) do(s) departamento(s) ModaUFTPR.setNome ( "Moda" );
TecnologiaUTFPR.setNome ( "Tecnologia da UTFPR" ); DAELN.setNome ( "Eletronica da UTFPR" );
FisicaPrinceton.setNome ( "Fisica de Princenton" );
MatematicaCambridge.setNome ( "Matematica de Cambridge" ); // "Agregação" do(s) Departamento(s) a(s) Univesidade(s). UTFPR.setDepartamento ( &DAELN, 0 ); UTFPR.setDepartamento ( &ModaUTFPR, 1 ); UTFPR.setDepartamento ( &TecnologiaUTFPR, 2 ); Princeton.setDepartamento ( &FisicaPrinceton, 0 ); Cambridge.setDepartamento ( &MatematicaCambridge, 0 ); DAELN.setUniversidade ( &UTFPR ); .... } void Principal::Executar ( ) { // Cálculo da idade.
Christiano.Calc_Idade ( diaAtual, mesAtual, anoAtual ); Diego.Calc_Idade ( diaAtual, mesAtual, anoAtual ); Simao.Calc_Idade ( diaAtual, mesAtual, anoAtual ); Einstein.Calc_Idade ( diaAtual, mesAtual, anoAtual ); Newton.Calc_Idade ( diaAtual, mesAtual, anoAtual ); printf ("\n"); // "Filiação" a universidade. Christiano.setUnivFiliado ( &UTFPR ); Diego.setUnivFiliado ( &UTFPR ); Simao.setUnivFiliado ( &UTFPR ); Einstein.setUnivFiliado ( &Princeton ); Newton.setUnivFiliado ( &Cambridge ); printf ("\n"); // "Filiação" ao departamento. Christiano.setDepartamento ( &ModaUFTPR ); Diego.setDepartamento ( &TecnologiaUTFPR ); Simao.setDepartamento ( &DAELN ); Einstein.setDepartamento ( &FisicaPrinceton ); Newton.setDepartamento ( &MatematicaCambridge ); printf ("\n");
// Universidade que a Pessoa trabalha. Christiano.OndeTrabalho ( );
Diego.OndeTrabalho ( ); Simao.OndeTrabalho ( ); Einstein.OndeTrabalho ( );
Newton.OndeTrabalho ( ); printf("\n"); // Departamento que a Pessoa trabalha. Christiano.QualDepartamentoTrabalho ( ); Diego.QualDepartamentoTrabalho ( ); Simao.QualDepartamentoTrabalho ( ); Einstein.QualDepartamentoTrabalho ( ); Newton.QualDepartamentoTrabalho ( ); }