Tá ali, pessoal, a função CadUniversidade.
Vamos nos concentrar nela. Esqueçam os outros códigos aqui pra baixo, por enquanto.
Quero que vocês se concentrem nesse quadro aqui, ó,
que eu tô circulando com o mouse.
Tô criando um vetorzinho de caractere nomeUniversidade.
150 caracteres. Parece ser suficiente.
Posso aumentar pra 1500 se eu quiser, tá.
Nada obsta.
puniv. puniv é um ponteiro de Universidade aterrado com nulo.
Aqui eu pergunto pro usuário qual é o nome da Universidade que ele quer cadastrar.
Sei lá, ele pode colocar lá, então, aqui, através do cin:
"Universidade Estadual de Ponta Grossa".
Ou se ele quiser ele pode usar a sigla lá, "UEPG".
Aqui eu vou criar um novo objeto de Universidade agora dinamicamente.
O objeto não tem nome interno.
Não tem nome do ponto de vista mnemônico interno.
Ele tem apenas um apontamento temporário, aqui, inclusive, chamado puniv.
Através desse apontamento eu vou colocar um valor dentro do atributo nome.
O atributo nome dele é o... ou seja, é um conjunto de caracteres, né,
que existe dentro dele. Não é um mnemônico dentro do sistema.
Por exemplo, a UTFPR é um objeto criado estaticamente
dentro do sistema.
A UTFPR é do tipo Universidade.
Então, eu tenho um mnemônico interno, porque ele é criado estaticamente.
Quem é criado estaticamente tem um mnemônico.
Tem um nome internamente, por assim dizer.
Aí, na UTFPR, ele pode fazer lá
UTFPR.setNome e passar "Universidade Tecnológica Federal do Paraná".
Porque daí você lê o conteúdo que vai tá dentro do atributo nome
do objeto UTFPR que tem esse mnemônico interno UTFPR.
Isso dito, tá.
Basicamente o que eu fiz aqui, voltando no meu ponto,
é criar dinamicamente a Universidade e colocar um valor dentro do atributo nome dela,
através desse ponteiro temporário puniv.
Professor, mas se é ponteiro temporário
então ele vai sumir com a... depois da execução da função.
Vai.
Como é que eu vou acessar daí, essa Universidade que eu criei dinamicamente?
Cujo nome interno lá, é o nome que o senhor deu aí,
sei lá, UEPG, USP o que for.
Bom, justamente por isso que eu pego esse endereço,
isso aqui foi criado dinamicamente, isso aqui tem um endereço.
Esse endereço tá, por ora, armazenado aqui.
Vou pegar esse endereço e ele vai armazenar
dentro de ListaUniversidades
Veja que ele não armazena, obviamente, o puniv.
Ele armazena o endereço que está dentro de puniv nesse momento.
Aí ele vai ficar armazenado, vai ficar nos encadeamentos lá.
A partir de pPrimeiro, pProximo, próximo, próximo, tá,
que eu consigo navegar e encontrar ele através dos encadeamentos.
Pra isso que ser a lista encadeada, inclusive.
E aí, depois que eu já utilizei o endereço de armazenamento de puniv,
depois que já seguirei ele, né,
mantive dentro da ListaUniversidades,
depois esse ponteiro pode sumir no final dessa execução aqui.
Bom, se vocês viram o CadUniversidade, vamos ver agora o CadDepartamento.
Ah, o CadDepartamento também é interessante.
É interessante pelo seguinte.
Você tem ali uma variável temporária
o nomeUniversidade e nomeDepartamento, vetores de caractere.
Dois ponteiros aqui, puniv e o pdepart.
Professor, não tá aterrado com nulo. Aterrem por gentileza, aí.
Daí, vejam que interessante.
Pra eu criar só um Departamento
eu tenho que saber em qual Universidade ele está.
Então, eu pergunto pro usuário qual é o nome da Universidade
e leio aqui o nome da Universidade.
Daí, eu fiz o quê?
Eu tenho que saber qual é a Universidade pra poder amarrar o Departamento na Universidade.
Poder jogar esse Departamento na ListaDepartamentos da Universidade, na prática.
Bom, e isso tá feito aonde?
Isso tá feito aqui, ó.
Eu fui na própria ListaUniversidades, lá na classe...
Bom, LUniversidades, que existe no Principal, é do tipo ListaUniversidades conforme vocês já viram.
Lá, eu tive que criar, pra resolver esse exercício,
eu criar uma função a mais, chamada localizar.
Que recebe um vetor de caracteres,
que é o nome da Universidade, e tenta buscar essa Universidade
através do nome na função localizar.
Se ele encontrar, ele devolve o ponteiro da Universidade e se ele não encontrar ele devolve nulo.
Olhe lá, ó.
Então, aqui eu passei, sei lá... sei lá eu, por exemplo, passei aqui "UTFPR".
Ele vai pegar esse vetor de caracteres "UTFPR"
e vai utilizar pra fazer a busca.
Como ele faz a busca?
Cria o paux aqui que é ponteiro de ElUniversidade.
Pode aterrar com nulo se quiser,
mas logo em seguida eu já faço o paux apontar pro primeiro
Fazer um while, enquanto o paux não for nulo
Ele vai indo de próximo, próximo, próximo, em próximo.
Em cada passagem, eu testo se a Universidade
pra onde o paux tá apontando, tem o mesmo nome que o parâmetro dado.
Se tem, ele vai retornar 0 aqui, tá.
0 significa que... que deu boa nesse comando string copy
que é um comando que vem do string.h, naturalmente, conforme vocês já sabem.
Então, aqui, se ele encontrar, e se der ok:
Opa, igualzinho, UTFPR e UTFPR. Ele vai retornar aqui.
Aí, eu vou fazer o quê?
Vou retornar da função.
Retorna aqui da função. Vejam que interessante. Eu volto pra função aqui.
Já retorno o getUniversidade.
Vejam que o paux é ElUniversidade.
O paux tem a Universidade,
ele tem o apontamento próprio pra Universidade.
Então eu consigo, através do getUniversidade,
recuperar a Universidade com o qual esse...
ElUniversidade em questão, né,
no qual eu tô navegando, me retorna a Universidade.
Até explicando de uma maneira um pouco mais pragmática, tá.
O que acontece aqui é o seguinte, tá.
Eu tô navegando em Elementos de Universidade (ElUniversidade),
sendo que cada elemento cuida, obviamente, de uma Universidade na lista.
E aí, eu vou navegando de Elemento a Elemento.
Vocês vejam que eu não tô navegando dentro das Universidades,
eu tô navegando nos Elementos que cuidam delas na lista.
Compõe a lista encadeada portanto.
Ué, e como é que funciona o getNome?
Você tem que lembrar que dentro da classe ElUniversidade,
tal qual foi feito nas demais listas,
você vai ter no Elemento a capacidade de ele ir lá
na sua Universidade apontada
recuperar o nome e retornar aqui.
Então é por isso que funciona.
Professor, mas o senhor não tinha feito a classe ListaUniversidades.
Sim, isso aqui eu tô assumindo que vocês já fizeram a classe ListaUniversidades
no exercício que eu mandei, ali, ser feito anteriormente. Bem entendido.
O que eu tô mostrando aqui é a expansão da classe que vocês fizeram.
Uma vez que ele encontrou a sua Universidade,
ele vai através de ElUniversidade, dar um getUniversidade.
Aqui ele vai, basicamente, retornar um ponteiro da Universidade que ele tá cuidando.
Eu tendo o ponteiro Universidade aqui,
e ele é importante sendo diferente de nulo.
Aí sim, eu vou perguntar o nome do Departamento,
vou criar um novo Departamento em tempo de execução,
vou por um nome ao Departamento.
Faço o ponteiro apontar pra Universidade, ó.
Aquele exercício que a gente fez lá nos primeiros slides,
ou seja, faço o Departamento conhecer a Universidade
e aí, faço ademais, a inclusão do Departamento na lista de universidades.
Isso é bastante importante.
Você veja que isso aqui é a lista geral de Universidades, tá.
É a lista geral de Universidades. É a lista que tem dentro da Principal.
Então, é basicamente isso que tá acontecendo mesmo, tá.
Recuperei a Universidade; Aí, eu tenho a Universidade na qual eu quero cadastrar o Departamento.
E tá legal, porque se eu tenho a Universidade aqui, tá.
Então, eu consigo criar o meu Departamento.
Consigo criar o meu Departamento, pôr nome em Departamento,
fazer com que o Departamento conheça a sua Universidade.
E aí, obviamente, na lista geral de Departamentos na Principal,
eu incluo esse Departamento pra não perdê-lo, obviamente.
Bom, talvez, finalmente
enquanto em perfeição, tá.
Eu posso, dentro da classe Universidade, tá,
ter uma lista de Departamentos.
Que provavelmente já foi pedido em alguma solução anterior aqui.
Já tem ali, ó.
Cada Universidade tenha a sua lista de Departamentos, tá.
Tenha, inclusive, um incluaDepartamento.
Então, tá.
Então, aqui o que eu posso fazer, é o seguinte.
Cheguei aonde o meu cérebro tava cozinhando que eu poderia fazer uma pequena melhora.
E nesse quadro aqui, eu suponho que meu código vai ficar ainda mais completo.
Além de colocar o Departamento na lista geral de Departamentos da Principal,
eu também coloco o Departamento na ListaDepartamentos da Universidade em questão.
A Universidade recebe Departamento que vai, daí, repassar pra sua lista internamente.
Então, é até por isso que tá sublinhado, suponho.
Professor, o senhor não mostrou pra nós a função CadDisciplina.
Sim, essa eu quero que cês façam.
Ora, pro cadastrar da Disciplina
vocês vão ter que fazer o quê?
Vocês vão ter que localizar
a Universidade dessa Disciplina e o Departamento dessa Disciplina.
Então, vocês vão ter que fazer um estratagema de funções de localização
igual essa que eu fiz.
Muito legal.
E aqui, por fim, eu tenho um exercício derradeiro
que é o seguinte.
Para cada classe existente no sistema,
criar um atributo Id
que servirá para identificar de forma única um objeto.
Assim sendo, a cada objeto criado/instanciado,
atribuir um id único para ele.
É interessante que eu já, intuitivamente,
as vezes no modelo, né.
Eu já começava a colocar esse atributo Id, até como reflexo, tá.
Porque é muito usual a gente tê-lo.
Aqui, em todo o caso, eu tô explicitando
da forma de um requisito, né, de um exercício.
Daí justifica a sua existência dentro dos nossos modelos de código
Agora vocês têm que fazer, tá.
Claro que, veja só,
se você tem uma classe base Pessoa
e Professor e Aluno derivam dela, basta você colocar o Id como protegido,
dentro da Pessoa, tá. Isso provavelmente vai resolver a questão.
Elabore uma solução, ainda, que
permita registrar os objetos,
isto é, suas informações em arquivos,
de forma a recuperá-los em uma segunda execução do sistema.
Como o sistema tá agora, pessoal.
Como o sistema tá agora.
Vamos executar o sistema.
Deixa eu até fechar esse slide aqui.
Seis.
Aqui está.
Versão C.
Cadê o solution.
Bastante código aí, hein.
Tá pedindo pra eu converter, né. Vou converter.
Bom, vamos compilar, vamos ver aqui os códigos, tá.
Tá aí, ó. Todos os .h's que eu andei fazendo
todos os .cpp's que eu andei fazendo, tá.
Aonde que o main e o _tmain
vai tá aqui no ProjetoOOExemplo.
Joia.
Vamos fazer um "Recompilar Tudo",
porque não custa.
Praticamente a gente já fez aqui uma compilação,
no caso, pra garantir,
tá recompilando.
Aqui, enquanto compila,
vocês podem ver, por exemplo, a Principal.
É a Principal.h aqui, tá.
Com todos os elementos que a gente tem.
Veja que a gente tem... continua tendo os elementos estáticos como eu falei, tá.
Além dos dinâmicos.
Até se cê for na InicializaUniversidades
agora, vocês vão... perdão.
No Inicializa, por exemplo,
é Universidades, acho que é uma boa opção.
Cadê o Principal.cpp.
Olha o que eu tô fazendo, tá.
Eu, além de colocar nome nas Universidades,
agora eu tô colocando as Universidades estáticas
também na lista geral de Universidades.
Por quê? Porque elas fazem parte do sistema.
Foram criadas estaticamente, mas fazem parte do sistema.
Como se fossem Universidades pétreas, elas têm que existir no nosso sistema, tá.
Não faz a mínima importância. Princeton, Cambridge e UTFPR.
Elas tem que existir, porque elas foram criadas estaticamente.
Óbvio que isso aqui é um exemplo pedagógico, tá.
Pra mostrar que eu posso jogar na lista Universidades
criadas estaticamente e Universidades criadas dinamicamente.
Muito bem.
E se eu executar aqui?
Depurar.
Iniciar sem Depurar.
Ali, ó.
Então, eu posso executar, agora, inclusive aqui.
Vou listar as Universidades.
3.
Bom, aqui ele foi... tá com algum erro de pausa ali, tá.
Avançou muito rapidamente.
Vocês viram ali, ele pisca e some.
Não sei se é algum reflexo do teclado.
Inclusive, tá me dando um errinho aqui, vou ter que descobrir o que que é.
Acho que até sei do que que é, inclusive.
Vou dar um "Ignorar" nesse momento. Vou dar um "Abortar" e ele fechou.
Cadê a função de execução?
O MenuCad, o MenuExe.
Já que ele não tá parando,
eu vou colocar um getchar a mais aqui pra nós.
Ou até um system pause, se for o caso.
Recompilar tudo. Salvar.
Recompilar tudo.
Agora vamos executar.
Agora vamos ver se ele vai me obedecer.
Agora obedeceu.
As vezes acontece que o buffer do teclado tá com lixo.
Ele leu o caractere, no primeiro getchar tá vindo lixo,
apesar de eu ter feito um flush ali.
Tá, e aí, eu coloquei mais um getchar.
Mas tudo bem, tá aí.
Agora imaginem que eu quero cadastrar uma nova Universidade.
Perdão. Deixa eu fazer um 4 - Sair.
Eu tô fazendo um 4 - Sair.
Cadastrar. Cadastrar uma nova Universidade.
3.
Vou pôr aqui UEPG.
Tá ali.
Inclusive, ele não dá resposta nenhuma pro usuário, né.
Poderia falar "Universidade cadastrada com sucesso", tá.
Não tá aí, vamos dizer, a coisa mais bonita do ponto de vista da Interação Humano Computador.
Vocês podem melhorar isso. Espero que melhorem.
Executar.
Agora aparece UEPG.
Muito legal.
Se eu sair daqui, agora, do sistema.
4.
Daí Sair.
Continuou dando aquele errinho, já vou explicar do que se trata.
O que acontece se eu executar de volta agora?
Se eu executar de volta. Dou Executar.
Lista de Universidades.
Obviamente, a UEPG não tá mais aqui.
Não tá aqui, porque isso foi criado com alocação dinâmica, né.
E aí, se eu fiz new, eu tenho que fazer delete.
Mesmo que eu não tivesse feito delete no sistema,
ele ia continuar não apresentando aqui.
Porque se eu não fizesse delete,
aquela UEPG que eu tinha criado, em tempo de execução,
ela também vai ser memória perdida.
Minha lista de... minha lista encadeada ela sumiu
ela perdeu os encadeamentos.
Então, naturalmente, que eu não vou reencontrar aquela memória perdida.
Ele virou um zumbi.
Então, aqui eu teria que, além de ter um zumbi no sistema, teria que recadastrar aqui.
Mas é fato que eu tô fazendo um delete,
no final da minha lista de Universidades, tá.
Se for na classe ListaUniversidades
e olhar a destrutora dela, tem um delete lá.
Bom, aí nesse caso aqui, eu ia ter que me obrigar
a fazer um novo cadastro.
Justamente, aquele exercício que eu tava propondo pra vocês
é, por meio de arquivos, vocês
conseguirem gravar as informações que vocês criaram dinamicamente,
pra depois recriar automaticamente os objetos, tá.
Fazendo a chamada persistência de objetos no tempo.
Como os objetos são criados na memória RAM,
que é a memória volátil, quando eu fecho o programa
e fiz delete eu perco os objetos.
Se eu não fiz delete,
eu perco os objetos também e, ademais, fico com lixo de memória.
Muito bem.
Isso considerado,
através de arquivos,
porque tá pensando em memória não-volátil
eu consigo guardar as informações de objetos e depois recuperar, na próxima rodada,
fazendo a chamada persistência de objetos.
Coisa que é o que o último exercício tá propondo pra vocês, tá.
Vocês podem, se quiserem, pra fazer aquele exercício,
ler os capítulos de arquivos e persistência
lá do livro dos Deitel, por exemplo.
Ou vocês podem aguardar a minha próxima exposição,
aonde eu mostro como fazer uma persistência de objetos, tá,
mais por curiosidade pra vocês não ficarem com esse item a descobrir, tá.
É interessante ver como é fazer uma persistência de objetos.
Aqui, como eu dizia, tá, só pra finalizar sem deixar alastro.
Eu tenho a classe ListaUniversidades.
Tá ali, ó.
Bonitinha, tá. pPrim, pAtual. Tudo que é necessário.
Olha a destrutora ali, ó.
Ir para a Definição.
Aqui, ó.
Ele foi automaticamente pro .cpp pra mim, tá.
Artimanhas de... como diz?
De quem conhece o ambiente.
E aqui tá a função destrutora, tá.
Com os devidos delete's ali, tá.
Depois eu mudei, inclusive, aqui tô usando dois deletes.
a solução mais, mais
prolixa que eu tinha feito, depois eu mudei a solução que tava lá no slide.
Em todo o caso, ele faz o delete.
O que tá acontecendo aqui, pessoal, é que
essa lista tá misturando objetos estáticos e objetos dinâmicos.
Em versões anteriores do compilador,
ele não tinha problema nenhum em dar um delete em objeto estático.
Ele dava delete em objeto estático
e ele ignorava o delete.
Agora, aparentemente, ele tá reclamando em dar o delete em objeto estático.
Então, a gente tem que fazer alguma artimanha
pra testar se o objeto é estático ou não.
Dá pra colocar um flag lá na classe Universidade, por exemplo, pra dizer se ele é estático ou não.
E aí, alimentar esse flag conforme o contexto que ele for ser criado,
se é estático ou dinâmico.
Aí você só vai dar delete se ele for dinâmico, se ele não for estático.
Uma maneira de fazer.
Mas eu deixo vocês testarem isso, tá.
Pra verificar se de fato é esse erro nesse código,
mas muito provavelmente é isso mesmo.
Pessoal, espero que tenham gostado da aula.
Aqui eu vou salvar,
vou fechar
e deixo vocês fazerem as experimentações de vocês em casa.
Bom, bons estudos, aí.
Fiquem em casa nessa pandemia, não saiam, tá.
Não se coloquem em risco, não precisa.
Claro, só vai sair se for realmente necessário, né.
Precisa ir na farmácia, precisa ir no mercado.
Protejam vocês mesmos e suas famílias.
É isso que eu tinha pra contar pra vocês no dia de hoje
e vou sair ao encerrar a gravação.
Até a nossa próxima... próximo encontro.