Ocultação de Informação
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 36 de 104.
Ocultação de informações vai além do simples uso de especificadores de acesso. É um princípio de design onde você oculta não apenas os dados, mas também os detalhes de implementação de como sua classe funciona internamente.
O objetivo é expor apenas o que os usuários da sua classe precisam saber, mantendo todo o resto oculto. Isso permite que você altere a implementação interna sem afetar o código que utiliza sua classe:
class Temperature {
double kelvin; // Representação interna - detalhe oculto
public:
void setCelsius(double c) {
kelvin = c + 273.15; // Conversão oculta para o usuário
}
double getCelsius() const {
return kelvin - 273.15;
}
double getFahrenheit() const {
return (kelvin - 273.15) * 9.0/5.0 + 32;
}
};Os usuários desta classe não sabem (ou não precisam saber) que a temperatura é armazenada internamente em Kelvin. Se você decidir posteriormente armazená-la em Celsius, alterará apenas a implementação privada — a interface pública permanecerá inalterada.
Esta separação entre interface e implementação oferece diversos benefícios: ela reduz a complexidade para os usuários da sua classe, previne o uso indevido acidental de dados internos e torna seu código mais fácil de manter. Quando os detalhes internos estão ocultos, você tem a liberdade de otimizar ou refatorar sem quebrar o código existente que depende da sua classe.
Desafio
FácilVamos construir uma classe Distance que demonstra a ocultação de informações ao armazenar distâncias internamente em metros, enquanto fornece uma interface limpa para trabalhar com diferentes unidades. Os usuários da sua classe não precisarão saber (ou se importar) como a distância é armazenada internamente — eles apenas trabalharão com a unidade que for mais conveniente para eles.
Você criará dois arquivos para organizar seu código:
Distance.h: Defina uma classeDistanceque oculta sua representação interna enquanto expõe uma interface pública flexível. Internamente, armazene a distância em centímetros (como umdouble) — este é o seu detalhe de implementação oculto. Sua interface pública deve permitir que os usuários:- Definam a distância usando
setMeters(double m),setCentimeters(double cm), ousetKilometers(double km) - Obtenham a distância usando
getMeters(),getCentimeters(), ougetKilometers()— todos devem ser métodos const - Somem duas distâncias com
add(const Distance& other)que retorna um novo objetoDistance
Inclua um construtor padrão que inicializa a distância como zero. A lógica de conversão deve estar oculta dentro dos seus métodos — os usuários apenas chamam
setKilometers(5)egetMeters()sem se preocupar com o formato de armazenamento interno.- Definam a distância usando
main.cpp: Demonstre que os usuários podem trabalhar com sua classe sem conhecer a representação interna. Leia dois valores de distância da entrada: o primeiro em metros, o segundo em quilômetros. Então:- Crie um objeto
Distancee defina-o usando o valor em metros - Imprima
"In meters: <value> m" - Imprima
"In centimeters: <value> cm" - Imprima
"In kilometers: <value> km" - Crie um segundo objeto
Distancee defina-o usando o valor em quilômetros - Some as duas distâncias e armazene o resultado
- Imprima
"Combined in meters: <value> m"
- Crie um objeto
A beleza da ocultação de informações é que você poderia, mais tarde, alterar o armazenamento interno de centímetros para milímetros (ou qualquer outra coisa) sem mudar como os usuários interagem com sua classe. A interface pública permanece estável mesmo que a implementação mude.
Formate todos os valores de saída com duas casas decimais usando std::fixed e std::setprecision(2) de <iomanip>. Converta as strings de entrada para doubles usando std::stod().
Referência de conversão: 1 metro = 100 centímetros, 1 quilômetro = 1000 metros.
Folha de consulta
O ocultamento de informações é um princípio de design onde você esconde detalhes de implementação de como sua classe funciona internamente, expondo apenas o que os usuários precisam saber.
Isso permite que você altere a implementação interna sem afetar o código que utiliza sua classe:
class Temperature {
double kelvin; // Representação interna - detalhe oculto
public:
void setCelsius(double c) {
kelvin = c + 273.15; // Conversão oculta do usuário
}
double getCelsius() const {
return kelvin - 273.15;
}
double getFahrenheit() const {
return (kelvin - 273.15) * 9.0/5.0 + 32;
}
};Os usuários não sabem (ou precisam saber) que a temperatura é armazenada em Kelvin internamente. Se você alterar o formato de armazenamento posteriormente, apenas a implementação privada muda - a interface pública permanece inalterada.
Benefícios do ocultamento de informações:
- Reduz a complexidade para os usuários da sua classe
- Previne o uso indevido acidental de dados internos
- Torna o código mais fácil de manter e refatorar
- Permite a otimização sem quebrar o código existente
Experimente você mesmo
#include <iostream>
#include <string>
#include <iomanip>
#include "Distance.h"
using namespace std;
int main() {
// Ler valores de entrada
string metersInput, kmInput;
cin >> metersInput; // Primeiro valor em metros
cin >> kmInput; // Segundo valor em quilômetros
// Converter strings para doubles usando std::stod()
double metersValue = stod(metersInput);
double kmValue = stod(kmInput);
// Definir a formatação de saída
cout << fixed << setprecision(2);
// TODO: Criar o primeiro objeto Distance e defini-lo usando o valor em metros
// TODO: Imprimir "In meters: <value> m"
// TODO: Imprimir "In centimeters: <value> cm"
// TODO: Imprimir "In kilometers: <value> km"
// TODO: Criar o segundo objeto Distance e defini-lo usando o valor em quilômetros
// TODO: Somar as duas distâncias usando o método add()
// TODO: Imprimir "Combined in meters: <value> m"
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 OOP
Arquivos ExternosBuild e Compilação em C++Arquivos Header e SourceNamespaces e EscopoIntrodução a OOP em C++Classes vs ObjetosO Ponteiro 'this'Métodos (Funções Membro)Atributos (Membros de Dados)Básico de Ctors e DtorsRecapitulação - Calculadora Simples4Propriedades de Classe
Membros de Instância vs EstáticosGetters e SettersFunções de Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRecapitulação - Gerenciador de Conta Bancária7Herança
Herança BásicaNíveis de Acesso na HerançaOrdem de Chamada de Ctor e DtorSobrescrita de MétodosFunções Virtuais e VTableHerança MúltiplaHerança VirtualRecapitulação - Hierarquia de Funcionários2Gerenciamento de Memória
Memória Stack vs HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Smart Pointers em C++RAII em C++Recapitulação - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de Acesso em C++Especificadores de Acesso em DetalhesOcultação de InformaçãoStruct vs ClassClasses Aninhadas e InternasRecapitulação - Sistema de Registros de Alunos8Polimorfismo
Polimorfismo de Compilação vs Tempo de ExecuçãoSobrecarga de FunçõesFunções Virtuais RevisitadasFunções Virtuais PurasClasses AbstratasDesign de Interfaces em C++Dynamic Casting e RTTIRecapitulação - Calculadora de Formas3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentaçãoListas de Inicialização do ConstrutorConstrutores DelegadosMergulho Profundo em DestrutoresRegra dos Três / Cinco / ZeroRecapitulação - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de StreamSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçãoTemplates de ClasseEspecialização de TemplatesTemplates VariádicosFundamentos de SFINAE e Type TraitsRecapitulação - Container Genérico