Os alunos no final desta aula deverão conhecer:
Deverão também ser capazes de:
Caso os alunos sintam que os objectivos não foram atingidos na totalidade deverão concluir/repetir os exercícios desta aula autonomamente e ou recorrer aos horários de dúvidas.
Os ficheiros relativos a esta aula estão disponíveis no arquivo Aula5.zip.
1. Na Aula prática 4 a implementação dos conceitos de lista e iterador foi alterada de modo a fazer uso de ponteiros. Os ponteiros foram usados, em particular, para guardar informação acerca dos elos anterior e seguinte de cada elo na cadeia duplamente ligada de elos que se usou para representar a lista.
No directório ~/POO/Aula5 encontrará os ficheiros fonte lista_de_aluno.H,
lista_de_aluno_impl.H e
lista_de_aluno.C,
do módulo físico lista_de_aluno (tal como foi desenvolvido na Aula
prática 4 embora adaptado para os itens serem da classe Aluno),
os ficheiros fonte aluno.H e aluno_impl.H
(que definem a classe Aluno), do módulo aluno, e o
ficheiro fonte ordena_alunos.C, de um módulo com o mesmo nome que
contém a função main() do programa.  Estes módulos fazem
parte de um programa que lê informação acerca de alguns alunos (nome e
número) e os escreve por ordem não-decrescente de número.
Juntamente com os ficheiros acima indicados encontrará um ficheiro de
construção de nome Makefile que pode ser usado para construir o
programa ordena_alunos.
Construa o ficheiro executável ordena_aluno  do programa usando o comando
make.  Execute-o.
1.a) Analise a implementação das listas e iteradores realizada na Aula prática 4 e pense nas alterações a realizar de modo a transferir a gestão (reserva e libertação) dos elos para os mecanismos de construção e destruição de variáveis dinâmicas disponibilizados pelo C++:
elos continua a ser necessária?  Porquê? 
    Quais as consequências da sua resposta para a representação da lista? 
    Onde se localizarão os elos necessários à lista?ListaDeAluno::reservaElo() e
    ListaDeAluno::libertaElo()? 
    Continuam a ser necessárias?  Porquê?ListaDeAluno::estaCheia()?  Será que o melhor
    é eliminá-la?  Ou a lista pode estar mesmo cheia?ListaDeAluno?1.b) Altere a implementação das listas e iteradores da Aula prática 4 de modo a transferir a gestão (reserva e libertação) dos elos para os mecanismos de construção e destruição de variáveis dinâmicas disponibilizados pelo C++:
listaDeAluno::reservaElo() e
listaDeAluno::libertaElo() deixam
de ser necessárias.  Elimine-os.primeiro_elo_livre
deixa de ser necessária.elos e da constante membro de classe numero_maximo_de_itens,
uma vez que deixa de haver um número máximo de itens pré-estabelecido.listaDeAluno::estaCheia().Elo. 
Esse construtor recebe como argumento um ponteiro para o elo anterior,
um ponteiro para o elo seguinte, e o valor do item a guardar nesse elo. 
Se cada um dos parâmetros do construtor tiver um valor por omissão
(os ponteiros o valor singular 0 e o item o valor por omissão dos
itens, ou seja, Item()), simplifica-se bastante a construção
de elos.listaDeAluno::reservaElo()
e listaDeAluno::libertaElo() pelos operadores new e delete. 
Faça uso do construtor definido para a estrutura Elo.1.c)  Recorde a implementação do método listaDeAluno::transfereDe()
realizada na Aula prática 4.  Use o cenário da
Figura
5.1 para descrever o seu funcionamento.
 
Figura 5.1
1.d) Use o cenário da Figura 5.2 para pensar numa implementação do referido método que tire partido da nova implementação das listas com elos dinâmicos.
 
Figura 5.2
1.e)  Re-implemente o método listaDeAluno::transfereDe() com as ideias
desenvolvidas.
2.a)  Altere a classe listaDeAluno (e iterador correspondente),
de modo a guardar ponteiros para aluno (Item passa a ser Aluno*). 
A classe deve passar a chamar-se ListaDePonteiroAluno.
2.b)  Altere o módulo físico ordena_alunos.C
de modo a que, usando duas listas de ponteiros para alunos, leia 5 alunos
do teclado e os guarde na memória livre, colocando ponteiros para
eles nas duas listas.  A primeira lista conterá os ponteiros
para os alunos por ordem crescente de nome.  A segunda conterá
ponteiros para os mesmos alunos mas por ordem crescente de número. 
No final os alunos deverão ser mostrados duas vezes: por ordem de
nome e por ordem de número.  
2.c) Quem se deverá encarregar de destruir os alunos* (que são variáveis dinâmicas)?
2.d) 
Que sentido têm as operações ListaDePonteiroAluno::primeiraOcorrenciaDe() e
ListaDePonteiroAluno::ultimaOcorrenciaDe()
quando os itens na lista são ponteiros?
* Salvo seja.
3. O operador de inserção de uma lista no canal recebe a lista por referência não constante. Altere de modo a que passe a receber a lista por referência constante. Recompile. A mensagem de erro surge porque não existem iteradores que garantam que não alteram os itens referenciados nem a lista associada. O objectivo deste exercício é construir um novo tipo de iteradores, os chamados iteradores constantes, que o garantam. Siga os passos abaixo:
listaDeAluno::IteradorConstante
igual à classe listaDeAluno::Iterador.  Não se
esqueça de definir os respectivos métodos!* para Item const&.  Alternativamente
Item (devolução por valor, menos eficiente).listaDeAluno const&.primeiro() pode alterar
a lista [indirectamente].listaDeAluno, listaDeAluno::Iterador e
listaDeAluno::IteradorConstante
formam um casamento a três...ListaAluno::primeiro(), etc. que devolvam um iterador
constante.ListaAluno::insereAntes() e ListaAluno::remove()
que recebam iteradores constantes.  Estas operações fazem sentido por,
apesar de os iteradores garantirem a não alteração das listas associadas, as
listas em si não serem constantes.  Pode-se dizer que a autorização de
mudança vem da lista e não do iterador, que se limita a indicar uma
posição.  É por causa destas novas operações que os iteradores
constantes, apesar de garantirem a constância dos itens referenciados, contêm
ponteiros para elos não constantes.* Na realidade não é claro que não altere os seus elos. O programador produtor se encarregará de garantir que tal não se passa.