Membros de Instância vs. Estáticos
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 27 de 104.
Até agora, todas as variáveis-membro que você criou pertencem a um objeto específico. Quando você cria dois objetos Player, cada um tem seu próprio name e health. Esses são chamados de membros de instância — eles existem separadamente para cada instância da classe.
Mas e se você precisar de dados compartilhados entre todos os objetos? Por exemplo, acompanhar quantos jogadores existem no total.
É aqui que entram os membros estáticos. Um membro estático pertence à própria classe, não a nenhum objeto específico.
class Player {
std::string name; // Membro de instância - cada jogador tem o seu próprio
int health; // Membro de instância
static int playerCount; // Membro estático - compartilhado por TODOS os jogadores
public:
Player(std::string n) : name(n), health(100) {
playerCount++; // Incrementa quando qualquer jogador é criado
}
~Player() {
playerCount--; // Decrementa quando qualquer jogador é destruído
}
};A principal diferença: os membros de instância são acessados por meio de um objeto, enquanto os membros estáticos podem ser acessados pelo próprio nome da classe. Pense nos membros de instância como “um por objeto” e nos membros estáticos como “um por classe”.
| Membros de instância | Membros estáticos |
|---|---|
| Únicos para cada objeto | Compartilhados entre todos os objetos |
| Criados quando o objeto é criado | Existem antes que qualquer objeto seja criado |
Acessados por meio do objeto: player.health | Acessados por meio da classe: Player::playerCount |
Membros estáticos são úteis para contadores, valores de configuração ou quaisquer dados que pertençam logicamente à classe, em vez de a objetos individuais.
Desafio
FácilVamos criar um sistema de inventário de produtos que acompanhe tanto os detalhes individuais de cada produto quanto as estatísticas gerais do inventário usando membros de instância e estáticos.
Você criará dois arquivos para organizar seu código:
Product.h: Defina uma classeProductque gerencie produtos individuais e também acompanhe os dados gerais do inventário. Sua classe deve ter:- Membros de instância:
name(string) eprice(double): exclusivos de cada produto - Um membro estático
totalProductsque contabiliza quantos produtos existem atualmente - Um membro estático
totalValueque acompanha o preço combinado de todos os produtos - Um construtor que recebe um nome e um preço, inicializa os membros de instância e atualiza ambos os contadores estáticos (incrementa a quantidade, adiciona o preço ao valor total)
- Um destrutor que atualiza os contadores estáticos quando um produto é removido (decrementa a quantidade, subtrai o preço do valor total)
- Um método
getInfo()que retorna uma string no formato:"<name>: $<price>" - Um método estático
getInventoryStats()que retorna uma string:"Products: <count>, Total Value: $<value>"
- Membros de instância:
main.cpp: Demonstre como os membros estáticos são compartilhados entre todos os objetos, enquanto os membros de instância permanecem exclusivos. Leia dois nomes de produtos e seus preços da entrada (name1, price1, name2, price2: cada um em uma linha separada) e, em seguida:- Imprima as estatísticas iniciais do inventário usando o nome da classe:
Product::getInventoryStats() - Crie um bloco de escopo com chaves e, dentro dele, crie um
Productcom o primeiro nome e preço. Imprima suas informações e as estatísticas atuais do inventário. - Após o fim do bloco (o primeiro produto é destruído), imprima
"After first scope:"seguido das estatísticas do inventário - Crie outro
Productcom o segundo nome e preço. Imprima suas informações e as estatísticas do inventário. - Crie um terceiro
Productcom o nome"Bonus"e o preço5.00. Imprima as estatísticas finais do inventário.
- Imprima as estatísticas iniciais do inventário usando o nome da classe:
Lembre-se de definir seus membros estáticos fora da classe no arquivo de cabeçalho (após a definição da classe). Formate os preços com duas casas decimais usando std::fixed e std::setprecision(2) de <iomanip>.
Inclua seu arquivo de cabeçalho em main.cpp usando #include "Product.h".
Experimente você mesmo
#include <iostream>
#include <string>
#include "Product.h"
using namespace std;
int main() {
// Ler entrada
string name1;
double price1;
string name2;
double price2;
getline(cin, name1);
cin >> price1;
cin.ignore();
getline(cin, name2);
cin >> price2;
// TODO: Imprima as estatísticas iniciais do inventário usando Product::getInventoryStats()
// TODO: Crie um bloco de escopo com chaves
// Dentro do bloco:
// - Crie um Product com name1 e price1
// - Imprima suas informações usando getInfo()
// - Imprima as estatísticas atuais do inventário
// TODO: After the block ends, print "After first scope:"
// Em seguida, imprima as estatísticas do inventário
// TODO: Crie outro Product com name2 e price2
// Imprima suas informações e as estatísticas do inventário
// TODO: Crie um terceiro Product com nome "Bonus" e preço 5.00
// Imprima as estatísticas finais do inventário
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos externosBuild e compilação em C++Arquivos de cabeçalho e arquivos-fonteNamespaces e escopoIntrodução à POO em C++Classes vs. objetosO ponteiro 'this'Métodos (funções membro)Atributos (membros de dados)Noções básicas de construtores e destruidoresRevisão - calculadora simples4Propriedades de Classe
Membros de Instância vs. EstáticosGetters e SettersFunções Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRevisão - Gerenciador de Contas Bancárias7Herança
Herança básicaNíveis de acesso da herançaOrdem de chamada de construtor e destrutorSobrescrita de métodosFunções virtuais e VTableHerança múltiplaHerança virtualRevisão - Hierarquia de funcionários10Visão geral da STL
Visão geral e filosofia da STLContêineres da STLIteradoresAlgoritmos da STLFunctors e expressões lambdaRecapitulação - Frequência de palavras13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonFactory e Abstract FactoryPadrão BuilderPadrão ObserverPadrão Strategy2Gerenciamento de Memória
Memória Stack vs. HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Ponteiros Inteligentes em C++RAII em C++Revisão - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de acesso em C++Especificadores de acesso em profundidadeOcultação de informaçõesStruct vs ClasseClasses aninhadas e internasRecapitulação - Sistema de registros de alunos8Polimorfismo
Polimorfismo em compilação vs. execuçãoSobrecarga de funçõesFunções virtuais revisadasFunções virtuais purasClasses abstratasDesign de interfaces em C++Conversão dinâmica e RTTIRecapitulação — Calculadora de formas11Conceitos Avançados de OOP
Composição vs. HerançaMixins via CRTPIdioma PimplApagamento de TiposClasses Enum e Tipagem ForteTratamento de Exceções em OOPHierarquias de Exceções Personalizadas14Padrões de Projeto — Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositeRAII como Padrão3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentoListas de Inicialização do ConstrutorConstrutores DelegantesAprofundamento em DestrutoresRegra dos Três / Cinco / ZeroRevisão - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de FluxoSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçõesTemplates de ClassesEspecialização de TemplatesTemplates VariádicosNoções Básicas de SFINAE e Traits de TiposRecapitulação - Contêiner GenéricoPratique por conta própria: Compilador de C++ online