Membros estáticos: static

Ver Todos os Exercícios

Teoria

E aí pessoal, aqui é Juan do Responde Aí, e hoje vamos falar sobre membros estáticos de uma classe!

Os atributos estáticos

Imagine que você está desenvolvendo o sistema de um jogo online, onde jogadores do mundo todo podem se cadastrar. Para organizar esses jogadores, você criou uma classe chamada J o g a d o r que contém informações como: nome, personagem, itens, etc...

Mas aí eu te pergunto: como você pode contabilizar quantos jogadores estão cadastrados?

Uma forma é criar uma variável global chamada c o n t a J o g a d o r e s , e sempre que um novo jogador se cadastrar essa variável aumenta um valor. Mas observe uma coisa, uma variável global é facilmente modificada por qualquer parte do programa. Seria legal se tivesse um jeito de manter a variável c o n t a J o g a d o r e s acessível apenas aos membros da nossa classe.

Até agora a gente viu que cada objeto criado no C++ possui variáveis próprias. Ou seja, se eu alterar o nome do j o g a d o r 1 isso não vai afetar o nome do j o g a d o r 2

Mas pro nosso exemplo, seria legal se existisse um tipo especial de variável que fosse compartilhada entre todos os objetos. Assim, se a gente alterar a contagem de jogadores, esse número seria acessível em qualquer objeto. E é pra isso que no C++ existem os membros estáticos.

E pra criar um membro estático é bem simples, é só usar a palavra-chave s t a t i c antes do tipo na hora de declarar a variável.

s t a t i c   t i p o   n o m e

Vamos ver um exemplo: por simplicidade, vamos criar somente atributos públicos, mas tudo que fizermos é valido para atributos privados também!

Nas linhas 05 a 11 criamos uma classe bem simples chamada J o g a d o r que contém um atributo chamado n o m e do tipo s t r i n g   e um atributo estático do tipo i n t   chamado c o n t a J o g a d o r .

Na linha 12 criamos um método construtor que recebe o nome do jogador, e o mais importante é que incrementa o valor do atributo estático c o n t a J o g a d o r . Ou seja, sempre que um jogador for criado, a contagem de jogadores irá aumentar! Seguindo uma lógica inversa, na linha 20 criamos um destrutor que diminui o valor de c o n t a J o g a d o r . Assim, a contagem vai diminuir quando um jogador for destruído.

Na linha 28 inicializamos o valor da variável estática. Para evitar ambiguidades, no C++ o valor de um atributo estático só pode ser inicializado fora da declaração da classe. Isso existe pra evitar que o atributo seja inicializado mais de uma vez e perca o seu conteúdo.

Um detalhe, note que a palavra-chave s t a t i c só é usada dentro da definição da classe!

Agora vamos utilizar essa classe dentro da m a i n ( ) :

Na linha 32 a gente cria um jogador. Como resultado, o construtor imprime o nome do jogador e atualiza a contagem. Na linha 35 e 36 criamos um outro jogador, mas dessa vez com alocação dinâmica, e note que o total de jogadores foi atualizado novamente.

Já na linha 39 nós deletamos o objeto p t r 2 , o destrutor é executado e diminui a quantidade de jogadores. Então, quando a gente imprime o atributo estático na linha 41 o resultado é que só temos um único jogador!

Por fim, quando o programa finalmente acabar todos os objetos serão automaticamente destruídos!

Métodos estáticos

Assim como os atributos, os métodos de uma classe também podem ser estáticos. O detalhe é que um método estático só pode acessar outros membros estáticos dentro da classe! Por consequência, membros estáticos não podem usar o ponteiro t h i s .

Vamos ver um exemplo. Vamos expandir a classe J o g a d o r que criamos, criando um método que diz se o número de jogadores é par ou ímpar:

Na linha 12 nós usamos a palavra-chave s t a t i c para criar o protótipo do método estático chamado j o g a d o r e s P a r I m p a r do tipo v o i d . Depois, vamos para a linha 32 onde implementamos os detalhes da função: um i f - e l s e que imprime uma mensagem se o número de jogadores for par, e outra mensagem se o número de jogadores for ímpar.

