C++ Modificateurs d'accès des classes

Classes et objets C++

En programmation orientée objet (POO) en C++, l'encapsulation des données est l'un des concepts fondamentaux. En termes simples, cela signifie "cacher" les données et n'exposer que les interfaces nécessaires au monde extérieur pour garantir la sécurité des données.

Pour contrôler qui peut voir ces données, C++ fournit trois mots-clés, appelésModificateurs d'accès:

  • public(public)
  • private(private)
  • protected(protected)
class Base { public: //Membres publics protected: // Membres protégés private: // Membres privés };

Pour faciliter la compréhension, nous pouvons considérer uneclasse comme votre maison:

Modificateurs Analogie avec le monde réel Qui peut y accéder ? Utilisation typique
public Salon/Porte d'entrée Tout le monde(à l'intérieur de la classe, des sous-classes, du code externe) Fonctions d'interface (API) fournies au monde extérieur.
protected Chambre Vous et vos enfants(à l'intérieur de la classe, des sous-classes) Données utilisées uniquement au sein de la famille (hiérarchie d'héritage).
private Coffre-fort Uniquement soi-même(uniquement au sein de la classe elle-même) Données essentielles, variables qui ne doivent pas être modifiées à la légère.

Remarque: Si aucun modificateur n'est écrit, les membres d'une classe C++La valeur par défaut estprivate(private).

membres publics

publicLes membres sont accessibles n'importe où dans le programme sans lire ni écrire via les fonctions membres, comme le montre l'exemple suivant :

Exemple

#include <iostream> using namespace std; class Line { public: double length; void setLength( double len ); double getLength( void ); }; // Définition de la fonction membre double Line::getLength(void) { return length ; } void Line::setLength( double len ) { length = len; } // La fonction principale du programme int main( ) { Line line; // Définir la longueur line.setLength(6.0); cout << "Longueur de la ligne : " << line.getLength() <<endl; // Définir la longueur sans utiliser de fonction membre line.length = 10.0; // OK : car length est public cout << "Longueur de la ligne : " << line.length <<endl; return 0; }

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

Length of line : 6
Length of line : 10

membres privés

Les membres privés sont complètement fermés à l'extérieur de la classe ; le code externe ne peut ni les lire, ni les modifier, ni les appeler, et les classes dérivées n'ont pas non plus de droits d'accès directs. Seules les fonctions membres de la classe elle-même et les entités auxquelles l'autorisation friend a été accordée peuvent agir sur ces contenus.

Si aucun spécificateur d'accès n'est utilisé dans la classe, les membres sont privés par défaut. Comme le montre l'exemple ci-dessous, width tombe automatiquement dans la zone privée, ce qui indique que les membres non explicitement marqués sont tous traités comme privés :

Exemple

class Box { double width; public: double length; void setWidth( double wid ); double getWidth( void ); };

En pratique, nous définissons généralement les données dans la section privée et définissons les fonctions associées dans la section publique, afin que ces fonctions puissent également être appelées en dehors de la classe, comme montré ci-dessous :

Exemple

#include <iostream> using namespace std; class Box { public: double length; void setWidth( double wid ); double getWidth( void ); private: double width; }; // Définition de fonction membre double Box::getWidth(void) { return width ; } void Box::setWidth( double wid ) { width = wid; } // La fonction principale du programme int main( ) { Box box; // Définir length sans utiliser de fonction membre box.length = 10.0; // OK : car length est public cout << "Longueur de la boîte : " << box.length <<endl; // Définir la largeur sans utiliser de fonction membre // box.width = 10.0; // Erreur : car width est privée box.setWidth(10.0); // Définir la largeur à l'aide d'une fonction membre cout << "Largeur de box : " << box.getWidth() <<endl; return 0; }

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

Length of box : 10
Width of box : 10

membres protégés

protectedL'existence de ... sert principalement àl'héritage。

  • S'il n'y a pas d'héritage, il estprivateidentique (non visible de l'extérieur).
  • S'il y a héritage,une sous-classe (classe dérivée) peut accéder auprotectedmembre de la classe parente, mais ne peut pas accéder auxprivatemembres.

Dans le chapitre suivant, vous découvrirez les classes dérivées et l'héritage. Maintenant, vous pouvez voir dans l'exemple ci-dessous que, à partir de la classe parenteBox, nous avons dérivé une sous-classesmallBox。

