Eu que não vou fazer pausa nenhuma,
vou continuar aqui em ato contínuo, tá.
Bom, o resultado da simulação vocês já sabem, tá.
Então, eu não preciso nem mostrar aqui.
Agora eu vou propor um segundo exercício
que é fazer com que a lista em questão
que é a lista de Disciplinas em Departamento
seja, não mais, simplesmente encadeada,
mas duplamente encadeada.
Como é que uma lista pode ser duplamente encadeada, gente?
Em termos de modelo, aqui, de Projeto.
Agora, em vez de ter pProximo, eu vou ter pAnterior
Se ela aponta só pro próximo, ela é simplesmente encadeada.
Se cada Disciplina consegue apontar pro próximo e pro anterior,
ela pode ser duplamente encadeada.
Daí ela vai ser duplamente encadeada.
Então, o que mudou é aqui, tá. Aliás, aqui.
Agora, eu criei um novo... um novo ponteiro aqui, o pAnterior.
Implementação via uma lista duplamente encadeada
baseada em ponteiros: pDisciplPrim e pDisciplAtual de Departamento
Isso já tinha, não mudou em nada.
E pProximo e pAnterior da Disciplina.
O pProximo já tinha e o que foi acrescentado aqui é o pAnterior
pra que seja duplamente encadeada e não simplesmente encadeada.
Duplamente encadeada, insisto.
O que muda em termos de código?
pAnterior, ponteiro Disciplina, pra que seja duplamente encadeada.
Observação: deveria ser privado, refazer.
Então, vocês vão colocar esses caras como privado, fazer os sets e gets e atualizar os códigos.
É um exercício, inclusive,
pra vocês, primeiro, entre aspas, se obrigarem a estudar o código
e segundo, colocando eles como privado você vai ter que mexer nos algoritmos,
se simpatizar melhor com os algoritmos, ali, até de maneira mais íntima.
Vai ter que entender eles no âmago, tá.
Legal.
O que vai mudar no Departamento.cpp?
Agora eu tô aterrando... tô aterrando quem eu já aterrava, na verdade.
Por primeiro pAtual isso não mudou.
O que vai mudar é que o else...
o else do IncluaDisciplina ele vai levar em consideração também o pAnterior.
Daí a gente vai simular isso aqui que fica mais fácil simulando, tá.
do que ficar fazendo um discurso aqui, estático.
Além do listeDisciplinas1 ou listeDisciplinas simplesmente,
que vai do primeiro para o próximo, para o próximo, para o próximo,
eu vou ter o listeDisciplinas2 que vem do atual, ou seja, do último
para o anterior, para o anterior, para o anterior.
Então, nesse caso, eu vou poder percorrer a lista do início pro fim e do fim pro início.
Legal.
Qual é a vantagem, professor, de ter duas navegações?
É que, imaginem o seguinte, tá. Imagine que você melhora esse algoritmo aqui.
Você melhora esse algoritmo aqui, pra fazer uma inclusão na lista
um pouco mais aprimorada.
A inclusão que a gente tá fazendo aí, gente, é uma inclusão bastante simplória.
No sentido que sempre tá incluindo no último elemento da lista.
Ele é quase, na prática, uma fila, no final das contas.
Mas você podia melhorar essa lista aqui, pra fazer uma inclusão um pouquinho mais inteligente.
Inclusão por ordem alfabética, por exemplo.
Aí, obviamente, você, a hora que recebia a Disciplina aqui você ia ter que ler o nome da Disciplina
Você ia ter que fazer um algoritmo de percorrimento da lista
pra localizar em qual posição o camarada estaria nessa lista
ordenada alfabeticamente.
Ia ter que fazer algumas astúcias mais audazes aqui,
um pouquinho mais avançadas para amarramento de pProximo, tá,
e, nesse caso, pAnterior também.
Então, teria algumas astúcias aqui,
e também alguma reflexão melhor sobre pAtual, né.
Você só ia atualizar o pAtual no caso se a inclusão
resultasse na ordem alfabética no último elemento.
No caso, se você tem uma ordenação, aqui, de ordem alfabética
que vocês podem fazer, nada obsta, como exercício se assim quiserem, tá.
Inclusive, apoiado em conteúdos que vocês tiveram ou venham ter
lá de Estrutura de Dados, tá.
Isso dá mais significado pro uso de lista duplamente encadeada.
Imaginem que você vai querer buscar um nome,
você vai buscar um nome, por exemplo, que começa com Z.
Vou colocar aqui Zenildo.
Se você for buscar o Zenildo, nessa lista encadeada
como você sabe que ela tá ordenada alfabeticamente,
é melhor buscar usando uma abordagem de início pro fim, ou de fim pro início?
Bom, obviamente, se ela tiver
se vocês fizeram, aqui, uma melhoria do algoritmo pra incluir alfabeticamente,
seria melhor fazer a busca do Zenildo, então,
do fim pro início.
Supondo que você quer recuperar, né. Aqui eu tô só listando, tá.
Suponham que você quer recuperar esse elemento
pra dar algum tratamento pra ele no teu sistema.
Mas, enfim, isso aqui é só pra contextualizar melhor esse exemplo
que pode ser bastante útil pra vocês em outros momentos, aí,
da formação de vocês e, particularmente, da atuação profissional.
Legal.
Então, foi isso que modificou aqui, tá, em termos de Departamento.cpp.
Alguma mudança aqui nesse âmbito, concretamente falando
e esse listeDisciplinas2, aqui, concretamente falando.
E no Disciplina.cpp o que mudou?
Agora, além de aterrar pProx, agora sim,
eu também aterro pAnterior.
Tanto na construtora, quanto na destrutora.
Tá ali pAnterior, então.
Aqui não mudou nada. A gente continua usando aquela abordagem
de o Departamento conhecer
perdão, da Disciplina já conhecer o Departamento.
Disciplina já conhecer o Departamento e, logo em seguida,
o Departamento já conhecer a Disciplina através do this.
E vamos fazer uma simulação.
Inclusive, eu nem preciso fazer essa simulação, tá.
Agora, vocês podem fazer a simulação de vocês,
olhando os códigos que já tem disponível.
Aqui tá o momento de execução do código.
Tô fazendo Computacao1_2006 conhecer o DAELN.
Tá ali, ó.
Vou fazer com que o DAELN seja conhecido no âmbito de Disciplina,
pegando o endereço de DAELN que tá vindo por parâmetro,
daí armazenando no pDeptoAssociado.
Coisa que vocês já conhecem.
Agora eu vou fazer o DAELN incluir a Disciplina esta, this.
Que é quem nesse caso? Computacao1_2006.
Tá ali, ó.
No DAELN, o Departamento DAELN,
pDisciplPrim é nulo nesse momento? É.
Então, eu vou fazer pPrimeiro e pAtual apontar pra ponteiro de Disciplina.
Que é quem o ponteiro Disciplina?
Obviamente é o Computação 2006 que é o que tá em execução nesse momento,
ou quem gerou a execução.
E aqui eu tenho o empilhamento de chamadas de função.
Legal.
Agora, então, eu vou fazer as conexões ali.
Se ele executou o if, ele não executa o else.
Eu vou desempilhar essa chamada.
E vou desempilhar outra chamada também
eliminando qualquer variável temporária aqui, incluindo os parâmetros.
Legal.
Tá ali a conexão feita.
Neste caso, pessoal, vejam que não tem a atualização de pProximo nem pAnterior.
Ah, por quê? Porque é só um cara que foi incluído.
Se foi... só foi um cara incluído não tem pProximo e não tem pAnterior.
Muito bem.
Agora eu vou incluir o Introdução...
aliás, agora eu vou fazer o Introd_Alg_2007 conhecer o DAELN.
Naturalmente.
Tá ali,
e ele, através do pdpto,
armazenou o endereço que tá vindo do DAELN via pdpto no Departamento...
pDeptoAssociado da Disciplina em questão.
Agora, eu vou fazer o DAELN incluir a Disciplina em questão
que é a Introd_Alg_2007.
Empilhamento de chamada de funções aqui.
pDisciplPrim em DAELN é nulo?
Não, não é, ele já aponta pra alguém. Então eu cai no else.
No else, vou fazer o quê?
Vou fazer o pDisciplAtual,
quem que é pDisciplAtual? Computação 2006,
apontar pro ponteiro Disciplina.
Quem que é o ponteiro Disciplina? É o cara que tá vindo.
Natural, né, eu vou fazer esse cara apontar pra quem tá sendo incluído.
Tá ali, ó.
Olha que interessante.
pDisciplina quem que é?
É Introd_Alg_2007.
Ah, tá. Então, Introd_Alg_2007
no seu anterior vai apontar pra pDisciplAtual.
Quem que é pDisciplAtual? É esse cara aqui.
Ah, então o anterior vai apontar pra aquele cara ali, ó.
Muito bem.
Tá apontado.
E agora eu vou fazer o quê? Vou atualizar, naturalmente, o atual.
Porque o atual aqui foi incluído por último.
Vou fazer aqui a finalização do incluaDisciplina.
Eliminando qualquer variável temporária, nesse caso, só tem a...
o parâmetro como variável temporária, se eu não me equivoco, é isso.
Vou desempilhar essa função, vou eliminar...
vou desempilhar outra função também
que elimina parâmetros temporários que, nesse caso, é o parâmetro dado.
E você pode continuar a simulação. E você já sabe o resultado.
Então, você pode continuar pra exercitar melhor
essa questão aqui, além de conectar com próximo
também vai conectar com o anterior.
Vai se conectar próximo e anterior, próximo e anterior.
Você vai ver que no último aqui, tá.
Ele não vai ter próximo, mas ele, sim, vai ter anterior.
Isso é interessante.
A execução final, aqui, ela é peculiar, tá.
Você vai ver que, de fato, ele conecta o próximo,
conecta o anterior, mas naturalmente não vai ter pProximo, porque não tem pProximo.
Muito bem.
Aí você pode continuar a simulação, tá.
Inclusive, você pode voltar, lá, um pouco,
nesse âmbito aqui, e também executar lá
aquela execução de trás pra frente.
Eu já simulei pra vocês lá, um pouco antes dessa exposição
a listagem indo do início pro fim.
Agora, faz do fim pro início.
Utilizando o pAtual do Departamento em questão, do DAELN
e o pAnterior de cada Disciplina.
Isso no âmbito aí dessa simulação, usando esse diagrama de cubos
que, na verdade, é um diagrama de objetos.
Aqui, eu tenho um Exercício 2, que é o seguinte.
Cada Objeto oriundo da Classe Disciplina
poderá ter um número determinado de objetos Alunos relacionados,
de uma classe Aluno.
Esse número será determinado no construtor da classe
cujo o valor padrão, default, será 45.
As referências, endereços, dos objetos Aluno
serão armazenados em uma lista duplamente encadeada
em cada objeto Disciplina.
Os objetos Aluno serão registrados
em ordem alfabética nos objetos Disciplina relacionados.
Bom, isso aqui, tá. Eu vou deixar aqui pra vocês, se vocês quiserem fazer isso aqui, tá.
Isso aqui eu não vou obrigar vocês fazerem, isso aqui só se...
realmente for... é optativo, tá.
Os alunos serão incluídos e excluídos da Disciplina... das listas de Disciplinas, tá.
Então, como isso aí ia ficar muito complexo,
vocês podem fazer, tá.
Eu gostaria que vocês fizessem, pelo menos, até essa parte aqui.
Não, necessariamente, vocês viram aí na... isso em Estrutura de Dados,
esse tipo de técnica, mas se você estiver estimulado você esse item ali.
Os demais estão certinho.
Legal. Avancemos nós.
Então, vamos tentar atender já nesses slides
esses requisitos aqui, pelo menos esses quatro,
salvo esse que tá rabiscado.
Tá aí uma... um Diagrama de Classes, tá.
A gente pode olhar a relação de Disciplina com Aluno e dizer o seguinte.
Na verdade, uma Disciplina ela vai ser... ela vai ter uma associação.
Se a gente olhar o mundo real é assim que a Disciplina se porta.
A Disciplina tem uma associação.
A Disciplina é cursada por um ou mais Alunos
e cada Aluno cursa uma ou mais Disciplinas.
Isso é um analista olhando.
Pode ser que eu tenha uma lista e fale: não, eu acho que a associação
na verdade, tá errada, eu acho que
cada Disciplina ela contém, ainda que fracamente,
ela contém Alunos.
E aí, ele vai dizer: então, eu vou modelar isso já em termos de Análise
como uma agregação-fraca.
O Aluno... a Disciplina tem o Aluno, em alguma medida, e o Aluno é contido
em uma ou mais Disciplinas.
É agregação-fraca e não forte.
Bom, e aí, as vezes tem situações que geram debate, tá.
Geram debate e tal,
e às vezes pra você não travar um debate
você pode usar uma artimanha, tá. Isso aqui é um pontilhado, tá.
Não sei porque motivo que ele tá colocando aí como
linha continuada, mas é um pontilhado.
Quando gera um debate assim,
vocês vão... primeiro que vocês já vão tá de acordo
que, na prática, vocês vão implementar isso daqui via ponteiros.
A implementação, seja de associação,
seja de agregação-fraca, nesse caso, vai ser a implementação, a mesma implementação.
Agora, conceitualmente, pode ficar o debate.
Então, se você quiser avançar na implementação antes de tomar a decisão
se vai ser Disciplina... se vai ser agregação-fraca nessa relação Disciplina com Aluno
ou se vai ser uma associação nomeada Cursar
Toda associação tem um verbo infinitivo, né.
Você pode colocar essa equivalência, tá.
Isso aqui é equivalência.
Isso é, na verdade, uma realização, mas como tá no mesmo âmbito aqui
a gente pode dizer que é uma equivalência.
Você diz: isso é equivalente àquilo, depois a gente vai chegar a uma conclusão.
Daí vocês fizeram os protótipos e tal
e chegaram a conclusão depois de implementar, realmente é uma associação.
Inclusive, nesse momento aqui, é uma associação direcional,
no sentido que vocês evoluíram o modelo, tá.
Vocês planejaram, inclusive, a chegar em termos de Projeto depois
e falaram não, é uma associação, inclusive, direcional.
Só a Disciplina que vai ter ponteiros pros Alunos em alguma medida
e o Aluno não vai ter ponteiro pra Disciplina.
Vocês chegaram a essa conclusão e criaram essa associação n pra n.
Prestem atenção nisso, n pra n.
Não é a mesma situação anterior, aonde era 1 pra n, n pra 1.
Lá o Departamento tem uma Disciplina
aliás o Departamento tem um conjunto de Disciplinas
e cada Disciplina está ligada apenas a um Departamento.
Relação 1 pra n, n pra 1.
Aqui, eu insisto, é n pra n.
Legal.
Bom, e aí, vocês naturalmente vão tentar fazer o exercício se inspirando
no que vocês já conhecem lá do exercício anterior.
Cada objeto oriundo da classe Disciplina
poderá ter um número determinado de objetos Alunos relacionados.
Bom, isso aqui foi um incremente que eu fiz com relação
ao exercício anterior, dizendo que cada Disciplina pode ter no máximo 45.
Então, eu criei aqui um número de alunos
e vejam que eu criei um na aqui, que tem o valor default 45.
ou seja, vou ter no máximo 45,
mas ele pode ter 30, ele pode ter, sei lá eu, 10.
Então, você pode especificar o valor aqui.
Muito bem.
Professor, mas aqui o senhor não estava... eu posso colocar um valor maior.
Posso colocar o valor 80.
Bom, aí você pode ter uma lógica interna pra não deixar passar de 45.
Mas o fato é que você pode pôr um valor aqui, nessa implementação dada,
e se você não colocar nada ele vai assumir o 45 pro valor default.
As referências, endereços, de objeto Aluno,
serão armazenadas em uma lista duplamente encadeada em cada objeto Disciplina.
Bom, aqui a tendência é o cara pensar o seguinte.
Bom, então, tá. Eu tenho ali a classe Disciplina
e aqui eu vou ter uma lista encadeada,
duplamente encadeada, de Alunos.
Então, é natural que eu tenha um pPrimeiro e um pAtual.
Um pAlunoPrimeiro e um pAlunoAtual ambos do tipo Aluno.
Aqui, eu posso fazer com que a Disciplina inclui o Aluno.h,
porque o Aluno.h não incluiu a Disciplina e, por enquanto, nem inclui.
E se for incluir, daí, se o Aluno for incluir Disciplina ele vai ter que usar aquele artifício.
de redefinir a classe no .h e incluir efetivamente no .cpp.
Isso é só uma observação à parte.
Ainda com relação à lista encadeada
vai ser necessário que o Aluno tenha um pProximo e um pAnterior
Tá ali, ó. pProximo e pAnterior, ponteiros de Aluno.
legal.
Esse número será determinado, o número 45 lá, né,
vai ser determinado no construtor da classe,
cujo valor padrão, default, será 45.
Legal. Muito bem.
Bom, aqui o que a pessoa tá fazendo é o seguinte
ela tá se inspirando na solução que ela já fez lá, que ela já viu entre Departamento e Disciplina,
pra também criar uma lista encadeada de Disciplina com relação a alunos.
A Disciplina vai ter uma lista encadeada de Alunos
aonde cada Aluno, aparentemente, participa da
composição da lista, conhecendo pProximo e pAnterior.
Aqui, eu tenho o aterramentos de ponteiros pertinentes à Disciplina.
Tenho, aqui, sets e gets da Disciplina.
setDepartamento e getDepartamento que é coisa de exercício anterior.
Códigos que, supostamente, vocês já estão simpatizando com.
E, aqui, eu vou ter a função, incluaDisciplina.
Eu vou ter as funções de listagem do início pro fim e do fim pro início.
Bom, aqui eu tenho um pouquinho mais de decisão.
Antes eu testo se minha contagem de Alunos, que começa em 0,
não tá maior que o número máximo de Alunos.
Faço um teste pra ver se o ponteiro que tá vindo não é nulo.
Bom teste, inclusive, pra ver se ele é diferente de nulo.
Se ele passar nesse primeiro teste
aí eu vou testar se o pAlunoPrimeiro é nulo
fazendo as amarrações de primeiro e, se não for, fazendo as amarrações
de pProximo e pAnterior e a atualização do atual.
Aqui, também, depois desse if-else,
eu tenho, aqui, o incremento da contagem de Alunos, né.
Cada vez que eu vou colocando um Aluno, eu vou incrementando.
Tem um else em relação ao primeiro if, que é "Aluno não incluído. Turma já lotada."
Eu podia até melhorar, né.
Fazer um teste, ver se
é porque tá lotado ou se é porque o ponteiro é nulo, tá.
Eu posso melhorar esse nível de informação pro usuário.
Aqui estão as listagens, tá. Nada de surpreendente.
No próximo slide, eu vou destacar essa função incluaAluno
e as funções de listagem só pra saber que essas funções que nos interessam nesse momento.
Agora, na função Principal, eu tô contando que eu incluí, aqui, Alunos, tá.
Bom, a gente sabe que
ainda teve mais Departamentos que eu andei criando também, tá.
Muito embora, não esteja mostrando aqui.
Por ali.
O que modificou foi que eu tenho, agora, Alunos também.
Eu tenho... já tinha Departamentos
Já tinha Universidades, já tinha Departamentos, já tinha
Professores, já tinha Disciplinas,
agora tenho Alunos, ademais.
Se você olhar agora, também, eu tenho uma funçãozinha
a mais chamada aqui, ó, lista Alunos por Disciplina.
Em algum lugar nessas funções aqui, eu vou
fazer com que a Disciplina conheça os Alunos.
A gente já vai descobrir aonde, sem muito mistério.
Tá aqui o InicializaDisciplinas.
Professor, o InicializaAlunos tá vazio.
Na verdade, os Alunos aqui eles podem ter códigos, tá.
Como, por exemplo, pra receber nomes, né.
Seria até razoável lá, tá. Fazer AAA,
que tá definido no meu slide anterior, inclusive. Lá, ó.
AAA.setNome, recebe um nome, sei lá eu, Simão.
Outro nome qualquer, "Simãozinho".
BBB.setNome recebe "Marcelo".
CCC.setNome recebe "Jean". E assim vai, tá.
Vai usar alguns nomes ali, só pra fins de exemplificação.
Legal.
Que é o que eu tava falando aqui, tá. Em termos de reticências.
Muito bem.
Dá um "Salvar", né, porque é importante.
Eu sempre levanto na página, tá.
A última versão, depois que eu faço, aqui, algumas correções em tempo de execução, tá.
Vocês já recebem os slides na página minha, com as correções feitas.
Aqui, pessoal, no InicializaDisciplinas. A Disciplina conhece... recebe nome.
Eu faço que a Disciplina conheça o Departamento.
e aí, internamento, o Departamento já vai incluir Disciplina.
Coisa que a gente simulou nos slides anteriores.
E agora, eu faço ademais, a inclusão dos Alunos da Disciplina.
Nesse caso, Metodos2_2007.
E aqui eu tenho as listagens.
Muito bem.
Isso aqui funciona uma beleza. Sem problema.
Mesmo porquê, até então, muito embora a relação seja 1 pra n,
muito embora a relação, perdão, seja n pra n.
Por enquanto eu só exercitei um pra n.
Só fiz uma Disciplina incluir várias... vários alunos
e esses Alunos tão incluídos só em uma Disciplina
Mas o que acontece se você fizer isso?
Você exercitar a relação n pra n?
Agora, eu fiz uma Disciplina incluir vários Alunos.
Uma segunda Disciplina conhecer... incluir outros Alunos.
Vejam que tem Alunos que tão incluídos nas duas Disciplinas.
Como o triplo A e o triplo E.
Isso dá problema.
Qual é o problema? Como resolver?
Pra você identificar o problema, a primeira coisa que eu indico é fazer uma solução...
fazer uma simulação.
Fazendo uma simulação, você vai identificar o problema
e depois você vai poder propor uma solução.
Por que não funciona?
Não funciona por uma questão matemática.
O relacionamento de Disciplinas com Alunos é n pra n.
Uma Disciplina pode ter vários Alunos e o Aluno pode tá em várias Disciplinas.
Diferente da relação de Departamento, lá, com Disciplina que era 1 pra n, n pra 1.
Bom, a dimensão matemática que interessa pra gente aqui.
Pessoal, estudem um pouco a situação. Reflitam um pouco sobre o que...
sobre essa situação de dimensão matemática,
porque que uma situação funciona num domínio e não funciona no outro.
E aí, a gente volta a discutir isso na próxima exposição.
Até breve e bons estudos pra vocês.