Pessoal, boa noite.
Estamos aqui em Curitiba no dia
11 de julho de 2020.
Grupo de Slides número 5,
continuamos falando de listas
relações via ponteiros e,
ademais, agora alocação dinâmica.
Vamos pro slide 2 desse Grupo de Slides.
Aqui eu tô retomando um exercício que a gente já fez na aula passada
e, inclusive, tinha uma incongruência no final
que eu pedi pra vocês investigarem.
Vamos relembrar rapidamente o exercício aqui, tá.
Sem muito delongas.
Cada objeto oriundo da classe Disciplina poderá ter um
número determinado de objetos Alunos relacionados.
De uma classe Aluno, portanto.
Este número será determinado no construtor da classe,
cujo 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.
Ali tem um item que está riscado, mas que, eventualmente, até poderia ser feito.
Que é: Os objetos Aluno serão registrados em ordem alfabética
em objetos Disciplina relacionados.
Por fim. Alunos poderão ser incluídos e excluídos das listas das Disciplinas, tá.
Inclusive, essa parte aqui de exclusão a gente não tinha feito em solução anterior.
Dessa vez a gente vai dar um jeito de excluir
e, aqui, não vai ser excluir um específico,
mas vai ser excluir todos, tá.
O que atendo ao requisito do exercício.
Ali tinha a Análise, né.
Associação; Você tinha a Disciplina... classe Disciplina, a classe Aluno.
Você colocou que a Disciplina é cursada por um ou mais Alunos
e cada Aluno cursa uma ou mais Disciplinas, tá.
Um analista, então, que olhou isso resolveu
que essa associação era uma boa coisa pra resolver a relação dada.
Associação é uma boa coisa pra resolver a relação dada, insisto.
Outro analista pode ter outra opinião.
Achar que isso é uma agregação-fraca.
Aonde a Disciplina teria um ou vários Alunos
e Aluno pertenceria, em alguma medida, a uma ou mais Disciplinas, tá.
Vejam que aqui é uma agregação-fraca já na Análise.
Se ela é na Análise, aí não tem escolha, ela também vai ser no Projeto.
Isso significa que, na prática,
eu faça assim ou faça assado, eu vou cair em ponteiros.
Então, as vezes você já começa a fazer a implementação, vai ser ponteiro de qualquer forma,
e essa discussão aqui, no final das contas, ela é importante,
mas ela é mais do ponto de vista do modelo, né,
do que do ponto de vista de implementação, tá.
Você pode criar uma equivalência,
usando aqui para tal o artifício da Realização.
Como você tá na Análise, não tem um projeto, realizando algo na Análise
essa Realização significa uma equivalência nesse sentido.
Aqui, inclusive, é um pontilhado, tá, aliás, um tracejado.
Ele saiu contínuo aqui, mas por erro de impressão, aqui, do slide.
Nesse slide, eu tô dizendo, basicamente, aqui, tá,
através de um artifício um pouco extraordinário
estou dizendo dizendo isso é equivalente aquilo em alguma medida
e daqui a pouco a gente vai decidir como faz.
Bom, depois de implementar um pouquinho, prototipar um pouquinho,
pode ser que os desenvolvedores chegam a compreensão,
na verdade, é uma associação, inclusive, direcional.
A Disciplina cursa um ou mais Alunos,
e o Aluno cursa uma ou mais Disciplinas. Sem ter ponteiro pro Aluno.
Ah, não, professor, não gostei dessa solução.
Então, a gente pode melhorar, tá.
Pode vir aqui e transformar direcional, ou seja, seta pros dois lados
ou simplesmente não ter seta nenhuma, o que significa que aqui é bidirecional.
Então, a gente vai ter usar algum estratagema aqui,
pro Aluno conhecer suas Disciplinas, ter uma lista de Disciplinas ali, né.
Através também de um Vector, um List,
ou quiçá ele implementar sua própria lista encadeada de Disciplinas.
Tal qual Disciplina, agora, está sendo implementada
com a sua lista encadeada intrínseca em si.
Ali, incrustada nela
e usando pra isso uma técnica de encadeamento de lista encadeada.
Muito bem, aqui a gente já está, então,
saindo da Análise e indo pro Projeto.
No Projeto a gente vai dizer que
isso vai ser implementado, justamente, via uma lista encadeada, só que duplamente encadeada
e não simplesmente encadeada.
Já aparece pProx e pAnt, lá, ó. Conhecido de vocês.
Vejam que ele está público, isso é heresia.
Aqui tem um número de Alunos
cont_alunos que são públicos isso também é heresia.
Vocês vão ver que na implementação eu já privei algumas coisas aqui, tá.
É necessário voltar aqui no Projeto e corrigir, daí.
Colocar um menos e colocar um menos aqui.
Se o ambiente estivesse integrado de
modelagem e implementação ele já ia fazer a correção automática.
Bem entendido.
Aqui, por ora, tá público mesmo na implementação.
Depois é exercício de vocês vir ali e privar essas coisas, deixar menos aqui,
e criar os respectivos gets e sets aqui, tá.
Tem que ter um setProx, ou pProx, um getPProx,
setPAnte e getPAnt, b em entendido.
Muito bem, aqui é pra implementação que vocês já viram, tá,
na aula passada, ali, na apresentação passada, exposição passada
e hoje eu só tô revisando aqui com vocês.
Cada objeto oriundo da classe Disciplina poderá ter um número determinado
de objetos Alunos relacionados.
Então, quais itens estão relacionados com isso?
O pPrim e o pAtual estão relacionados, porque eles vão permitir montar a lista encadeada.
Aqui tem um número que eu estou dando, tá, que é um número determinado.
Esse número será determinado no construtor da classe
cujo valor padrão, default, será 45.
Tá ali, né.
Se eu não colocar nada lá, não colocar parâmetros aqui na construtora, tá,
Ele vai assumir o 45.
Muito bem.
Agora, se eu colocar aqui, sei lá eu, na Disciplina lá, 30 Alunos
Área de conhecimento Computação,
Aí, o valor que eu colocar, acho que eu disse 30 agora há pouco, mas finge que seja 30.
O valor que eu colocar lá, enfim.
As referências, endereços, dos objetos Aluno
serão armazenados em uma lista duplamente encadeada em cada objeto Disciplina.
Pra isso eu tô usando uma lista encadeada, tá.
Para tal, a Disciplina tem ali, um pPrimeiro e pAtual.
Bom o nome certo é pAlunoPrim e pAlunoAtual, ambos ponteiros de Aluno,
mas eu, aqui no meu discurso, vou chamar de pPrimeiro e pAtual pra facilitar
o encadeamento da fala.
Aqui, eu tenho em Depar... perdão, em Aluno, derivado de Pessoa, inclusive,
eu tenho o pProximo e o pAnterior, ambos ponteiros de Aluno.
Muito bem. É isso que vai permitir a gente animar a lista encadeada, né,
e também essas funções aqui, tá.
O IncluaAluno e o listeAlunos1, por assim dizer, e 2 da classe Disciplina.
Bom, se a gente tá vendo aí o Disciplina.h,
é natural que a gente veja também o Disciplina.cpp.
Esse aqui é o .h, né. Disciplina.h. Vamos ver o Disciplina.cpp.
Bom, aqui o Disciplina aterra uma série de ponteiros, né,
que foram usados em exercícios anteriores e também em exercícios atuais, tá.
No atual é pertinente isso aqui, ó.
pAlunoPrim e pAlunoAtual, tá.
Vejam que essa quantidade de ponteiros aqui,
muito embora, a gente sabe do que se trata,
porque a gente fez o código, a gente resolveu os exercícios, tá.
Pra alguém de fora pode começar a soar um pouco grego.
Depois a gente vai ver maneiras de atenuar um pouco esse tipo de situação aqui, tá.
Mas deixa aí por enquanto e a gente vai melhorar isso daqui a pouco.
Legal.
Vejam a destrutora. A destrutora também tem aterros de ponteiros.
Aqui nós temos o incluaAluno de Disciplina.
Vai testar se o contador de Alunos,
um atributo nosso que é inicializado como zero na construtora,
ver se ele é menor que 45
por exemplo, se for o número de Alunos 45.
A gente também testa se o ponteiro não é nulo, tá.
Ninguém quer incluir um ponteiro nulo, bem entendido.
Bom, se ele passar nesse primeiro nível de decisão, aqui, né, de análise,
vai pro segundo.
Ver se é o primeiro cara incluído na lista ou não.
Se for, portanto o pPrimeiro vai ser nulo daí dentro da Disciplina, da construção
ele vem aqui e faz com que o pPrimeiro e o pAtual aponte pro cara que tá sendo inserido.
Se não ele faz as amarrações de próximo e de anterior
e atualização de pAlunoAtual, conforme vocês já viram na aula passada.
Aqui ele incrementa o contador.
Aqui tem a listagem do início até o fim, através do próximo, próximo, próximo.
Aqui tem listeAlunos2 que faz a listagem do fim pro início
através de pAtual, ou seja, o último, né, e anterior, anterior, anterior
e assim por diante até chegar no início da lista.
Muito bem.
É isso que nos interessa aqui, aqui já são funções conhecidas de vocês, tá.
Quem que tá elaborando o código, fazendo a sua versão do Sistema Acadêmico
Olha pra isso aqui e já sabe de cor e salteado do que se trata.
Aqui eu tô apenas destacando as funções de Disciplina.cpp.
As funções-membro que interessam pra nós nesse momento, tá.
Essas funções aqui a gente vai acabar simulando inevitavelmente.
Coisa que vocês já devem ter feito em casa,
porque eu pedi no final da última exposição.
Vamos pra classe Principal. A classe Principal agora tá muito mais bem organizada, né.
O Principal não tem aquele código espaguete
ele tá dividido em subfunções.
O Executar também não tem código espaguete
tá bem dividido em subfunções com nomes apropriados.
Inicializa nossas Universidades, nossos Departamentos, nossos Professores, nossas Disciplinas
nossos alunos e aqui nossos inteiros que é diaAtual, mesAtual e anoAtual, conforme já sabido.
A gente vai destacar algumas coisas aqui na nossa Principal.cpp, tá.
A gente já viu a Principal.cpp na íntegra na aula passada, aqui eu tô destacando o que interessa.
Tem momento aí que a gente, no InicializaDisciplinas, né.
Lembrar que você criou o ObjetoPrincipal
que fez o objetoPrincipal chamou a sua construtora, em algum momento.
A sua construtora chama a vários inicializas, inevitavelmente,
inclusive o InicializaDisciplinas.
E aqui a gente coloca nome em cada uma das Disciplinas, faz a Disciplina conhecer o seu Departamento.
Aqui, nessa versão, não foi chamado de DAELN, foi chamado de
EletronicaUTFPR, por algum motivo, tá.
A gente pode até atualizar isso aqui rapidamente.
Até é legal, porque permite a gente lembrar que é nesse momento aqui
que a Disciplina vai conhecer o seu Departamento.
Professor, eu posso fazer as Disciplinas conhecer outros Departamentos? Claro que pode.
Por exemplo, se tiver uma, sei lá eu, Técnicas de Programação, lá,
e você tiver um Departamento DAINF
você faz um procedimento parecido aqui, tá. Só que em vez
de ser DAELN aqui onde que eu tô lendo, aqui,
ele vai ser DAINF, obviamente.
Bom, o fato aqui, gente,
é que aqui eu tô fazendo o Computacao1_2006 conhecer o DAELN,
enfim, todas as Disciplinas conhecerem o DAELN
e, implicitamente, conforme vocês já viram na aula passada
o Departamento também vai conhecer essas Disciplinas montando sua lista encadeada.
E aqui eu tô fazendo mais uma coisa.
Tô fazendo o Metodos2_2007 incluir os Alunos.
Então, tá aqui ó, tô incluindo os 5 alunos, tá.
Aqui também tem os algoritmos pertinentes, tá.
Como a ListeAlunosDisc que faz parte da Principal
e aqui tem o Executar, inclusive, que chama ali, ó, o ListeAlunosDisc,
mas, bom, vamos focar aqui nessa inclusão.
Inclusive, eu peço que vocês façam a simulação.
Pra quem já viu essa simulação vai seguir o meu discurso, aqui, tá.
Pra quem não fez essa simulação ainda, ora, segunda chance,
vai e faz a simulação, primeiro porque é importante pra você entender o processo.
Não é isso?
Bom, pessoal, continuando aqui supondo que vocês já fizeram a simulação.
O que ocorre?
eu vou fazer a simulação agora pra vocês, tá,
vocês confrontarem com o que vocês fizeram, inclusive.
Obviamente que eu vou destacar esse momento do código que é o InicializaDisciplinas.
Por quê? Porque é ali que eu incluo as Disciplinas.
Inclusive, eu acabei avançando alguns slides pra frente, eu acho.
Deixa eu verificar. Sim, avancei.
Então, me permitam voltar um instantinho aqui.
Slide 13,
Aqui eu peço pra que vocês façam a simulação. Vamos lá.
Então, eu tô nesse momento do código ali, que é o InicializaDisciplinas,
agora, já no slide 14, tá.
No InicializaDisciplinas, você faz uma série de coisas pertinentes a Disciplinas e,
inclusive, a inclusão dos Alunos nas Disciplinas ,
nesse caso, tem uma Disciplina só que é o Metodos2_2007,
e a gente vai incluir os alunos que eu vou chamar aqui de
triplo A, triplo B, triplo C, triplo D e triplo E.
Óbvio que é o endereço deles, né, bem entendido.
Então, vamos lá. Vamos executar o incluaAluno de Metodos2_2007.
Ele vai chamar o incluaAluno. Ele vai testar o primeiro if, tá.
Contador tem 0 pela construtora.
Tá em 45, pelo valor default.
Isso aqui a gente sabe que ele é diferente de nulo, porque se você olhar ali, tá,
o ponteiro de Aluno tá apontando pro endereço de triplo A.
Tá ali, ó.
É a variável temporária, parâmetro, né.
Apontando pra quem é do direito que, aqui, no caso, é o endereço do triplo A.
Ele vai passar no primeiro if. Vai passar no segundo.
Como ele passa o segundo if também,
o pAlunoPrim e o pAlunoAtual vão apontar pro mesmo lugar que é ponteiro Aluno.
E tá ali, tá. Assunto conhecido.
Agora a gente vai inserir o triplo B. Ele vai passar no primeiro if,
mas não vai passar no segundo, então vai cair no else do segundo if,
e fazer as amarrações de próximo, de anterior e de atualização de atual.
Sem mistério.
Daí, ele incrementa o contador, tá.
Contador passa pra... começou em 0, tá... passou em 1 e agora tá em 2.
Então, vai virar pra 2 agora, justamente, nessa execução, aqui, tá. Neste momento.
Legal.
Aí ele retorna a execução da função e vai incluir o triplo C.
Tô pedindo pra vocês continuarem a simulação.
Vocês sabem o resultado que vai dar isso aqui.
Inclusive, faltou tela aqui, tá, mas ele continua lá.
Como vocês já sabem aqui eu tô terminando a execução
Muito bem.
Aqui eu entro num segundo momento. Até aqui não tem problema nenhum, tá.
Não tem problema nenhum nessa solução dada,
porque, muito embora, o relacionamento de Disciplina para com Aluno seja uma relação n pra n,
aonde a Disciplina pode ter vários Alunos e os Alunos podem estar em várias Disciplinas,
ou estarem incluídos, né, estarem relacionados, perdão, com várias Disciplinas,
aqui a gente só testou isso num quadro 1 pra n.
O relacionamento tem potencialidade de n pra n, mas aqui foi 1 pra n.
Só tem um Metodos2_2007 que tá aqui
relacionado com 5 alunos e esses 5 alunos só estão matriculados nessa Disciplina.
Só estão incluídos nessa disciplina.
Vamos exercitar uma outra situação que é essa posta aqui no slide 27.
Que é agora pra uma segunda Disciplina.
Aonde você vai ter alunos que estão na primeira Disciplina e na segunda.
Como o triplo A aqui, por exemplo, e o triplo C.
E aqui a gente já cai em um momento n pra n.
Nessa situação n pra n, a gente aplicou a mesma solução de
composição de lista encadeada que a gente tinha aplicado naquela problema 1 pra n da aula anterior.
Na aula anterior, nós tínhamos essa situação aqui, ó,
de Disciplina conhecer o DAELN e o DAELN já incluir as Disciplinas,
mas vocês tem que lembrar que as Disciplinas vão estar em só um Departamento
e o Departamento vai ter várias Disciplinas, então, isso aqui é um contexto de um relacionamento de 1 pra n.
E aqui é n pra n.
A gente aplicou, nesse contexto, a mesma solução que a gente tinha utilizado lá.
Será que funciona? Vamos ver.