Note que a palavra-chave s t a t i c só é usada dentro da definição da classe!

Dentro da m a i n ( ) vamos criar dois objetos o p l a y e r 1 e o p l a y e r 2 . E usando qualquer um dos objetos podemos chamar o método estático que teremos o mesmo resultado! Após isso o programa acaba e os objetos são destruídos.

Detalhando os membros estáticos

Um membro estático é usado quando queremos compartilhar algo entre todos os objetos de uma classe! Um membro estático pertence a classe e não aos objetos. Em termos técnicos, os objetos só são alocados na memória no momento em que eles são criados, porém os membros estáticos são alocados na memória assim que o programa é iniciado!

Como os membros estáticos estão na memória desde o início do programa, isso permite uma

Isso permite uma vantagem dos membros estáticos: eles podem ser usados mesmo que não exista nenhum objeto criado, da seguinte forma:

N o m e C l a s s e   :     : N o m e M e t o d o E s t a t i c o ( )

Legal né!

Outra coisa que vale ressaltar é que os membros estáticos podem ser públicos ou privados!

Por fim, é importante você ter atenção para evitar erros comuns:

Erros comuns

  • Esquecer da palavra-chave s t a t i c
  • Usar a palavra-chave s t a t i c fora da declaração da classe.
  • Tentar inicializar o valor de um atributo estático dentro da declaração da classe
  • Usar um método estático para acessar um membro não-estático
  • Usar ponteiro t h i s dentro de um membro estático

Agora que você está estático como uma pedra, vamos pros exercícios de fixação!

Métodos estáticos

Detalhando os membros estáticos

Exercícios Resolvidos

Exercício Resolvido #1

Explique o que é um membro estático. Diga como ele se diferencia dos membros comuns e como eles podem ser úteis.

Passo 1

Um membro estático são os atributos e métodos compartilhados entres todos os objetos de uma classe. Isso acontece porque os membros estáticos pertencem à classe e não os objetos, como é o caso dos atributos e métodos comuns. Um membro estático pode ser público ou privado.

Os membros estáticos se diferenciam dos comuns por serem compartilhados entre todos os membros. Assim, quando modificamos um atributo estático essa modificação é visível para todos os objetos da classe.

Para declarar um membro estático devemos usar a palavra-chave s t a t i c antes do nome. Outro detalhe é que o conteúdo do membro estático não pode ser escrito dentro da declaração da classe.

Os membros estáticos são úteis quando queremos guardar uma informação que é importante para todos os objetos, como por exemplo, uma contagem de quantos objetos foram criados. Outra vantagem dos membros estáticos é que eles podem ser utilizados mesmo sem ter um objeto criado.

Resposta

Ei, a resposta está no passo a passo :)

Exercício Resolvido #2

Crie uma classe Círculo que tenha um construtor que receba um valor de raio, e calcule a área e o perímetro do círculo. Para a constante π utilize uma variável estática.

Nessa classe, todos os atributos e métodos devem ser públicos.

Depois, teste essa classe utilizando o raio r = 5 , e imprima a área e o perímetro.

Passo 1

Vamos lá pessoal, essa questão é bem parecida com o que já fizemos nos tópicos passados: criar uma classe com um construtor! O diferencial aqui é que o enunciado pede pra gente usar uma variável estática para a constante.

Antigamente a gente tinha duas abordagens pro valor de π . A primeira era criar uma variável global pro programa inteiro, que é uma abordagem de programação estruturada. A segunda era criar uma constante dentro da nossa classe. E agora vamos usar uma terceira alternativa, que é criar uma constante estática, afinal, o valor de π vai ser o mesmo para todos os objetos, então faz sentido usá-lo como objeto compartilhado.

Então vamos nessa! Pra começar vamos fazer o cabeçalho do nosso programa. Vamos incluir o < c m a t h > para executar as operações.

Passo 2

Vamos agora construir nossa classe chamada C i r c u l o .

A questão diz que todos os parâmetros e métodos devem ser públicos, então vamos usar a palavra-chave p u b l i c desde o início.

