Aqui nós temos um exercício 3,
aonde a gente começa a melhorar, inclusive, um dos nossos requisitos, tá.
Olhe só.
Em Diagrama de Classes da UML e depois em C++
Fazer com que uma Universidade possa ter até 50 Departamentos,
tendo pelo menos um.
Fazer que cada Departamento referencie a Universidade
a qual está filiada.
Criar mais Departamentos filiando-os às Universidades
O que eu aconselho pra vocês, nesse primeiro momento,
é também fazer uma pausa no vídeo
e tentarem fazer esse exercício,
tanto do ponto de vista de modelagem,
quanto do ponto de vista de implementação.
Particularmente, essa parte que tá em vermelho aqui.
Essa parte que não está avermelhada
vocês podem deixar para a sequência.
Bom, pessoal, então eu suponho que vocês já tenham feito
a versão de vocês do exercício,
eu passo aqui em ato contínuo pra fazer a minha versão.
Começando com esse tópico aí que é: Fazer com que
uma Universidade possa ter até 50 Departamentos,
tendo pelo menos um.
Vamos lá.
Tá aí em termos de Análise.
Se eu olhar, Universidade vai se compôr de 1 a 50 Departamentos.
Ela tem um número fixo de Departamentos.
Por que que a agregação é direcional?
Ora, porque depois se a gente voltar aqui um pouquinho, inclusive, no enunciado.
Os Departamentos vão conhecer Universidade também.
Então, é uma agregação, digamos assim, entre aspas, consciente.
Na prática, o Departamento vai ter um ponteiro pra Universidade em algum momento.
Em termos de Análise, é uma composição
Vamos melhorar a palavra, ali, ó, na... na anotação aqui.
Em termos de Análise, é uma composição, ou agregação-forte,
porque assim o é no sistema real considerado.
Tá ok.
De fato a Universidade tem lá uma quantia de Departamentos.
Só que eu resolvi implementar,
agora já em termos de Projeto, a coisa como um...
vetor de 50 ponteiros Departamento.
Então se eu olhar assim, tecnicamente falando,
eu não tenho ali os 50,
ou até 50 Departamentos,
os 50 Departamentos, os Departamentos alocados ali
dentro da minha Universidade,
mesmo porque pode variar de 1 a 50, né.
Então, tecnicamente é mais inteligente utilizar ali, um ponteiro,
porque imagine que a minha Universidade tenha 10 Departamentos,
nesse âmbito dado é mais... menos custoso
você ter 40 Departamentos, daí, com nulo, né,
aterrados, apontamentos aterrados,
do que você ter 40 objetos
inutilizados de Departamento dentro de Universidade.
Como, tecnicamente falando,
você não tem os objetos aqui dentro,
você tem apontamentos de objeto.
Uma interpretação possível é essa.
Em termos de projeto, é uma agregação-simples,
porque será implementada via ponteiros.
Claro que isso é uma interpretação.
Você também pode, se você definir com a sua equipe
e dizer olha, negativo.
Se aqui na Análise é agregação-forte,
por mais que eu opte, por motivos técnicos,
usar ponteiros, eu continuo usando agregação-forte aqui
e vai ser uma agregação-forte implementada via ponteiros.
Isso é possível.
É uma interpretação também correta.
O importante é que você mantenha a coerência,
com relação à sua interpretação
junto com a sua equipe.
O fato é que em termos de código
o que vai acontecer é isso aqui.
50... perdão, 50 pDptos.
50 ponteiros Departamento.
Então, pDptos é um vetor...
vetor de 50 ponteiros Departamento.
Aqui eu tenho setDepartamento().
Veja que setDepartamento() recebe
o endereço de Departamento e também o índice aonde
esse endereço vai ser registrado no endereço lá em questão.
Vamos lá.
Aqui inclusive eu tô destacando a coisa, tá.
Um problema dessa implementação é...
Destacando e fazendo uma observação.
Um problema desta implementação
é que o número de Departamentos é fixo,
o que pode gerar desperdício ou sub-dimensionamento.
De fato, tá.
Se eu tiver, sei lá... por mais que....
Estruturando melhor o meu discurso.
Por mais que isso seja melhor,
essa implementação por ponteiros seja melhor,
porque tem um vetor de
de fato 50 Departamentos
que é um vetor de 50 ponteiros Departamento.
Assim, se eu tiver uma Universidade com 10 Departamentos apenas, aí apontados,
eu vou ter 40 apontamentos inutilizados.
O que é menos grave do que eu ter
40 objetos de Departamento inutilizados.
Do ponto de vista de aproveitamento de memória e afins.
Ainda sim, mesmo usando ponteiros,
Eu teria 40 ponteiros de Departamento inutilizados, lá, aterrados com nulo,
nesse quadro de uma Universidade ter 10 Departamentos.
Outra questão é que se eu tiver uma
aí, uma Universidade com 51 Departamentos, por exemplo,
essa solução já não comporta.
Aí vem a segunda parto de comentário.
Há soluções para isso,
como o uso de lista encadeada
ou o uso de alocação dinâmica de vetor com expansão,
desalocação e nova alocação, quando se fizer necessário.
Bom, vocês já trabalharam lá
com malloc, com free,
em linguagem C, então vocês sabem que eu posso
alocar um vetor dinamicamente, tá,
e desalocar dinamicamente.
Isso não é novidade pra vocês.
Inclusive, um exercício aqui, cabível,
é refazer essa solução, em vez de usar um vetor fixo,
usar um vetor alocado dinamicamente.
Ele que pode ter... ser alocado com um valor dado
e depois quando estourar o valor dado, quando encher o
o valor dado, você pode alocar mais, né,
à luz dos artifícios aí de malloc,
free, realloc e afins.
Muito bem.
Isso considerado,
sabendo essa limitação da solução, vamos ainda sim avançar
um pouquinho mais com a solução que é a solução dada
e atenda os requisitos, bem entendido.
A gente tá criticando a solução, mas a solução atende os requisitos, tá.
A gente pode ir lá, inclusive, e criticar os requisitos também.
Dizer que o requisito tem que mudar pra ser de 1 a n e não de 1 a 50.
Daí a gente vem aqui e melhora também
a solução decorrente dos requisitos.
Legal.
Considerando então, essa solução dada aqui,
de 50 ponteiros de Departamento.
Uma coisa importante é
já que tem apontamentos, esses apontamentos tem que estar aterrados, tá.
Todo ponteiro que uma...
que existe em um código, uma classe, onde for tem que tá aterrado.
É o que eu faço aqui na construtora, inclusive, de Universidade.
Vamos ver lá.
Todos os elementos são aterrados, tá vendo ó?
Lá no setDepartamento() eu recebo
um Departamento, um endereço,
e armazeno em que posição do vetor?
Na posição que me for informada.
Aqui ainda, na classe Universidade
eu criei uma funçãozinha a mais, chamada imprimeDptos().
Pra mostrar, né, pra testar
se os Departamentos foram de fato incluídos dentro
de cada Universidade em um momento dado.
Muito bem.
Aqui, então, eu tô mostrando o código de Universidade.cpp.
Aqui é a Universidade.h e aqui é a Universidade.cpp.
Tá lá os aterramentos feitos na construtora.
A destrutora vazia, getNome(), setNome(),
Universidade, setDepartamento() a gente já viu.
E aqui é o imprimeDptos(), tá.
Eu crio um ponteiro auxiliar pdep.
que é aterrado com NULL, ponteiro Departamento, bem entendido.
aqui eu tenho um for variando em i,
bem entendido,
de 0 até i menor que 50,
incrementado de 1 em 1, i++, né.
Aqui eu recupero a partir
de cada posição do vetor
eu recupero ali no ponteiro intermediário...
perdão, no ponteiro temporário.
Testo se o apontamento que tá vindo lá não é nulo,
se não for nulo eu imprimo a partir desse apontamento
o nome da coisa apontada.
Vocês tem que lembrar que dentro
do vetor vai ter uma série de Departamentos apontados,
que eu tô recuperando ponteiro a ponteiro no loop
nesse ponteiro temporário.
E a partir, então, desse ponteiro temporário,
que vai tá apontando pra algo se ele não for nulo,
eu recupero o nome do cara apontado.
Obviamente, tá, que isso aqui é um código bem pedagógico
a gente pode fazer uma coisa bem mais direta e pragmática
que é essa segunda versão aqui.
Também funcionaria, tá.
Acessar diretamente o vetor, lá.
Sem problema nenhum, funciona tal qual.
Muito bem.
Agora no Principal, você tem aqui
Pessoas criadas, tá.
Aqui é nome de Alunos como o qual a gente fez juntos em sala.
Tem lá o Cristiano, o Diego, o Simao, o Einstein, o Newton.
Aqui temos Universidades, tá, UTFPR, Princeton, Cambridge.
Alguns departamentos a mais que a gente criou ModaUTFPR,
TecnologiaUTFPR, DAELN, FisicaPrinceton, MatematicaCambridge.
Isso significa que lá na versão de vocês, tá,
do Sistema Acadêmico de vocês, vocês podem criar mais Pessoas,
mais Professores conforme vocês quiserem pra animar
essa situação, aí, desse exercício dado.
Aqui foi o que eu fiz.
Aqui temos mais códigos que está escondido, né.
Tá aqui a Principal.
Principal aqui é a construtora.
Construtora já tá ficando grandinha.
Vejam que eu tenho varias coisas que acontecem aqui na construtora.
Tem a leitura da data atual.
Pode ser via lá, time.h, windows.h.
Aqui tá inicializando cada uma das Pessoas.
Inicializando o nome das Pessoas, aliás, das Universidades.
Colocando o nome dos Departamentos.
Relacionando... ah, sim, e aqui é a parte importante do exercício.
Fazendo com que cada Departamento
conheça o conjunto de...
perdão, fazer com que cada Universidade conheça
outro conjunto de Departamentos, tá aqui, ó.
O endereço DAELN vai ser armazenado na posição 0
do ponteiro de... do vetor de ponteiros de Departamentos dentro da Universidade UTFPR.
Já ModaUTFPR, vai ser apontado na posição 1.
TecnologiaUTFPR na posição 2, e assim vai, tá.
Como se eu tivesse mais Departamentos aqui.
No caso do Princeton e do Cambridge, cada qual só vai ter um
Departamento apontado
colocado na posição 0 do vetor, na primeira posição do vetor portanto, tá.
Provavelmente aqui tem mais código, tá, que tá em reticências aqui
além de leitura da data atual.
Muito bem.
Inclusive de coisas que a gente já tinha trabalhado na...
no passado aí, tá, nas versões passadas.
Deixar aqui a reticências pra lembrar disso.
Só pra que a coisa fique inequívoca.
Muito bem.
Voltemos aqui.
Aqui tá o Executar().
Calc_Idade de cada Pessoa.
Ah, sim.
Aqui eu tô fazendo as associações dentro do Executar(), tá.
Isso aqui não é muito perfeito não, tá.
Esses caras ficariam melhor
lá na construtora, aliás, eles deveriam estar lá na construtora.
Inclusive vamos fazer esse ajuste aqui, tá.
Pra fins de perfeccionismo.
Relacionamentos entre objetos, tá.
Eles tem que ser feitos antes das execuções.
Esse código até funcionaria, por causa da posição que ele está, tá.
Mas seria muito mais correto
colocar esses caras na função...
então, nossa função construtora
ela começa aqui
e ela vai terminar
aqui.
Vou destacar em vermelho ali, pra eu não ter
dúvidas a respeito.
Pois bem.
Então na construtora tá acontecendo tudo que deveria acontecer, tá pessoal.
Leitura da data atual.
Inicialização dos objetos da classe Pessoa.
Coloca nome nas Universidades.
Coloca nome nos Departamentos.
Faz cada Universidade agregar
o seu Departamento através do artifício de apontamentos.
Inclusive aqui, no caso, é vetor de ponteiros.
Coloco... associo a cada Pessoa uma Universidade.
E ainda filio cada Pessoa a um Departamento.
E depois eu venho fazer a execução propriamente dita, tá,
agora tá certinho, que é o cálculo da idade das Pessoas,
que é só mostrar aonde trabalha em...
enquanto Universidade e aonde trabalha enquanto Departamento.
E tá aí resolvido o exercício, agora com o código
bem mais organizado conforme vocês tão vendo agora aí em tela.
Inclusive, eu posso voltar isso aqui pro modo apresentação agora.
Começa lá a construtora e termina ali.
Legal.
Na prática a gente fez o que tá em minúsculo aqui, ó.
Fazer com que a Universidade possa ter até 50 Departamentos
Criar mais Departamentos filiando-os às Universidades.
Isso foi cumprido.
O que não foi cumprido
e fica pra vocês fazerem
aí como exercício
lá no Sistema Acadêmico que vocês tão elaborando
cada qual com o seu
é o seguinte, fazer com que um Departamento
referencie a Universidade a qual está filiado.
Na prática, o que vai acontecer é que é necessário
que o Departamento tenha um ponteiro pra Universidade,
ele tem que apontar pra Universidade que ele está filiado,
que ele pertence na prática, tá.
Muito bem.
Aqui tem uma observação técnica
muito importante, eu gostaria que vocês prestassem muita atenção
inclusive, porque é o último slide dessa...
penúltimo slide, perdão, dessa exposição.
Quando vocês criaram o vetor
de ponteiros Departamento dentro da classe Universidade,
você fizeram o include de Departamento.h.
Isso é natural, né.
Vocês foram lá, se vocês voltarem aqui o...
um pouquinho os slides, tá, me permitam voltar
Cadê a classe Universidade? Tá ali, ó.
Universidade tem um vetor de ponteiros Departamento.
Ora, se eu vou usar Departamento, eu incluo Departamento.
#include "Departamento.h"
Bem entendido.
Bom, mas tem uma peculiaridade.
Aqui a classe Universidade incluiu o Departamento.h.
Se Universidade incluiu o Departamento.h,
se Universidade.h incluir o Departamento.h,
eu não posso fazer a recíproca.
Eu não posso que Departamento.h inclua Universidade.h.
Dá erro.
Dá os chamados includes recursivos lá do C++.
Novamente, se A incluiu B, B não pode incluir A.
Se Universidade incluiu Departamento,
o Departamento não pode incluir Universidade.
E, nesse caso, pra você escapar dessa situação de bloqueio,
você tem que usar o artifício ali posto.
Que artifício é esse?
Vejam a Universidade já incluiu o Departamento.
Assim, o Departamento não pode incluir a Universidade no .h.
Portanto, é feito o quê aqui no Departamento.h?
É redefinido a classe Universidade
class Universidade;
E no respectivo .cpp
eu faço a inclusão daí da Universidade
faço aí o hashtag né, o sustenido include (#include)
"Universidade.h".
Mais uma vez,
pra Universidade.h incluir o Departamento.h
o Departamento.h não pode fazer
o include da Universidade.h.
Aí, eu tenho que usar esse estratagema aqui.
Redefinir a classe aqui no .h,
e incluir no respectivo .cpp.
Isso contorna o problema.
A única restrição é que aqui no Departamento,
eu posso ter no máximo ponteiros de Universidade,
não posso vir a ter objetos de Universidade aqui
no Departamento.
Insisto, eu posso, no máximo, ter ponteiros aqui nesse âmbito de Universidade
no Departamento.
Se eu tentar criar aqui, dentro do Departamento,
mesmo que por brincadeira,
um objeto Universidade,
a Universidade U.
Ele dá erro.
Agora se eu fizer um pU, ponteiro Universidade,
e for um ponteiro Universidade, funciona.
Por questões técnicas.
Por ora, é isso que vocês tem que entender.
Tá, quando você usar esse artifício, ele resolve o problema dos includes recursivos
em contrapartida você consegue, no máximo, usar ponteiros aqui
no contexto do artifício dado.
Bom, depois que vocês usarem esse artifício,
vocês vão poder refazer, então, que o Departamento tenha aqui
um pU, um ponteiro Universidade.
Daí vai permitir vocês levarem
no final das contas, ou chegarem no final das contas,
a uma solução mais ou menos assim, tá.
Lá no código
vocês vão poder fazer ali o...
o DAELN, por exemplo, setUniversidade() o endereço da UTFPR.
Tá aqui a construtora da Principal.
Leitura data atual.
Inicialização das Pessoas.
As Universidades ganham nome.
Os Departamentos ganham nome.
Aqui eu faço as Universidades
conhecerem os seus Departamentos.
Olhe só, a UTFPR conhece o DAELN,
ModaUTFPR, TecnologiaUTFPR, cada qual
registrado em um dado índice do vetor
de ponteiros de Universidade.
Outramente dito
Cada Universidade conhece os seus Departamentos
e cada Departamento agora conhece a sua Universidade.
DAELN.setUniversidade().
Ora, se você vai ter um ponteiro de Universidade dentro da classe Departamento,
a classe Departamento vai ter que ter um setUniversidade(), né, naturalmente.
E aqui você vai colocar os demais códigos, similares a esse, né,
como, por exemplo,
FisicaPrinceton.setUniversidade()
recebendo o endereço de FisicaPrinceton.
Pessoal, foi uma aula também um pouquinho
mais longa, mas é que também, é uma série de conteúdos muito importantes
muito pertinentes, tá.
Eu prometo que as próximas aulas vão ser mais curtas, mais objetivas, tá,
mas aqui a gente cobriu um conjunto de
exercícios e de conceitos sobretudo
que são fundamentais, né.
A verdade é que também eu me alonguei em algumas explicações
pra que isso fique... pra que elas fiquem mais entendíveis, tá.
Espero que vocês tenham apreciado a aula.
Nos vemos nas aulas subsequentes, tá,
nas exposições subsequentes,
aonde a gente vai ver, daí, a parte B e C
desse Grupo de Slides número 3.
Até breve.