L'exemple ci-dessous est similaire à l'exemple précédent ; iciwidthpeut être accédé par toute fonction membre de la classe dérivée smallBox.

Exemple

#include <iostream> using namespace std; class Box { protected: double width; }; class SmallBox:Box // SmallBox est une classe dérivée { public: void setSmallWidth( double wid ); double getSmallWidth( void ); }; // Fonction membre de la classe dérivée double SmallBox::getSmallWidth(void) { return width ; } void SmallBox::setSmallWidth( double wid ) { width = wid; } // La fonction principale du programme int main( ) { SmallBox box; // Définir la largeur à l'aide d'une fonction membre box.setSmallWidth(5.0); cout << "Largeur de la boîte : "<< box.getSmallWidth() << endl; return 0; }

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

Width of box : 5

Modifications des permissions d'accès lors de l'héritage

Lorsque vous définissez une sous-classe (commeclass B : public A), après les deux-pointspublicest aussi un modificateur d'accès ; il déterminecomment les membres de la classe parente « apparaissent » dans la classe enfant。

Cela semble compliqué, mais vous devez seulement retenir ceciPrincipe de rétrogradation:

Le mode d'héritage détermine l'autorisation la plus élevée que les membres de la classe parente ont dans la classe enfant.
Si le mode d'héritage est plus strict que l'autorisation d'origine du membre, l'autorisation du membre est « rétrogradée » au niveau du mode d'héritage.

Tableau de modification des accès

les droits d'accès d'origine des membres de la classe de base héritage public(le plus couramment utilisé) héritage protected héritage private
public restent public rétrogradé à protected rétrogradée en privé
protected restent protégées restent protégées rétrogradée en privé
private Inaccessible Inaccessible Inaccessible

Note : inaccessible signifie que le code de la classe enfant ne peut pas utiliser directement la variable, mais la variable existe toujours en mémoire.

code de démonstration complet

Pour plus de clarté, nous renommons la variable enpub_var(public),pro_var(protected),pri_var(private).

Exemple

#include <iostream>
using namespace std;

class Parent {
public:
    int pub_var;
protected:
    int pro_var;
private:
    int pri_var; // Seul Parent lui-même peut y accéder

public:
    Parent() { pub_var = 1; pro_var = 2; pri_var = 3; }
};

// 1. Héritage public - le plus courant, fidèle à l'original
class ChildA : public Parent {
public:
    void test() {
        cout << pub_var << endl; // OK
        cout << pro_var << endl; // OK
        // cout << pri_var << endl; // Erreur ! Les membres privés de la classe Parent ne sont pas visibles
    }
};

// 2. Héritage protégé - tout devient protégé
class ChildB : protected Parent {
public:
    void test() {
        cout << pub_var << endl; // OK, mais du point de vue de ChildB, il est protégé
        cout << pro_var << endl; // OK
    }
};

// 3. Héritage privé - tout devient privé
class ChildC : private Parent {
public:
    void test() {
        cout << pub_var << endl; // OK, mais du point de vue de ChildC, c'est privé
        cout << pro_var << endl; // OK, mais du point de vue de ChildC, c'est privé
    }
};

int main() {
    ChildA a;
    cout << a.pub_var << endl; // OK, accessible de l'extérieur
    // cout << a.pro_var << endl; // Erreur, protected n'est pas accessible de l'extérieur

    ChildB b;
    // cout << b.pub_var << endl; // Erreur ! Parce que c'est un héritage protégé, pub_var devient protégé en externe

    ChildC c;
    // cout << c.pub_var << endl; // Erreur ! Parce que c'est un héritage privé, pub_var devient privé en externe

    return 0;
}

Résumé

  • Public: Tout le monde peut l'utiliser. Utilisé comme interfaces (API).
  • Privé: Seul lui-même peut l'utiliser. Utilisé pour stocker des données (option sûre par défaut).
  • Protégé: Seule la famille (chaîne d'héritage) peut l'utiliser. Utilisé pour laisser une porte dérobée aux classes filles.

Héritage:

  • Héritage public: Les attributs de la classe parente restent inchangés (le plus couramment utilisé).
  • Héritage privé/protégé: Restreindra les permissions des membres de la classe parente, généralement utilisé dans des scénarios d'implémentation particuliers.

Classes et objets C++

autres extensions