Vamos começar definindo a nossa variável estática p i , que também deve ser constante, então vamos usar as palavras chaves s t a t i c e c o n s t , e como p i é um número real, devemos usar o tipo f l o a t

Por enquanto vamos deixar a constante sem valor, pois atributos estáticos sem definidos após a classe.

O segundo atributo que vamos definir é o r para representar o raio do círculo

Agora que já declaramos os atributos, vamos desenvolver o método construtor. Criamos uma função sem tipo com o nome C i r c u l o e vamos receber o parâmetro real r a i o . O corpo da função consiste em assimilar o valor recebido do raio no atributo r .

Com os valores de r e p i podemos criar uma função A r e a ( ) que retorna resultado do cálculo da área. E uma outra função chamada P e r i m e t r o ( ) que retorna o resultado do cálculo do perímetro.

E agora podemos fechar a classe.

Porém, nada irá funcionar sem um valor para a constante p i . Então vamos definir um valor para ela. Após o fechamento da classe acessamos o atributo p i . Lembre-se que não devemos mais usar a palavra-chave s t a t i c , porém, temos que usar a definição de tipo c o n s t   f l o a t . Em seguida invocamos a classe C i r c u l o e com o operador acessamos o atributo p i e definimos o valor 3.1415

E dessa forma a nossa classe está prontinha!

Passo 3

Show, vamos por a classe pra trabalhar!

Dentro da m a i n   criamos um objeto c 1 da classe que criamos, e inicializamos esse objeto com o valor 5

 

E usando este objeto, podemos calcular a área e o perímetro da circunferência, e imprimir os resultados utilizando o c o u t .

E prontinho! Vamos rodar o programa e...

O programa roda lindão!

E é isso pessoal. Clica no botão aí em baixo pra ir pro próximo exercício!

Resposta

Exercício Resolvido #3

Uma bateria é formada por várias células de energia. Para desenvolver o driver de controle de uma bateria crie uma classe chamada C e l u l a . Crie um atributo privado chamado c a r g a que inicia em 25 . Construa dois métodos públicos: c o n s u m i r que sempre que é chamado consome 5 da carga atual da célula, e c a r r e g a r que aumenta a carga em 5 do valor atual.

Para manter as células bem alinhadas crie um parâmetro compartilhado chamado c a r g a B a t e r i a que armazena a soma de carga de todas as células. Por segurança esse parâmetro deve ser privado.

Para testar o programa crie três células c e l 1 , c e l 2 e c e l 3 . Chame o método consumir uma vez nas células 1 e 2, e carregar na célula 3. Imprima a carga total da bateria.

Passo 1

Vamos lá pessoal, essa questão dá instruções para criar uma classe para as células de uma bateria. A primeira parte traz informações gerais da classe para criar o atributo c a r g a e os métodos c a r r e g a r e c o n s u m i r .

O detalhe na questão é que ela pede pra criar um parâmetro compartilhado chamado c a r g a B a t e r i a , que é uma forma de dizer que esse é um atributo estático.

Nota o seguinte, os métodos c a r r e g a r e c o n s u m i r deve alterar o valor do atributo c a r g a , mas para manter a bateria atualizada, será preciso atualizar o valor do atributo c a r g a B a t e r i a também.

Outra coisa, o atributo c a r g a B a t e r i a tem que começar em 0 . Então sempre que uma C é l u l a for adicionada vamos precisar atualizar o valor da carga da bateria. Ou seja, precisamos de um método construtor.

Um último detalhe, é que o atributo c a r g a B a t e r i a é estático e privado. Precisamos criar um método getter para acessar esse valor. Como este método só vai lidar com atributos estáticos, então poderá ser um método estático.

Pode parecer muita coisa, mas fica tranquilo que vamos fazer juntos. E pra começar, vamos fazer o cabeçalho do programa:

Passo 2

Então vamos começar criando a nossa classe chamada C e l u l a . Como descrito no enunciado temos que criar dois atributos privados c a r g a para armazenar a carga da célula, e c a r g a B a t e r i a para armazenar a caga de todas as células.

Note que c a r g a B a t e r i a é um atributo compartilhado, e por isso deve ser estático.

