A partir do próprio...
da própria construtora,
depois que eu inicializo os atributos,
aqui faltou colocar o -1 em idadeP.
Deixo vocês colocarem lá, na versão de código de vocês.
Bom, e aqui eu chamo daí o Calc_Idade, passando a suposta data atual.
Inclusive, eu posso recuperar essa data atual aqui
esse dia, esse mês e ano do sistema
usando bibliotecas como o time.h.
Depois a gente vai fazer alguma coisa assim na sequência.
Mas, tá, o fato é que eu crio a pessoa
passo informações pra ela, através da construtora
e já inicializo aqui os atributos pertinentes
depois eu chamo o Calc_Idade, que vai fazer o cálculo e imprimir.
Vocês vejam que a minha função main tá ficando bem limpa, bem elegante.
Em relação aos códigos que a gente tinha anteriormente, inclusive.
Legal.
Deixa eu avançar um pouquinho mais aqui.
Aqui, na função main,
eu criei uma finalização de programa, lá, "Fim do Programa.",
usando cout e endl.
Então, vejam que interessante,
aqui eu tô utilizando
o cout e, portanto, inclui a biblioteca pertinente.
A biblioteca pertinente é o iostream.
Só que diferente da linguagem C
que usa .h pra tudo
do ponto de vista de bibliotecas externas
stdio.h, string.h, math.h.
Aqui o iostream perdeu o .h, no C++ contemporâneo.
Você faz lá um hashtag, um sustenido #include
do módulo, biblioteca externa iostream
e você tem que colocar na próxima linha
uma declaração dizendo que você tá usando
o conjunto, ou o espaço de nomes,
padrão, standard, std.
Então, você é obrigado a colocar essa linha aqui, using namespace std;
Legal.
Isso vai lhe habilitar a utilizar o quê? Utilizar essa biblioteca
e utilizar todos os comandos do iostream,
incluindo o cout e o endl.
Então, nessas reticências, eu poderia,
tal qual eu tenho no main.cpp,
eu poderia ter, também, o Pessoa.cpp.
Ou se eu tivesse, abrindo um parêntesis aqui,
se eu tivesse lá um concentrador de inclusão de bibliotecas externas
tal qual eu tenho lá nos ambientes Microsoft
como standard affixment, stdafx,
eu poderia incluir esse #include
e using namespace lá naquele standard affixment
no ambiente Microsoft.
Isso é só uma...
um detalhe com relação ao ambiente
coisa que a gente já discutiu lá em aula passada.
Retornando aqui ao ponto, tal qual está nos slides,
o fato que aqui eu tenho esse include aqui
nessas reticências eu poderia ter um include similar a esse aqui.
Mas se você olhar no próximo slide, justamente,
eu resolvi, lá, fazer uma coisa um pouco mais econômica.
Em vez, vou voltar um slide, em vez de usar essa abordagem
de incluir todos os comandos da iostream,
eu posso, nas minhas inclusões,
fazer uma inclusão mais seletiva.
Olha aqui, include iostream usando
do espaço de nomes std apenas o comando cout.
Olha lá, os dois pontos que é de pertencimento.
Usando apenas o comando endl que pertence a std.
Isso permite que você vá lá e pince
comando a comando que você quer utilizar.
Se teu compilador não for muito esperto,
pra pinçar automaticamente os comandos sem incluir tudo
esse tipo de código garante
você pinçar lá dentro da biblioteca só de fato
os comandos que realmente interessam
pra tua execução ou pro teu módulo visado,
mas, enfim, aqui são duas maneiras de incluir, tá.
Ou você inclui a biblioteca inteira,
ou você inclui apenas os comandos
que realmente interessam pra você
que é o que tá sendo mostrado nesse presente slide.
Além do cout, eu tem o cin.
Então, aqui nessa função main
eu tô criando o Simão, Einstein e Newton
mesmo que Simão, Einstein e Newton estejam chamando
o Calc_Idade lá tá com uma data fixa.
Então, vai ter um cálculo que não é tão justo.
Ou eu vou lá na construtora e faço um automatismo
pra recuperar a data do sistema
ou vou ter que usar outros subterfúgios, tá, não tão automáticos,
que é o subterfúgio que tá sendo mostrado aqui nesse slide.
Em todo caso, esse subterfúgio serve pra mostrar o comando de entrada,
que é aqui o cin.
Se o cout é tela, por assim dizer, o cin é teclado.
Então, aqui eu vou ler a informação da variável dia
a informação da variável mês, a informação da variável ano,
ou seja, o usuário vai passar um dia, mês e ano,
e aí eu vou chamar o Calc_Idade.
Professor, não poderia pegar esse código todo aqui
que você está circulando com o mouse
e jogar dentro da construtora?
Poderia. Poderia pegar esse código aqui, ó.
Mais a definição das variáveis, obviamente.
Obviamente, e jogar na tua construtora. Também funcionaria.
Pessoal, tem uma certa reflexão,
a ser feita com relação a todo esse código que foi mostrado.
Particularmente, voltando aqui um pouquinho,
com relação ao Calc_Idade, tá.
Esse código funciona, se executar ele, funciona.
Perfeitamente.
Agora, se você prestar atenção
nessa função, em particular, Calc_Idade.
Há algo de errado com ela?
Sim.
A função se chama Calc_Idade,
e tá calculando a idade, o que tá muito bem,
mas ela tá fazendo mais que Calc_Idade,
ela tá calculando a idade e imprimindo a idade.
E aqui entra numa situação chamada acoplamento.
É o típico exemplo, tá. É um exemplo bem simplório, bem entendido.
Mas é uma típica situação que a gente não devia acontecer,
não devia deixar acontecer.
Acoplamento é uma coisa ruim.
Os bons projetos de software
e até de sistemas em geral, tá.
Eles devem respeitar um princípio muito importante chamado
coesão e desacoplamento.
E aqui, eu vou deixar esse exemplo um pouco em tela aí
e vou fazer um pequeno discurso de reflexão.
Vou pegar um outro artefato que não seja software.
Pegar um artefato de engenharia
como, por exemplo, um chuveiro.
Nas casas mais simples,
que foi onde eu morei minha infância inteira
e minha adolescência e parte da minha vida adulta, inclusive
as casas mais simples tem chuveiros mais simples.
Esses chuveiros, eles têm só um comando
com esse mesmo comando você aciona
a liberação da água, ou seja, a vazão da água
e também, ao mesmo tempo, você acaba,
através disso, controlando a temperatura.
Não raro, acontece que em climas frios você tem
ou muita água saindo numa temperatura, no máximo, morna,
ou você tem pouca caindo com a temperatura mais apropriada mais quente.
Né, se você quiser a temperatura quente.
Ali tem um problema, tá.
Porque você tem duas coisas que você quer controlar.
Você quer gerenciar duas funcionalidades, a vazão e a temperatura
No mesmo comando.
Ora, em chuveiros um pouco melhores, o pessoal separa.
Separa em duas válvulas.
Você vai ter uma válvula, ou um comando, se quiser chamar assim,
que gerencia a vazão, a saída da água.
e outro comando que gerencia a temperatura.
Então você desacoplou.
Usou princípio de desacoplamento.
Ao mesmo tempo, não adianta, você ter um comando
como o comando da vazão da temperatura...
Perdão, como o comando da vazão da água do banheiro
e o controle de temperatura, o comando, lá na cozinha.
Estão geograficamente espalhados, isso é ruim.
Eles tem que ter alguma coesão.
Nesse caso, uma coesão geográfica, uma coesão de proximidade.
Então, eu tenho, meu banheiro que é o contexto apropriado,
os dois comandos
um comando pra vazão da água e outro comando pra temperatura da água.
Aí você criou desacoplamento dos comandos
e manteve coesão pra eles poderem trabalhar,
ou serem acionados ali conjuntamente,
que é natural nesse tipo de situação.
Isso aqui foi só pra lembrar pra vocês, o princípio geral
da coesão e do desacoplamento.
Muito bem.
Trazendo esse... saindo desse exemplo mais genérico, mais pictórico, tá.
Um exemplo mais real, aqui nesse Calc_Idade
a gente tem justamente um problema de acoplamento.
Olha lá, ó. Você tem uma função, Calc_Idade
que tá fazendo mais do que ela deveria.
Tá fazendo o cálculo de idade e também mostrando o nome.
Fazendo um paralelo, tá liberando a água e ainda
controlando a temperatura da água.
Como é que a gente resolve isso?
Deixa eu puxar uma outra tela pra vocês aqui.
Aqui eu vou pegar uma versão, Copy,
que eu melhorei o código.
Eu gerei uma solução melhor que essa dos slides.
Tô abrindo o ambiente Microsoft.
Já foi discutido nas aulas passadas.
Vamos lá, gente.
Vou dar um Ok aqui, muito embora
Não tenho
Aqui eu tenho, então, o meu main,
o meu _tmain, porque eu tô usando
uma versão de projeto que não usa o main
usa o _tmain, mas tudo bem.
Aqui eu criei então, o Simão, o Einstein, o Newton e mais o Zezinho.
Vocês vejam, inclusive, que o Zezinho aqui, ó,
não tem ano e não tem nome.
Isso significa que eu tô usando os valores default lá.
Provavelmente na construtora eu coloquei valores default, a gente vai verificar.
Aqui eu tô chamando a função, não Calc_Idade, mas sim, calc_idade_imprime.
Mas como assim?
Então, bastou eu mudar o nome da função pra eu melhorar aquele acoplamento?
Não, não foi só isso.
Vamos dar uma espiada no arquivo de cabeçalho, no header.
No Pessoa.h.
Tá aqui, ó.
Então, eu tenho os meus atributos da classe Pessoa.
Tenho a construtora
que, de fato, eu tenho valor default em ano e em nome.
Eu tenho o Calc_Idade, uma função independente.
Eu tenho o imprime_idade, como outra função independente
e tenho o Calc_Idade e o imprime_idade.
Se você olhar o Calc_Idade e o calc_idade_imprime
eles tem o mesmo conjunto de parâmetros.
Professor, aqui o senhor usou letras minúsculas e lá o senhor usou
aliás, minúsculas e lá maiúsculas, tá.
É melhor padronizar.
Tem que padronizar de fato.
Aqui, por exemplo, seria melhor a gente fazer isso aqui.
Bom, agora eu vou ter que corrigir isso aqui no .cpp.
Pronto, corrigido.
Se você olhar o calc_idade, aqui, agora com minúsculo.
mas enfim, pouco importa,
para o que a gente ta focando aqui
eu tenho lá a função de cálculo, não tem mais o imprime.
Quem tem o imprime é aqui, uma função independente.
Ela que imprime o que ela tem que imprimir, usando o cout.
Então, elas estão desacopladas eu tenho a função calc_idade
desacoplada da função imprime_idade,
cada um no seu quadrado.
Professor, mas tem situações que eu vou querer calcular e imprimir.
Então, pra evitar que você tenha que chamar as duas funções,
daí eu criei uma função de coesão aqui, em alguma medida
que é a função que chama calc_idade
e traz todos os parâmetros pertinentes.
Tá vendo aqui.
Então, repassa o parâmetro.
Vejam que obviamente, né, pessoal,
aqui eu não vou colocar int.
Aqui eu não tô definindo a variável
a variável já tá definida ali na função, aqui eu tô só repassando
pra essa chamada de função, bem entendido.
E, daí, imprime_idade.
Aqui, então, eu consegui garantir
nesse exemplo simples, tá.
Desacoplamento, e no final das contas, alguma coesão também.
Certo.
Tá aqui a construtora de Pessoa,
vejam que eu não estou chamando o calc_idade nessa versão,
eventualmente, até posso.
Aqui, em contrapartida,
eu estou usando o idadeP = -1, ali
inicializando a variável, porque isso é fundamental.
Vamos compilar aqui, ver se eu não
acrescentei nem um erro, nem um problema.
Êxito.
E vamos pra execução sem depuração.
Tá ali executou a idade,
do Simão, do Einstein, do Newton
e do Zezinho que não tem nome, tá vendo, desnomeado.
e como foi colocado zero, zero ele calculou 2019.
Por que não foi 2020?
Porque depende do que eu coloquei aqui, né, gente,
na minha main.
Deixa eu dar uma olhada na minha main aqui.
Tá ali, ó. Eu tô chamando direto aqui, tá,
e fixando um valor inclusive aqui.
Nada impede, insisto tá, em fazer
uma coisa um pouquinho mais inteligível.
Vamos fazer pra vocês verem
Tá aqui ó, tô só criando os objetos.
Agora eu vou no Pessoa.cpp
vou criar um
umas variáveis temporárias aqui
int dia, mes, ano;
Vocês que estão começando, colocou uma linha de código,
dá uma compiladinha
pra ver se tá indo no caminho certo.
Até vocês pegar segurança nas coisas que vocês estão fazendo.
Isso é uma boa tática, é uma boa dica.
Legal.
Agora eu vou fazer aqui um cin.
dia, mes e ano.
eu posso, tá, pelo menos deveria poder,
fazer essa leitura aqui, direto numa pegada só.
Claro que você pode ser elegante com o usuário
e não deixar ele sem informação então vocês diz lá
Informar, ou informe, no imperativo
dia, mês e ano de
aqui já posso usar o nome da pessoa porque eu já tenho o nome
aí eu vou colocar aqui, dois pontos, pra ele não ficar perdido,
e aqui eu vou colocar um pulação de linha.
Bom, e por fim,
eu vou chamar o calc_idade_imprime
dia, mês e ano,
ponto e vírgula, e vamos ver se isso aqui compila.
Deu um warning lá, depois a gente pode verificar do que se trata,
mas ele compilou.
Iniciar sem depuração.
Então, hoje, por exemplo,
É 07/07/2020.
A idade da pessoa seria 43.
Que que eu tô fazendo aqui?
Ah, sim, vejam só que interessante.
No que eu coloquei
a leitura
é de cada Pessoa.
Então, aqui tá acontecendo o quê?
Pra cada pessoa eu tenho que digitar o dia atual,
o que não é a coisa mais agradável do mundo.
Então, vocês viram que, nessa situação posta,
obviamente, tá, depois mais, saber fazer
seria não chamar o imprime_idade aqui, nesse momento
e deixar pra fazer lá no âmbito da função main
pra precisar digitar só uma vez
essa informação.
Aí, nesse contexto, procede, tá, não colocar o calc_idade aqui,
pelo menos não por ora.
já que eu não tô pegando informação direto do sistema
se eu tivesse pegando informação direto do sistema,
aí, compensaria, pra chamar o calc_idade aqui.
Voltemos pra função principal.
Ok.
Deixa eu fazer aqui um retorno de código.
Agora eu tenho certeza que eu coloquei, porque eu fiz um Ctrl + X
Bom eu tô fazendo uns ajustes aqui, vocês tão percebendo, né.
Não muito a necessidade de discurso.
Se eu perguntei os parâmetros para o usuário,
obviamente, que eu vou passar aqui de maneira automática, né.
Não vou ficar colocando data fixa ali.
Esse eu posso eliminar.
Bom, se eu não inseri nenhum erro, isso aqui deve compilar.
Bom, obviamente,
que isso aqui não ia funcionar aqui, né, pessoal,
porque eu tô fora do âmbito dentro da classe.
Quando eu estava aqui, ó, eu tinha acesso, nesse âmbito, ao nomeP.
Agora, obviamente, aqui, eu não tenho acesso, tá.
Então, simplesmente, eu vou dizer, mesmo porque eu não quero saber o nome
O dia, mês e ano atual
pra calcular a idade de alguém.
Então, eu vou retificar isso aqui.
Agora sim, vai estar no discurso de um experiente aqui,
Informe dia, mês e ano atual.
Lá, como estava dentro do objeto, seria o
O dia, mês e ano atual de fulano de tal para calcular a sua idade.
Bem, eu tinha que ficar informando pessoa a pessoa, tá.
Isso não é legal.
Aqui, eu tô fazendo a coisa mais estruturada
Informe o dia, mês e ano atual geral.
E aí, depois desse dia, mês e ano atual geral
eu faço, aí, os cálculos.
Bom, vamos lá.
Recompilar, agora sim, recompilar.
Compilado.
E, agora sim, está projetado, está certinho.
Conforme a gente queria desde o início.
Sete do sete de 2020.
Tá informado ali, ó
Simão 43, o Einstein no dia de hoje teria 141,
O Isaac teria, o Isaac Newton teria 367 anos
e o Zezinho lá que
não foi colocado nenhuma data apropriada de nascimento pra ele,
teria 2020 anos.
O que obviamente fica estranho ali, não colocar nome, nem nada.
Então, a gente tem que saber utilizar com a devida parcimônia aqui, tá.
Esses valores default.
Obviamente, esse aqui é um exemplo didático, né,
pra saber que você pode usar valor default
e você tinha que usar isso, aí, corretamente.
Vou colocar aqui, ó, sete.
do sete, de... do ano 2000.
E o Zezinho vai se chamar
José,
sei lá eu,
Joseh Joseh
Tem nome e sobrenome de José, então é o Zezinho.
E, tá aqui.
Isso aqui é um exemplo, obviamente, pedagógico
Vamos recompilar.
Executar.
Ah, sim. Sete, sete, vinte vinte.
Tá aí, agora o Zezinho tem 20 anos, naturalmente.
Ok, pessoal, isso aqui então foi só, na verdade
eu acabei me alongando, tá, mas o ponto aqui
de vir para esse código era, justamente, alcançar
um exemplo simples,
mais pragmático sobre acoplamento e algo sobre coesão.
Legal, deixa eu retomar com vocês agora
os meus... slides.