Menu
Coddy logo textTech

Spécificateurs d’accès en profondeur

Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy. Leçon 35 sur 104.

Maintenant que vous comprenez les trois spécificateurs d’accès, examinons leur comportement lorsque vous avez plusieurs objets de la même classe. Une idée reçue courante est que private signifie « uniquement cet objet » — mais cela signifie en réalité « uniquement cette classe ».

Les objets d’une même classe peuvent accéder aux membres privés les uns des autres :

class Person {
    std::string secret;
    
public:
    Person(std::string s) : secret(s) {}
    
    void readSecret(const Person& other) {
        // Accéder au membre privé d'un autre objet - autorisé !
        std::cout << other.secret;
    }
};

Cela fonctionne parce que le contrôle d’accès est appliqué au niveau de la classe, et non au niveau de l’objet. La méthode readSecret fait partie de la classe Person, elle peut donc accéder aux membres privés de tout objet Person. Cette conception permet à des opérations telles que les constructeurs de copie et les opérateurs de comparaison de fonctionner avec l’état interne d’autres objets.

Vous pouvez également alterner plusieurs fois entre les spécificateurs d’accès au sein d’une classe :

class Mixed {
public:
    void publicMethod1();
    
private:
    int privateData;
    
public:
    void publicMethod2();    // Retour au public
    
private:
    void privateHelper();    // Privé à nouveau
};

Bien que ce soit du C++ valide, il est généralement préférable de regrouper les membres par niveau d’accès pour améliorer la lisibilité. La plupart des guides de style recommandent de lister d’abord les membres publics (puisqu’ils constituent l’interface de la classe), suivis des membres protégés, puis des membres privés.

challenge icon

Défi

Facile

Construisons un système de comparaison de portefeuilles qui montre comment des objets de la même classe peuvent accéder aux membres privés les uns des autres. Il s’agit d’un point essentiel concernant le contrôle d’accès de C++ : il est appliqué au niveau de la classe, et non au niveau de l’objet.

Vous allez créer deux fichiers pour organiser votre code :

  • Wallet.h : définissez une classe Wallet qui stocke des données financières privées, mais permet les comparaisons entre portefeuilles. Votre classe doit comporter :
    • Membres privés : ownerName (chaîne de caractères) et balance (double)
    • Un constructeur qui prend le nom du propriétaire et le solde initial
    • Un accesseur public getOwnerName() qui renvoie le nom du propriétaire
    • Une méthode hasMoreThan(const Wallet& other) qui compare le solde de ce portefeuille au solde privé d’un autre portefeuille et renvoie true si ce portefeuille contient davantage d’argent
    • Une méthode combinedBalance(const Wallet& other) qui renvoie la somme des soldes privés des deux portefeuilles
    • Une méthode transferTo(Wallet& other, double amount) qui transfère de l’argent de ce portefeuille vers un autre. Elle doit modifier directement les soldes privés des deux portefeuilles (uniquement si le montant est positif et ne dépasse pas le solde de ce portefeuille)
  • main.cpp : démontrez l’accès aux membres privés entre objets. Lisez deux noms de propriétaires et deux soldes depuis l’entrée (quatre lignes : name1, balance1, name2, balance2), puis :
    • Créez deux objets Wallet avec les valeurs saisies
    • Affichez "Combined wealth: $<amount>" à l’aide de combinedBalance()
    • Comparez les portefeuilles et affichez "<name> has more money" pour le propriétaire dont le solde est le plus élevé (utilisez hasMoreThan() pour le déterminer)
    • Transférez 100.0 du premier portefeuille vers le second à l’aide de transferTo()
    • Affichez "After transfer:"
    • Affichez à nouveau "Combined wealth: $<amount>" (le résultat doit être inchangé)
    • Comparez à nouveau et affichez "<name> has more money" (le résultat peut avoir changé)

Le concept essentiel ici est que des méthodes comme hasMoreThan() et transferTo() peuvent accéder directement au membre privé Wallet d’un autre objet balance : aucun accesseur n’est nécessaire. Cela fonctionne parce que le contrôle d’accès en C++ est fondé sur la classe : tout code situé à l’intérieur de la classe Wallet peut accéder aux membres privés de n’importe quel objet Wallet.

Formatez toutes les valeurs monétaires avec deux décimales en utilisant std::fixed et std::setprecision(2) de <iomanip>. Convertissez les entrées de solde à l’aide de std::stod().

Essayez vous-même

#include <iostream>
#include <string>
#include <iomanip>
#include "Wallet.h"

using namespace std;

int main() {
    // Lire l'entrée : name1, balance1, name2, balance2
    string name1, name2;
    string balanceStr1, balanceStr2;
    
    getline(cin, name1);
    getline(cin, balanceStr1);
    getline(cin, name2);
    getline(cin, balanceStr2);
    
    double balance1 = stod(balanceStr1);
    double balance2 = stod(balanceStr2);
    
    // Définir le formatage de sortie pour les valeurs monétaires
    cout << fixed << setprecision(2);
    
    // TODO: Créer deux objets Wallet avec les valeurs d'entrée
    
    // TODO: Print combined wealth using combinedBalance()
    // Format: "Combined wealth: $<amount>"
    
    // TODO: Compare wallets using hasMoreThan() and print who has more money
    // Format: "<name> has more money"
    
    // TODO: Transférer 100.0 du premier wallet au second en utilisant transferTo()
    
    // TODO: Print "After transfer:"
    
    // TODO: Print combined wealth again
    
    // TODO: Compare again and print who has more money
    
    return 0;
}
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur C++ en ligne