Sempre que uma nova célula for adicionada, a carga total da bateria tem que ser atualizada. Para que algo aconteça no momento da criação de um objeto nós usamos um método construtor: uma função sem tipo com o mesmo nome que a classe. Dentro do construtor vamos atualizar o valor de carga da bateria.

Vamos agora desenvolver o método de carregamento. Quando o método c a r r e g a r ( ) for invocado ele deve aumentar a carga da bateria em 5 . E por consequência a carga da bateria deve ser atualizada também.

De maneira semelhante temos que desenvolver o método c o n s u m i r ( ) , porém os atributos c a r g a e c a r g a B a t e r i a devem ser reduzidos em 5

Ainda dentro da nossa classe, precisamos definir um método para acessar o valor da carga da bateria. Vamos criar um método do tipo f l o a t chamado g e t C a r g a B a t e r i a ( ) que retorna o valor da carga da bateria.

Com isso a nossa classe está quase concluída e já podemos fechar a classe. Mas ainda precisamos definir o valor inicial da variável estática c a r g a B a t e r i a .

Para definir o valor do atributo fora da classe não usamos a palavra-chave s t a t i c , apenas usamos o tipo f l o a t seguido do nome da classe C e l u l a , do operador e então usamos o nome do atributo que estamos acessando c a r g a B a t e r i a

E com isso a nossa classe está complemente definida.

Passo 3

Pra finalizar a questão, vamos executar um teste.

Primeiro vamos criar os três objetos do tipo C e l u l a : c e l 1 , c e l 2 e c e l 3 ..

Em seguida vamos usar os objetos c e l 1 e c e l 2 para executar o método c o n s u m i r ( ) e depois usamos o objeto c e l 3 para executar o método c a r r e g a r ( )

E finalizamos a questão executando o comando c o u t para visualizar a carga total da bateria. Para isso vamos acessar o método estático g e t C a r g a B a t e r i a ( ) .

A gente pode acessar um membro estático através de qualquer um dos objetos c e l 1 , c e l 2 ou c e l 3 . Porém, uma boa prática e acessar os métodos estáticos através da própria classe usando a sintaxe:

n o m e C l a s s e ∷ n o m e M e m b r o E s t a t i c o

No nosso caso fica da seguinte forma:

E com isso vamos ter o seguinte resultado:

E finalizamos mais uma questão! Vlw flw!

Resposta

Exercício Resolvido #4

Um programador criou uma classe para representar os funcionários da empresa. Porém ele cometeu alguns erros. Encontre e corrija.

Passo 1

Certo pessoal, essa é mais uma daquelas questões de encontrar erros no código. Então vamos olhar com atenção, linha-por-linha! Lets bora!

Das linhas 01 a 06 temos apenas os cabeçalhos e o início da classe. Até aqui está tudo certo

Agora observe a linha 07 e 08. Pelo comentário deixado pelo programador, podemos perceber que ele quer contar a quantidade de objetos criados. Para fazer esse tipo de contagem, é necessário que este atributo seja estático, pois só dessa forma é possível criar um atributo que seja compartilhado entre todos os objetos, permitindo assim que cada objeto altere o valor da contagem. Além disso, se você olhar pra linha 22, vai ver que de fato, o programador queria que esse fosse um membro estático.

Então o nosso primeiro erro está na linha 08. Precisão adicionar a palavra chave s t a t i c para informar ao compilador que a variável n u m E m p r e g é estática. Outra coisa importante é que os atributos estáticos não podem ser inicializados dentro da declaração da classe.

Então vamos corrigir

Passo 2

Seguindo em frente vemos o construtor da classe, que recebe os valores dos atributos e incrementa o valor de contagem n u m E m p r e g . Aqui não temos nenhum erro.

Porém, note o seguinte problema: A variável estática n u m E m p r e g é privada. E esse programador não criou nenhum método para poder acessar essa variável.

Precisamos criar um método getter para acessar o valor contido em n u m E m p r e g . Como a variável n u m E m p r e g é estática, o ideal é a gente criar um método getter que seja estático também!

