Pessoal, boa noite.
Hoje é o dia 21 de julho de 2020,
uma terça-feira, início de noite.
Estou aqui pra falar do Grupo de Slides número 10, parte A.
Nesse Grupo de Slides a gente vai falar micro-noção de evento,
ou de desenvolvimento orientado a eventos
e particularmente,
que, aí, é o foco principal da aula
gabaritos e templates.
Muito bem.
Avancemos.
Noção de evento,
Isso aqui é realmente só uma noção, tá,
do que seria uma programação orientada a evento,
trazendo, primeiramente, o conceito de estado de evento
isso é a comunicação entre objetos via evento.
Isso aqui acontece nesse momento,
porque um dia em alguma aula, muito tempo atrás
um aluno me perguntou
e a gente acabou montando esse material
e ele acabou ficando, tá.
Mas ele realmente é uma noção bastante...
Qual é o termo? Elementar.
E com bastante licença poética também.
Assim, de maneira bastante simplória,
a gente pode dizer que a gente tem um exemplo de evento.
Então, você tem ali um conjunto de opções
o usuário opta por algo,
que desencadeia, daí, um tratamento de eventos.
É justamente esse desencadear
e, particularmente, esse tratamento do desencadear
aonde que mora as peculiaridades da orientação a eventos.
Aqui, o desencadeamento é sempre primitivo, tá.
Ele vai entrar num switch-case e vai fazer a análise.
mas se eu tivesse numa interface gráfica,
com janelas, com botões,
aí, a coisa toma forma
e as noções de tratamento a eventos
começam ganhar, também, complexidade
nesse âmbito que eu tô descrevendo,
mas, enfim.
Aqui a pessoa, então, vai optar por uma opção,
e o que seria um evento.
A partir de uma opção dada, por exemplo,
Cadastro Departamento
que vem ser aqui o quê? A opção 2.
Esse evento de optar pela opção 2
dispara a execução do método em questão,
que o é o CadDepartamento.
O disparar desse método
promove a comunicação entre alguns objetos,
o que promove a alteração de estados
de outros objetos, tá.
Aqui, a comunicação
é no sentido de fazer com que eles se relacionem, né.
Se você olhar aqui,
querendo ou não eu vou criar algum relacionamento
em algum momento,
entre Departamento e Universidade.
Tá vendo, ó.
E assim, eu vou alterar o estado, também, do Departamento.
Porque antes o Departamento tava num estado aqui,
nesse momento de código que eu tô salientando com o mouse,
num momento de código em que ele não...
não conhecia Departamento nenhum,
agora ele passa a conhecer.
Se você olhar momentos anteriores do código
aqui também é uma mudança de estado, ó.
Antes ele não conhecia nome,
agora ele passa a conhecer.
Então ele tava num estado
de desconhecer, no sentido de não ter um nome internamente,
dentro de si, né,
um vetor de caracteres lá, ou coisa que o valha.
Agora ele passa a ter,
no momento anterior ainda,
o objeto Departamento nem existia,
então ele passa de um estado inexistente pra um estado de existente.
Enfim, aqui é só pra passar essa noção realmente breve de eventos, tá.
Saber que cada vez que você opta por alguma coisa,
você vai desencadear, na verdade,
um conjunto de ações,
que no caso da orientação a objetos, acaba incorrendo na...
na execução de métodos.
Cada execução de métodos insisto,
promove a comunicação
entre um conjunto de objetos,
Essa comunicação, essas iterações,
ou apenas interações
entre esses objetos,
acaba levando, ou promovendo,
a alteração de estado deles
e mesmo de outros objetos.
Então, isso aqui é só essa noção básica,
a gente vai retomar isso aqui depois em interface gráfica,
e aí, lá, vamos falar de eventos com mais calma,
tratar da coisa de maneira mais adequada.
Agora, a segunda parte que realmente é o foco
dessa exposição aqui, tá,
que é gabaritos ou templates.
Vamos começar retomando o conteúdo anterior.
Aqui tem um exercício, proposto em aula anterior, que é o seguinte:
Cada Disciplina deve ser capaz de armazenar uma lista de Alunos.
E a classe Aluno, entretanto,
não deverá possuir um ponteiro para o Próximo.
Isto deverá estar
em uma classe associada chamada ElAluno
relacionada a classe LAlunos.
Na verdade, aqui a classe ListaAlunos, né.
LAlunos provavelmente é o nome do objeto.
Não é isso?
Ainda que também nada obsta de eu chamar a classe,
se eu quiser assim,
aí eu vou ter que chamar o objeto outramente, bem entendido.
Mas tudo bem.
O fato é que eu tenho esse exercício aqui.
Mas a gente já resolveu esse exercício
tanto em termos de codificação,
quanto em termos de modelagem.
Inclusive, modelagem bem elaborada,
saindo da Análise e indo até o Projeto.
Projeto esse que depois acaba
desencadeando no código
à luz do que tá concebido no projeto.
Então, esse assunto tá bem tratado, tá. Tá bem descrito
Insisto, desde a Análise e Projeto até código.
Inclusive, Análise e Projeto foi exposição do Grupo de Slides anterior.
E aqui cabe uma reflexão, sabe.
Inclusive, lá na modelagem já,
vocês viram que a hora que a gente modelou
o relacionamento de Disciplina e Aluno
utilizando como meio
pra animar a relação entre eles,
a classe ListaAlunos, ElAluno,
Depois a gente evoluiu, num outro momento da modelagem,
aonde a gente tratou do relacionamento entre
Departamento e Disciplinas logo assim,
vamos supor que seja departamento de disciplinas,
daí a gente criou o ElDisciplina e a ListaDisciplinas
lá nesse momento de modelagem
tal qual também no momento de codificação,
Vocês percebem que tanto em modelagem quanto em codificação
as soluções são muito parecidas.
O que muda na verdade é só o cara que tá sendo tratado.
O que leva a reflexão dada aqui.
Essa solução de criar uma classe ElementoAlgo
cada vez que se faz necessário uma lista
em uma classe dada, parece uma solução inteligente
ou mesmo razoável?
Se a gente olhar só pro elemento de fato, tá.
Sem pensar na lista ainda, só no elemento.
Se eu tenho uma lista de Alunos eu tenho que criar um ElAluno,
com próximo e com anterior.
Se eu tenho uma lista de Disciplinas eu tenho que criar o ElDisciplina,
com próximo e anterior e tudo mais.
Se eu tenho uma classe, sei lá, uma lista de Universidades,
eu vou ter que ter um ElUniversidade
com próximo, anterior e etc.
Bom, não seria melhor uma classe Elemento genérica
para tratar isso?
Na verdade, a gente vai generalizar
tanto o elemento quanto a lista.
Muito que obviamente, tá,
a gente não vai precisar ficar criando
uma lista específica pra Alunos,
uma lista específica pra Disciplinas,
uma lista específica pra Universidade
no tocante a soluções que são genéricas,
nas situações que são genéricas.
Insisto, no tocante as soluções que são genéricas.
Se você olha a STL
a Standard Template Library, a biblioteca padrão de templates ou gabaritos,
ela já faz isso.
o List ou até o Vector,
que a gente já deu uma pinceladinha, lá, em aulas passadas,
ela permite você criar vectors ou listas
parametrizados com outra classe.
Então, se eu quero um List de Alunos,
eu vou lá criar um List parametrizado com Alunos, aliás, com Aluno ou algo assim.
Bom, o fato é que tal qual a STL,
baseada em Templates,
a gente consegue criar os nossos templates também,
de maneira tal que a gente consiga, então, fazer classes que são parametrizáveis,
Para não começar já generalizando direto a lista,
eu vou generalizar algo que é mais simples
que é justamente o que tá posto aí.
Tá aqui, inclusive, a classe Elemento template.
Bom, aqui eu coloquei aquele código de ifndef,
não tá aparecendo aqui mas aqui vai ter o endif, evidentemente,
em algum momento.
Inclusive, vai aparecer no slide subsequente.
Bom, tá o código aqui de pré-compilação
que já foi discutido, né, o motivo da existência dele.
Aqui tá o que interessa nesse momento.
Eu tô criando uma classe Elemento,
que não é uma classe usual
é uma classe template,
ela pode ser parametrizada com outro tipo.
com outra coisa que nesse caso é uma classe que, internamente, eu tô chamando de TIPO.
Eu podia chamar isso aqui de T por exemplo, podia chamar de TYPE.
Aqui, é como é que eu vou tratar a coisa
dentro da classe Elemento,
uma vez que essa classe seja parametrizada em uma dada instanciação.
Eu vou avançar um ou dois slides.
Talvez até um pouquinho mais.
Tá aqui, ó. Aqui eu tenho o ListaAlunos.
Aqui, eu já tô criando dentro do ListaAlunos,
que tem pElAlunoPrim e pElAlunoAtual
ponteiros pra apontar pro primeiro Aluno e pro Aluno atual ou último, né.
Porque agora eles não são mais da classe ElementoAluno
Eles são da classe Elemento parametrizada com Aluno
Olha, o segundo, também,
da classe Elemento parametrizada com a classe Aluno,
porque eu tenho uma classe parametrizada com outra.
que vai dizer como esses caras aqui vão se comportar.
Se eu olhar aqui essa Lista de Alunos
Vocês sabem que vai ter em algum momento aqui a função incluaAlunos.
Ela é a função inclua Alunos,
como todo mundo sabe,
que eu vou criar efetivamente o objeto,
de Elemento, agora parametrizado com Aluno
para tratar de Aluno na lista.
Vou avançar um pouquinho aqui.
Então, tá aqui, ó.
Lá eu recebi um Aluno por parâmetro na lista, né,
O endereço no Aluno,
Vou criar um paux
que é um ponteiro de Elemento parametrizado com Aluno.
Aqui eu vou, dinamicamente, criar um new Elemento,
parametrizado com Aluno
Então, aqui eu tô criando um objeto Elemento,
mas que precisa de uma parametrização pra funcionar
que é justamente, ora, o Aluno.
Apontado aqui por um ponteiro temporário, paux.
Aqui, tem uma arte, aqui,
que eu estou dentro do Elemento criado,
replicando o nome do Aluno que tá vindo
Isso aqui é uma réplica,
de uma informação do Aluno dentro do Elemento.
Depois a gente já vai discutir se isso é bom ou se é ruim, mas é isso que tá acontecendo.
E aqui que eu faço o Elemento paux, né,
parametrizado com Aluno,
conhecer o Aluno pra tratar dele.
Meu ponto aqui, tá,
nessa discussão toda, é isso aqui, ó.
É eu criar um novo Elemento agora parametrizado com Aluno,
não mais um novo Elemento Aluno.
Não é mais uma classe específica,
uma classe genérica
que é parametrizada com algo em tempo de criação
pra poder, daí, estanciar algum objeto efetivamente.
Claro que depois criado, aqui, o ElementoAluno, né,
temporariamente chamado de paux,
que eu vou entrar com os meus ifs pra decidir se é o primeiro,
ou se não é primeiro,
e aí, eu vou ter que fazer a amarração com próximo e com anterior e afins.
Legal.
Agora eu vou voltar um pouquinho lá na definição da classe novamente,
naquela que a gente tava.
Eu avancei slides pra frente, pra ficar entendível
porque que tem esse parâmetro aqui.
Ora, porque eu vou ter criar o Elemento parametrizado com algo,
Se eu quero um Elemento Aluno, parametrizo com a classe Aluno.
Se eu quero um Elemento Disciplina,
eu vou parametrizar com a Disciplina, e assim vai.
Aqui, internamente, pProximo e pAnterior
são ponteiros de Elemento parametrizados com o mesmo tipo que tá ali.
Se aqui for passado Aluno, aqui também vai ser Aluno e aqui também.
E que tipo de informação
ou de dados, se a gente quiser chamar assim,
esse elemento vai cuidar?
Ora, ele vai cuidar do ponteiro
do que tiver vindo por parâmetro.
Se for Aluno, então vai ser ponteiro de Aluno.
Claro, né, se eu crio um Elemento parametrizado com Aluno,
eu quero tratar com que tipo de informação?
Justamente de ponteiro de Aluno.
Vocês vejam que aqui, ó, eu coloco um asterisco na frente
desse parâmetro aqui, chamado TIPO,
que denota que eu vou tratar de ponteiro da coisa
e não da coisa.
Tem asterísco aqui, ó, bem entendido.
Tá joia?
Aqui tem a construtora e destrutora.
Tem o setProximo e o getProximo,
setAnterior e getAnterior.
Vejam que aqui eu já fui mais conservador, né,
já criei todas as coisas com a maneira privada.
Se eu criei privado eu tenho que fazer set e get,
que é o que tá acontecendo aqui.
Aqui, naturalmente, agora, eu sempre vou tratar
em todos os momentos
de Elemento parametrizado com a coisa
nesse caso, a coisa aqui é o TIPO.
Em todos os momentos
eu preciso usar esse Elemento parametrizado com o TIPO
e se você olhar aqui, ó,
pProximo e pAnterior eles são ponteiros de Elementos parametrizados com TIPO.
Então, é natural que continuem aqui, né, seguindo a mesma tipagem.
Por exemplo, no setInfo.
O setInfo ele é relativo ao pInfo,
pInfo é ponteiro de TIPO e não de Elemento parametrizado com TIPO.
Então, aqui eu vou colocar
pra manter o padrão, né, pra manter a coerência.
Ponteiro TIPO, ponteiro TIPO.
Depois set e get nome que é um set e um get usual.
Bom, aqui vocês tão vendo, vamos dizer, a definição da classe.
Agora você vai ver a definição e a implementação da classe.
Tá aqui a definição, ou seja, você tá vendo ponto e vírgula aqui, ó, não tem código aqui.
E, logo em seguida, vem a implementação.
Como é que fica na implementação?
Pegue qualquer função.
Vamos pegar aqui a função setNome, por exemplo.
setNome tem o parâmetro ali, n char*.
Ela é uma função que pertence, né.
Tem a pertinência pra classe Elemento parametrizado com tipo
e o retorno é void.
E tem um detalhe que antes da implementação de cada função
eu sou obrigado a colocar template
colocar aqui a mesma marca que eu tenho em cima da classe.
Eu preciso colocar essa mesma marca antes de cada função que for implementada
na parte de implementação.
Bom, isso considerado, tá.
Essa peculiaridade da sintaxe, vocês tem que se acostumar com
essa sintaxe particular de gabaritos, né,
de template bem entendido, né,
que aqui a gente já tá programando nosso template, nosso gabarito.
Ainda que numa classe simplória como é o Elemento, mas ainda sim a gente tá fazendo.
Tem uma peculiaridade, gente,
com relação a implementação de gabaritos
e templates que é o seguinte.
Em C++, templates são implementados somente no .h,
incluindo a implementação dos métodos.
É isso mesmo, tá. Tudo fica no .h.
Se você tentar fazer no .cpp com template dá erro.
Você até pode separar, como eu fiz,
em definição e implementação,
mas é tudo no .h mesmo.
Professor, se eu não quiser separar eu poderia não colocar o ponto e vírgula
e já fazer as implementações aqui?
Poderia.
Só que do jeito que eu fiz ele, supostamente, fica mais organizado.
Isso considerado,
a gente pode simplesmente aceitar
e dizer, "olha, é .h e pronto,
por quê? Porque é assim",
ou a gente pode refletir um pouquinho.
Se a gente refletir um pouquinho,
o que acontece quando você tem
uma classe que implementa algo em .h
aliás, que faz a definição em .h
e não faz as implementações efetivas no respectivo .cpp?
Na prática, os objetos da classe
vão, lá no baixo nível, na baixaria computacional,
eles vão compartilhar os métodos.
Bom, explicando de uma maneira simples, aqui, no caso dos templates, tá.
Eu não tenho como compartilhar método
entre os objetos da classe Elemento,
porque esses objetos dependem de uma tipagem parametrizada.
Eu vou criar um Elemento em tempo de execução.
Então, eu não sei se o Elemento vai ser parametrizado
com Aluno, com Disciplina, com Telefone, com Boitatá, Avião,
mas você pode ver que você vai parametrizar com algo.
e esse algo afeta como os métodos vão ocorrer,
como os métodos vão se dar.
Bom, justamente, quando a gente faz tudo no .h,
faz com que cada objeto tenha o seu conjunto de métodos pra si.
Não compartilhe com outros objetos de mesma classe.
Na baixaria computacional, bem entendido.
Então, estando tudo no .h
aqui fica resolvido, porque eu vou parametrizar
e aí, sei lá, eu vou criar um Elemento parametrizado com Professor.
Então, vai ser um elemento pra tratar professores em uma lista de Professor.
Esse Elemento parametrizado com Professor
ele vai ter o seu método getNome, por exemplo,
e vai retornar Elemento parametrizado como Professor em si, tá,
que não vai confundir com getNome de um outro Elemento
parametrizado com um outro tipo, por exemplo, Estagiario ou Aluno
cada um desses objetos ElementoAluno, ElementoEstagiario
vão ter o seu getNome com a devida parametrização com cada qual.
sem gerar confusões daí e cada qual tem o seu método.
Bom, isso aqui é uma explicação, tá, um pouco mais aguçada
sobre o funcionamento do C++ internamente, tá,
e se você não quiser se ater a essa explicação que eu fiz
se atêm ao que está em vermelho ali no slide.
Atenção: Templates são implementados somente no .h
incluindo a implementação dos métodos.
Grave isso que não tem problema,
depois se quiser você volta pra essa reflexão que fiz aqui
e se aprofunda no tema
do ponto de vista mais técnico nos livros,
até pra refinar o que eu estava explanando aí.