Menu
Coddy logo textTech

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, cada variável de membro que você criou pertence a um objeto específico. Quando você cria dois objetos Player, cada um tem seu próprio name e health. Estes 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, rastrear quantos jogadores existem no total.

É aqui que os membros estáticos entram em cena. Um membro estático pertence à própria classe, não a nenhum objeto em particular.

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: membros de instância são acessados por meio de um objeto, enquanto membros estáticos podem ser acessados por meio do 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ânciaMembros Estáticos
Único para cada objetoCompartilhado entre todos os objetos
Criado quando o objeto é criadoExiste antes de qualquer objeto ser criado
Acessado via objeto: player.healthAcessado via 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 objetos individuais.

challenge icon

Desafio

Fácil

Vamos construir um sistema de inventário de produtos que rastreia tanto os detalhes individuais dos produtos 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 classe Product que gerencia produtos individuais enquanto também rastreia dados de todo o inventário. Sua classe deve ter:
    • Membros de instância: name (string) e price (double) — únicos para cada produto
    • Um membro estático totalProducts que conta quantos produtos existem atualmente
    • Um membro estático totalValue que rastreia o preço combinado de todos os produtos
    • Um construtor que recebe um nome e preço, inicializa os membros de instância e atualiza ambos os contadores estáticos (incrementa a contagem, adiciona o preço ao valor total)
    • Um destrutor que atualiza os contadores estáticos quando um produto é removido (decrementa a contagem, subtrai o preço do valor total)
    • Um método getInfo() que retorna uma string no formato: "<name>: "<name>: $<price>"lt;price>"
    • Um método estático getInventoryStats() que retorna uma string: "Products: <count>, Total Value: "Products: <count>, Total Value: $<value>"lt;value>"
  • main.cpp: Demonstre como os membros estáticos são compartilhados entre todos os objetos enquanto os membros de instância permanecem únicos. Leia dois nomes de produtos e seus preços da entrada (name1, price1, name2, price2 — cada um em uma linha separada), então:
    • 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 Product com o primeiro nome e preço. Imprima suas informações e as estatísticas atuais do inventário.
    • Após o término do bloco (primeiro produto destruído), imprima "After first scope:" seguido pelas estatísticas do inventário
    • Crie outro Product com o segundo nome e preço. Imprima suas informações e as estatísticas do inventário.
    • Crie um terceiro Product com o nome "Bonus" e o preço 5.00. Imprima as estatísticas finais do inventário.

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 no main.cpp usando #include "Product.h".

Folha de consulta

C++ suporta dois tipos de membros de classe: membros de instância e membros estáticos.

Membros de instância são exclusivos de cada objeto - cada instância tem sua própria cópia:

class Player {
    std::string name;  // Cada jogador tem seu próprio nome
    int health;        // Cada jogador tem sua própria vida
};

Membros estáticos são compartilhados entre todos os objetos de uma classe - existe apenas uma cópia que pertence à própria classe:

class Player {
    static int playerCount;  // Compartilhado por TODOS os jogadores
    
public:
    Player(std::string n) : name(n), health(100) {
        playerCount++;  // Incrementa o contador compartilhado
    }
    
    ~Player() {
        playerCount--;  // Decrementa quando destruído
    }
};

Principais diferenças:

Membros de InstânciaMembros Estáticos
Exclusivo de cada objetoCompartilhado entre todos os objetos
Criado quando o objeto é criadoExiste antes de qualquer objeto ser criado
Acessado via objeto: player.healthAcessado via classe: Player::playerCount

Métodos estáticos podem ser chamados usando o nome da classe e podem acessar apenas membros estáticos:

class Player {
    static int playerCount;
    
public:
    static int getPlayerCount() {
        return playerCount;  // Pode acessar apenas membros estáticos
    }
};

// Chama usando o nome da classe
int count = Player::getPlayerCount();

Membros estáticos devem ser definidos fora da classe (geralmente em um arquivo .cpp ou após a definição da classe em um cabeçalho):

int Player::playerCount = 0;

Membros estáticos são úteis para contadores, valores de configuração compartilhados ou quaisquer dados que logicamente pertençam à classe em vez de objetos individuais.

Experimente você mesmo

#include <iostream>
#include <string>
#include "Product.h"

using namespace std;

int main() {
    // Ler a entrada
    string name1;
    double price1;
    string name2;
    double price2;
    
    getline(cin, name1);
    cin >> price1;
    cin.ignore();
    getline(cin, name2);
    cin >> price2;
    
    // TODO: Imprimir as estatísticas iniciais do inventário usando Product::getInventoryStats()
    
    // TODO: Criar um bloco de escopo com chaves
    // Dentro do bloco:
    //   - Criar um Product com name1 e price1
    //   - Imprimir suas informações usando getInfo()
    //   - Imprimir as estatísticas atuais do inventário
    
    // TODO: Após o fim do bloco, imprimir "After first scope:"
    // Depois, imprimir as estatísticas do inventário
    
    // TODO: Criar outro Product com name2 e price2
    // Imprimir suas informações e as estatísticas do inventário
    
    // TODO: Criar um terceiro Product com o nome "Bonus" e o preço 5.00
    // Imprimir as estatísticas finais do inventário
    
    return 0;
}
quiz iconTeste seus conhecimentos

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