Getters e Setters
Parte da seção Object Oriented Programming do Journey de C da Coddy — lição 19 de 61.
Com ponteiros opacos, os membros da struct ficam ocultos do código externo. Mas se o código externo não pode acessar os dados diretamente, como os lemos ou modificamos? A resposta são as funções getter e setter — interfaces públicas que fornecem acesso controlado a dados privados.
Um getter retorna o valor de um membro oculto:
// counter.h
int counter_get_value(const Counter *c);
// counter.c
int counter_get_value(const Counter *c) {
return c->value;
}
Um setter modifica um membro oculto:
// counter.h
void counter_set_value(Counter *c, int new_value);
// counter.c
void counter_set_value(Counter *c, int new_value) {
c->value = new_value;
}
Observe a convenção de nomenclatura: prefixe as funções com o nome do tipo (counter_) para evitar conflitos e tornar a API clara. Getters usam ponteiros const, já que eles não modificam o objeto.
Agora o código externo pode interagir com os dados ocultos de forma segura:
// main.c
Counter *c = create_counter(10);
printf("%d\n", counter_get_value(c)); // 10
counter_set_value(c, 25);
printf("%d\n", counter_get_value(c)); // 25
Este padrão oferece controle total sobre como os dados são acessados — uma base sobre a qual construiremos na próxima aula, quando adicionarmos lógica de validação aos setters.
Desafio
FácilVamos construir um módulo Score que utiliza o padrão de ponteiro opaco com funções getter e setter. Você criará um rastreador de pontuação oculto onde o código externo só pode interagir com os dados por meio da interface pública que você fornecer.
Você criará três arquivos:
score.h: Sua interface pública. Declare um tipoScoreopaco usando uma declaração antecipada (sem o corpo da struct!). Declare estas funções:create_score— recebe um inteiro para os pontos iniciais e retorna um ponteiro Scorefree_score— recebe um ponteiro Score e libera a memóriascore_get_points— um getter que recebe umconst Score *e retorna os pontos atuaisscore_set_points— um setter que recebe umScore *e um inteiro, atualizando o valor dos pontos
SCORE_H.score.c: Defina astruct Scorereal com um único membro oculto:int points. Implemente todas as quatro funções. Seu getter deve retornar o valor oculto, e seu setter deve atualizá-lo. Lembre-se de que os getters usam ponteirosconst, pois não modificam o objeto.main.c: Demonstre seu módulo criando uma pontuação, lendo seu valor, modificando-o através do setter e lendo-o novamente.
Você receberá duas entradas: os pontos iniciais (um inteiro) e o novo valor de pontos (um inteiro) para definir.
No seu arquivo principal, crie um Score com os pontos iniciais, imprima o valor atual usando o getter, atualize-o usando o setter com o novo valor, imprima o valor atualizado, depois libere a pontuação e imprima uma confirmação.
Imprima a saída neste formato:
Initial: {points}
Updated: {points}
FreedPor exemplo, com as entradas 100 e 250, a saída seria:
Initial: 100
Updated: 250
FreedObserve como o main.c não pode acessar points diretamente — ele deve passar pelas suas funções getter e setter. Isso é o encapsulamento em ação: você controla exatamente como os dados ocultos podem ser lidos e modificados.
Folha de consulta
Com ponteiros opacos, os membros da struct ficam ocultos do código externo. Para acessar ou modificar esses dados privados, use funções getter e setter.
Um getter retorna o valor de um membro oculto e usa um ponteiro const, já que não modifica o objeto:
// counter.h
int counter_get_value(const Counter *c);
// counter.c
int counter_get_value(const Counter *c) {
return c->value;
}
Um setter modifica um membro oculto:
// counter.h
void counter_set_value(Counter *c, int new_value);
// counter.c
void counter_set_value(Counter *c, int new_value) {
c->value = new_value;
}
Use uma convenção de nomenclatura com o nome do tipo como prefixo (counter_) para evitar conflitos e esclarecer a API.
O código externo interage com os dados ocultos por meio destas funções:
// main.c
Counter *c = create_counter(10);
printf("%d\n", counter_get_value(c)); // 10
counter_set_value(c, 25);
printf("%d\n", counter_get_value(c)); // 25
Experimente você mesmo
#include <stdio.h>
#include "score.h"
int main() {
int initial_points, new_points;
scanf("%d", &initial_points);
scanf("%d", &new_points);
// TODO: Criar um Score com initial_points
// TODO: Imprimir o valor inicial usando o getter
// Formato: "Initial: {points}"
// TODO: Atualizar a pontuação usando o setter com new_points
// TODO: Imprimir o valor atualizado usando o getter
// Formato: "Updated: {points}"
// TODO: Liberar o score e imprimir "Freed"
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 Object Oriented Programming
1Fundamentos da Programação Modular
Arquivos de CabeçalhoInclude GuardsArquivos-FonteFunções EstáticasRecapitulação: Calculadora Modular4Encapsulamento
Conceito de Ponteiros OpacosDefinindo Structs OpacasGetters e SettersValidação em SettersRecapitulação: Caixa Secreta2Objetos e Métodos
Structs como ObjetosO Ponteiro 'Self'Const CorrectnessPonteiro vs ValorMétodos AuxiliaresRecapitulação: Point Manager5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de Vida de Objetos
Padrão de ConstrutorPadrão de DestrutorInicialização na StackCópia ProfundaRecapitulação: String Wrapper6Herança via Composição
Incorporação de StructsA Regra do Primeiro MembroAcessando Membros PaiUpcastingRecapitulação: Hierarquia de Formas9Projeto: Desenhador de Formas
Visão Geral do ProjetoImplementação do Círculo