Então, antes de fechar a classe, vamos criar um método estático público chamado g e t N u m E m p r e g

Por enquanto vamos criar só o protótipo, e depois vamos adicionar os detalhes.

Passo 3

Continuando, nos deparamos com código das linhas 22 e 23. Aqui o objeto é inicializar o valor da variável estática.

Mas note o erro, a palavra-chave s t a t i c só deve ser usada quando declaramos o atributo dentro da classe

Corrigindo, fica dessa maneira:

Passo 4

Ok, antes de analisar a m a i n ( ) vamos escrever o código do método estático g e t N u m E m p r e g . Tudo que precisamos fazer aqui é retornar o valor contido no atributo n u m E m p r e g , então vamos ter o seguinte código:

Passo 5

Pra finalizar a questão, vamos analisar a m a i n ( ) . Aqui ele cria quatro objetos para representar quatro funcionários.

Depois ele utiliza a própria classe para imprimir o valor do atributo n u m E m p r e g . Contudo, esse é um atributo privado e por isso não é possível acessá-lo diretamente!

Por sorte, nós percebemos isso antes e já temos um método getter criado! Então para corrigir basta a gente usar o método getter:

Resposta

Exercício Resolvido #5

Crie uma classe P r o d u t o s para gerenciar o estoque de uma loja. Cada produto deve ter os um nome, um valor de venda e a quantidade disponível no estoque. Os atributos devem ser recebidos no momento em que o objeto seja instanciado.

Além disso, qualquer um dos objetos dessa classe deve ser capaz de acessar a quantidade de produtos no estoque e também deve saber quantos tipos de produtos diferentes estão disponíveis.

Para testar essa classe instancie 4 produtos diferentes com preços e quantidades variadas. E imprima o a quantidade e a variedade de produtos existentes.

Passo 1

Vamos nessa, pessoal. Essa questão pede pra gente criar uma classe para os produtos de uma loja, com atributos que representem o nome, quantidade e valor do produto. Por questão de boas práticas, estes atributos serão privados.

O diferencial da questão é que teremos duas variáveis que devem ser compartilhadas entre as classes: v a r i e d a d e P r o d u t o s e t o t a l E s t o q u e . Para isso, estes atributos devem ser do tipo s t a t i c . Para seguir as boas práticas, estes atributos serão privados.

A questão também pede pra gente imprimir os valores de v a r i e d a d e P r o d u t o s e t o t a l E s t o q u e , mas como estas são variáveis privadas vamos precisar criar um método para acessá-las.

Mas primeiro, vamos escrever o nosso cabeçalho. Adicionamos a classe < s t r i n g > para facilitar nossa vida.

Passo 2

Vamos começar a classe chamada P r o d u t o s . Vamos iniciar o escopo privado com a palavra-chave p r i v a t e .

E agora vamos declarar os atributos: o primeiro é o n o m e do tipo s t r i n g , depois o valor do produto será o atributo v a l o r do tipo f l o a t , e a quantidade de produtos será armazenada no atributo q u a n t i d a d e do tipo i n t .

Agora vamos dar atenção aos atributos estáticos. O primeiro representa a variedade de produtos disponíveis, vamos chamar de v a r i e d a d e P r o d u t o s e o segundo representa a quantidade de todos os produtos no estoque, então chamaremos de t o t a l E s t o q u e .

Passo 3

Agora vamos dar uma olhada nos atributos públicos da classe.

O primeiro deles é o nosso método construtor, que vai receber o os parâmetros do produto: n o m e ,   v a l o r e q u a n t i d a d e .

Antes de concluir o método construtor temos que olhar para as variáveis estáticas.

O atributo v a r i e d a d e P r o d u t o s aumenta sempre que um produto novo é inserido, então devemos atualizar esse atributo no momento da criação de um novo objeto.

Já o atributo t o t a l E s t o q u e depende da quantidade de produtos inseridos. Então vamos usar o operador + = para adicionar a q u a n t i d a d e inserida no t o t a l E s t o q u e .

