Masquage d'information
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy — leçon 36 sur 104.
Le masquage d'informations va au-delà de la simple utilisation des spécificateurs d'accès. C'est un principe de conception selon lequel vous masquez non seulement les données, mais aussi les détails d'implémentation de la manière dont votre classe fonctionne en interne.
L'objectif est d'exposer uniquement ce que les utilisateurs de votre classe ont besoin de savoir, tout en gardant tout le reste caché. Cela vous permet de modifier l'implémentation interne sans affecter le code qui utilise votre classe :
class Temperature {
double kelvin; // Représentation interne - détail caché
public:
void setCelsius(double c) {
kelvin = c + 273.15; // Conversion cachée pour l'utilisateur
}
double getCelsius() const {
return kelvin - 273.15;
}
double getFahrenheit() const {
return (kelvin - 273.15) * 9.0/5.0 + 32;
}
};Les utilisateurs de cette classe ne savent pas (ou n'ont pas besoin de savoir) que la température est stockée en Kelvin en interne. Si vous décidez plus tard de la stocker en Celsius à la place, vous ne modifiez que l'implémentation privée - l'interface publique reste inchangée.
Cette séparation entre l'interface et l'implémentation offre plusieurs avantages : elle réduit la complexité pour les utilisateurs de votre classe, empêche une mauvaise utilisation accidentelle des données internes et rend votre code plus facile à maintenir. Lorsque les détails internes sont masqués, vous êtes libre d'optimiser ou de refactoriser sans casser le code existant qui dépend de votre classe.
Défi
FacileConstruisons une classe Distance qui illustre le masquage d'informations en stockant les distances en interne en mètres tout en fournissant une interface propre pour travailler avec différentes unités. Les utilisateurs de votre classe n'auront pas besoin de savoir (ni de se soucier de) la manière dont la distance est stockée en interne — ils travailleront simplement avec l'unité qui leur convient.
Vous allez créer deux fichiers pour organiser votre code :
Distance.h: Définissez une classeDistancequi masque sa représentation interne tout en exposant une interface publique flexible. En interne, stockez la distance en centimètres (sous forme dedouble) — c'est votre détail d'implémentation masqué. Votre interface publique doit permettre aux utilisateurs de :- Définir la distance en utilisant
setMeters(double m),setCentimeters(double cm), ousetKilometers(double km) - Obtenir la distance en utilisant
getMeters(),getCentimeters(), ougetKilometers()— toutes doivent être des méthodes const - Additionner deux distances avec
add(const Distance& other)qui retourne un nouvel objetDistance
Incluez un constructeur par défaut qui initialise la distance à zéro. La logique de conversion doit être masquée à l'intérieur de vos méthodes — les utilisateurs appellent simplement
setKilometers(5)etgetMeters()sans se soucier du format de stockage interne.- Définir la distance en utilisant
main.cpp: Démontrez que les utilisateurs peuvent travailler avec votre classe sans connaître la représentation interne. Lisez deux valeurs de distance à partir de l'entrée : la première en mètres, la seconde en kilomètres. Ensuite :- Créez un objet
Distanceet définissez-le en utilisant la valeur en mètres - Affichez
"In meters: <value> m" - Affichez
"In centimeters: <value> cm" - Affichez
"In kilometers: <value> km" - Créez un second objet
Distanceet définissez-le en utilisant la valeur en kilomètres - Additionnez les deux distances et stockez le résultat
- Affichez
"Combined in meters: <value> m"
- Créez un objet
La beauté du masquage d'informations est que vous pourriez plus tard changer le stockage interne des centimètres aux millimètres (ou n'importe quoi d'autre) sans changer la façon dont les utilisateurs interagissent avec votre classe. L'interface publique reste stable même si l'implémentation change.
Formatez toutes les valeurs de sortie avec deux décimales en utilisant std::fixed et std::setprecision(2) de <iomanip>. Convertissez les chaînes d'entrée en doubles en utilisant std::stod().
Référence de conversion : 1 mètre = 100 centimètres, 1 kilomètre = 1000 mètres.
Aide-mémoire
Le masquage d'informations est un principe de conception selon lequel vous cachez les détails d'implémentation du fonctionnement interne de votre classe, en n'exposant que ce que les utilisateurs ont besoin de savoir.
Cela vous permet de modifier l'implémentation interne sans affecter le code qui utilise votre classe :
class Temperature {
double kelvin; // Représentation interne - détail caché
public:
void setCelsius(double c) {
kelvin = c + 273.15; // Conversion cachée pour l'utilisateur
}
double getCelsius() const {
return kelvin - 273.15;
}
double getFahrenheit() const {
return (kelvin - 273.15) * 9.0/5.0 + 32;
}
};Les utilisateurs ne savent pas (et n'ont pas besoin de savoir) que la température est stockée en Kelvin en interne. Si vous modifiez ultérieurement le format de stockage, seule l'implémentation privée change - l'interface publique reste inchangée.
Avantages du masquage d'informations :
- Réduit la complexité pour les utilisateurs de votre classe
- Empêche une mauvaise utilisation accidentelle des données internes
- Rend le code plus facile à maintenir et à refactoriser
- Permet l'optimisation sans casser le code existant
Essayez vous-même
#include <iostream>
#include <string>
#include <iomanip>
#include "Distance.h"
using namespace std;
int main() {
// Lire les valeurs d'entrée
string metersInput, kmInput;
cin >> metersInput; // Première valeur en mètres
cin >> kmInput; // Deuxième valeur en kilomètres
// Convertir les chaînes en doubles en utilisant std::stod()
double metersValue = stod(metersInput);
double kmValue = stod(kmInput);
// Définir le formatage de la sortie
cout << fixed << setprecision(2);
// TODO: Créer le premier objet Distance et le définir en utilisant la valeur en mètres
// TODO: Afficher "In meters: <value> m"
// TODO: Afficher "In centimeters: <value> cm"
// TODO: Afficher "In kilometers: <value> km"
// TODO: Créer le deuxième objet Distance et le définir en utilisant la valeur en kilomètres
// TODO: Additionner les deux distances en utilisant la méthode add()
// TODO: Afficher "Combined in meters: <value> m"
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBuild et Compilation C++Fichiers d'en-tête et Fichiers sourceEspaces de noms et PortéeIntroduction à la POO en C++Classes vs ObjetsLe pointeur 'this'Méthodes (Fonctions membres)Attributs (Membres de données)Bases des Ctors et DtorsRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d'instance vs membres statiquesGetters et SettersFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d'accès à l'héritageOrdre d'appel des Ctor et DtorRedéfinition de méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif - Hiérarchie des employés10Présentation de la STL
Présentation et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - Fréquence des mots13Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonFabrique & Fabrique abstraitePatron MonteurPatron ObservateurPatron Stratégie2Gestion de la mémoire
Mémoire Pile vs TasPointeurs et RéférencesMémoire dynamique (new/delete)Smart Pointers en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d'accès en C++Spécificateurs d'accès en profondeurMasquage d'informationStruct vs ClassClasses imbriquées et internesRécapitulatif - Système de gestion d'étudiants8Polymorphisme
Polymorphisme : Compilation vs ExécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d'interfaces en C++Dynamic Casting & RTTIRécapitulatif - Calculateur de formes11Concepts avancés de la POO
Composition vs HéritageMixins via CRTPIdiome PimplEffacement de typeEnum Classes & Typage fortGestion des exceptions en POOHiérarchies d'exceptions personnalisées14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeRAII en tant que patron3Constructeurs et Destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d'initialisation du constructeurConstructeurs déléguésAnalyse approfondie du destructeurRègle de trois / cinq / zéroRécapitulatif - Classe String6Surcharge d'opérateurs
Introduction à la surcharge d'opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l'opérateur d'affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif - Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation de templatesTemplates variadiquesBases de SFINAE & Type TraitsRécapitulatif - Conteneur générique