A classe está quase pronta. Mas antes de fechar a classe temos que desenvolver um método capaz de acessar os atributos v a r i e d a d e P r o d u t o s e t o t a l E s t o q u e . Então vamos criar o protótipo do método s t a t i c   v o i d   p r i n t E s t o q u e ( ) que será responsável por imprimir os valores.

Esse método pode ser do tipo estático pois ele só deve ter acesso as variáveis estáticas.

E com isso podemos fechar a nossa classe.

Passo 4

Contudo, a classe ainda não está concluída. Precisamos definir os valores iniciais dos atributos estáticos.

Então, fora da classe, nós chamamos os atributos utilizando a sintaxe t i p o   n o m e C l a s s e ∷ n o m e A t r i b u t o . Lembre-se que fora da classe não precisamos usar a palavra-chave s t a t i c . Veja como fica no nosso código:

Também precisamos definir o corpo do método p r i n t E s t o q u e . Para isso usamos a sintaxe: t i p o   n o m e C l a s s e ∷ n o m e M e t o d o ( ) . Novamente, o uso do s t a t i c não é necessário.

No corpo da função vamos usar o c o u t para enviar uma mensagem legal pro usuário.

Agora sim, a classe está completamente finalizada.

Passo 5

Vamos por a classe pra trabalhar agora.

Vamos começar criando quatro objetos da classe P r o d u t o . Você pode dar a eles o nome, valor e quantidades de quiser. Aqui eu escolhi alguns valores aleatórios:

Prontinho, agora basta a gente invocar o método p r i n t E s t o q u e (   ) . A gente pode usar qualquer objeto para isso, porém, as boas práticas sugerem que a melhor forma de usar um método estático é pela sintaxe: n o m e C l a s s e ∷ n o m e M e t o d o . No código fica assim:

Agora vamos rodar pra ver se deu tudo certo:

E é isso! Tudo certo! Até a próxima, pessoal.

Resposta

Exercício Resolvido #6

Um programador está desenvolvendo um jogo online. Em determinado momento ele criou uma classe chamada M o n s t r o que representa os inimigos do jogo. Cada objeto M o n s t r o tem um nome, um valor de força e um indicador de vida, ambos inteiros que variam de 0 a 100.

Neste jogo podem existir no máximo 50 monstros de cada vez. Assim que um monstro é criado ou morto a quantidade de monstros deve ser atualizada.

Passo 1

Beleza pessoal, vamos nessa!

A questão está pedindo pra gente criar uma classe com um número máximo de objetos. Ou seja, vamos precisar contabilizar quantos objetos foram criados, quando o numero de objetos for maior que este máximo comportamento da classe vai mudar!

Vamos começar com o cabeçalho do código.

E vamos também criar uma constante global que contem o número máximo permitido de monstros.

Passo 2

Vamos desenvolver a estrutura da classe.

Vamos declarar a classe M o n s t r o

E como atributos privados vamos declarar a string n o m e e os inteiros f o r c a e v i d a .

Vamos mudar para o encapsulamento público. Aqui vamos declarar o atributo estático inteiro c o n t M o n s t r o s . Vai ser esse o atributo responsável por efetuar a contagem de monstros.

E em seguida vamos declarar os métodos da classe. Vamos precisar construtor que vai inicializar os três atributos da classe, e que vai aumentar a contagem de c o n t M o n s t r o s a cada novo objeto criado.

E também de uma função m o r r e u ( ) que vai diminuir a contagem de monstros sempre que um inimigo for derrotado.

Prontinho! A estrutura geral da classe está feita. Vamos agora desenvolver os detalhes.

Passo 3

A primeira coisa a fazer é determinar o valor inicial do atributo estático c o n t M o n s t r o s . Pra isso a gente chama o atributo fora da classe e inicializa:

Show!

Passo 4

Agora vamos desenvolver os métodos. O primeiro é o construtor, que vai receber e inicializar os atributos da classe. Para facilitar o processo de criar objetos, vamos colocar valores padronizados para os parâmetros do construtor.

Nós também temos que atualizar a contagem de monstros. Um novo monstro foi criado, então o valor de c o n t M o n s t r o s aumenta mais um:

E o construtor ainda não acabou! Aqui a gente tem que lembrar que a quantidade máxima de monstros é 50 . E o que impede a existência 51 º ? Até agora, nada! Então vamos adicionar aqui uma condição para eliminar automaticamente os monstros excedentes.

Para isso vamos usar um i f que quando o número de monstros passar do máximo, automaticamente o método m o r r e u ( ) vai ser executado, eliminando o monstro extra no momento da criação!

Passo 5

Agora temos que desenvolver o método m o r r e u ( ) . Um monstro morre quando sua vida chega a zero. Então o objetivo desse método será setar a v i d a do monstro para 0 , e em seguida atualizar a contagem de monstros em menos um.

Pro jogo ficar mais dinâmico, vamos adicionar também uma mensagem informando que o monstro foi derrotado.

Prontinho! A classe e seus métodos estão concluídos!

Passo 6

Show de bola, agora vamos testar essa classe.

Primeiro, vamos exibir a quantidade de monstros inicial. Esse valor tem de ser zero.

Em seguida, vamos criar a quantidade máxima de monstros permitida, para testar se a contagem está ocorrendo como deveria, e exibimos a nova quantidade de monstros.

E depois precisamos conferir se o limitador de monstros funciona. Então vamos criar mais um objeto da classe M o n s t r o e ver o que acontece quando o atributo c o n t M o n s t r o s .

Agora vamos rodar o programa e ver o resultado:

Viu que legal? A quantidade de monstros foi contada corretamente! E assim que um monstro excedente foi criado, automaticamente ele foi eliminado do jogo.

Resposta

Exercício Resolvido #7

Um sistema canais enche um tanque. A vazão total nunca deve ser maior que 50   L / m i n . Quando esse limite é superado, a vazão de todos os dutos ativos é reduzida proporcionalmente para atingir o limite máximo.

Utilizando orientação a objetos em C++, crie um programa que simule esta situação utilizando três canais.

Passo 1

E aí, galera! Vamos desenvolver mais um exercício de fixação.

A questão fala que um tanque é alimentado por canais que fornecem um certo valor de vazão individual cada um, e que somados oferecem uma vazão total para o tanque. Então uma boa solução é criar uma classe que represente canais e depois instanciar a quantidade de objetos necessários.

Mas antes, vamos começar com o cabeçalho da questão. Vamos aproveitar para declarar uma constante global M a x V a z a o T o t a l que guarda o valor da vazão máxima permitida:

Passo 2

Vamos desenvolver a classe que representa os canais.

No encapsulamento privado, vamos criar um tributo que represente a vazão desse canal:

A v a z a o de cada canal deve ser ajustada de acordo com a vazão total do tanque, então vamos declarar um atributo v a z a o T o t a l que armazena a vazão total do tanque. Acontece que o valor de v a z a o T o t a l é composto pela soma de todos os canais, como gerenciar isso sem saber a quantidade de canais que serão utilizados? Simples, o atributo v a z a o T o t a l deve ser estático:

Belezinha! Agora vamos pro encapsulamento público onde vamos definir alguns métodos importantes.

Primeiro o construtor, que recebe como parâmetro o valor da vazão individual de cada canal.

Depois criamos métodos g e t V a z a o ( ) e g e t V a z a o T o t a l ( ) para que a gente possa visualizar os atributos privados. Detalhe interessante é que o g e t V a z a o T o t a l pode ser do tipo estático, pois ele acessa apenas atributos estáticos.

E também vamos declarar um método que irá atualizar o valor da vazão quando necessário. Esse método recebe um parâmetro p r o p o r c a o pois o ajuste de vazão será proporcional a um determinado fator.

E com isso podemos fechar a classe.

Passo 3

Show. Agora que o esqueleto da classe foi desenvolvido, a gente pode desenvolver os detalhes.

Primeiro, vamos inicializar o atributo estático v a z a o T o t a l , pra isso a gente chama ele sem utilizar a palavra chave s t a t i c e inicializa com valor zerado.

Em seguida, vamos desenvolver o construtor da classe. O construtor receberá o parâmetro vazão (que tem valor padrão zero), o parâmetro recebido será usado para inicializar o atributo v a z a o e em seguida atualiza o valor da v a z a o T o t a l do sistema.

Em seguida, a gente desenvolve os getters que simplesmente retornam o conteúdo dos atributos privados.

O ponto chave é o método a t u a l i z a V a z a o . Esse método recebe um valor de proporção que é calculado de acordo com o excedente de vazão.

Então, para evitar que a vazão de um mesmo canal seja contabilizada duas vezes, primeiro removemos de v a z a o T o t a l o valor atual de v a z a o deste canal. Em seguida, a vazão deste canal é atualizada de acordo com o valor de p r o p o r c a o . E por fim, adicionamos a vazão atualizada deste canal na vazão total do sistema.

E pronto! Todos os métodos e atributos da classe estão definidos.

Passo 4

Agora vamos testar.

Primeiro, vamos criar três instâncias de C a n a l com valores quaisquer de vazão.

Vamos exibir a vazão total para o usuário.

Em seguida, vamos usar uma estrutura i f - e l s e para verificar se a vazão total excede a máxima permitida.

Caso a vazão seja excedente, nós informamos isso ao usuário e calculamos um valor proporcional de redução que deve ser aplicada nos canais para atingir o valor permitido:

t a x a   d e   r e d u ç ã o = V a z a o   m a x i m a   p e r m i t i d a V a z a o   a t u a l

Com o valor calculado, a gente passa a taxa de redução como parâmetro do método a t u a l i z a V a z a o ( ) de cada um dos canais. E depois informamos isso ao usuário.

E pra finalizar, é só a gente imprimir o valor de vazão total e de cada um dos canais.

E o resultado é:

E é isso! Até a próxima!

Resposta

Exercício Resolvido #8

Crie uma classe I n g r e s s o que contabilize a quantidade de ingressos vendidos. Existem dois tipos de ingresso, o Pista e o VIP.

Passo 1

E aí, pessoal, tudo certinho?

A questão é de boas.

A gente precisa desenvolver uma classe I n g r e s s o que sempre que instanciar um novo objeto vai contabilizar um ingresso adicional. Quando precisamos contar a quantidade de objetos criados, a melhor forma é utilizar membros estáticos.

Mas antes vamos começar com o cabeçalho da questão.

Passo 2

Vamos iniciar a nossa classe I n g r e s s o :

Dentro do encapsulamento privado, a gente vai declarar os atributos estáticos. A gente precisa contabilizar a quantidade de ingressos vendidos para a pista e também para a área VIP. Então vamos criar dois atributos estáticos v e n d a s P i s t a e v e n d a s V I P . Para isso é só adicionar a palavra chave s t a t i c :

Agora vamos mudar o encapsulamento para público onde iremos desenvolver o construtor, uma função sem tipo com o mesmo nome da classe. O construtor vai receber apenas um único valor booleano que define se o ingresso vendido é ou não do tipo VIP.

Dentro do construtor vamos utilizar uma estrutura i f - e l s e que caso incrementa o atributo estático v e n d a s V I P caso o parâmetro v i p seja t r u e , e incrementa o atributo estático v e n d a s P i s t a caso o parâmetro v i p seja f a l s e :

Para garantir o acesso aos membros estáticos vamos criar um getter para cada um dos atributos. Note que esses getters vão acessar apenas membros estáticos, então o ideal é que estes sejam métodos estáticos. Para isso é só adicionar a palavra chave s t a t i c :

Show. A estrutura da classe está pronta, podemos fechar a nossa classe!

Agora precisamos inicializar os membros estáticos. Lembre-se, membros estáticos não podem ser inicializados dentro dos parêntesis da classe.

Passo 3

Então, logo após a classe vamos invocar os atributos estáticos e inicializa-los com o valor inicial zerado. Lembre-se que não é necessário usar a palavra-chave s t a t i c novamente.

Logo em seguida, podemos inicializar definir o comportamento dos métodos estáticos. Estes são métodos getters simples, que apenas retornam o conteúdo das variáveis estáticas.

E pronto! A classe está pronta e os membros estáticos estão definidos!

Resposta