Classes et objets C ++ (on) - les concepts de base des classes, des qualificateurs de classe et de l'encapsulation et ce pointeur de fonctions membres de classe

Un, le concept de base de la classe

1.1 Définition de classe

class className
{
    
    
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
  • Class est le mot-clé pour définir la classe , ClassName est le nom de la classe , {} est le corps principal de la classe , faites attention au point - virgule après la fin de la définition de la classe .
  • Les éléments de la classe sont appelés les membres de la classe; les données de la classe sont appelées les attributs ou les variables membres de la classe; les fonctions de la classe sont appelées les méthodes ou les fonctions membres de la classe .

1.2 Deux façons de définir une classe

  1. Les déclarations et définitions sont toutes placées dans le corps de la classe. Remarque: si une fonction membre est définie dans la classe , le compilateur peut la traiter comme une fonction en ligne .
    Insérez la description de l'image ici
  2. La déclaration est placée dans le fichier .h et la définition de classe est placée dans le fichier .cpp (généralement de cette façon)
    Insérez la description de l'image ici

Deuxièmement, le qualificatif d'accès et l'emballage de la classe

2.1 Qualifiant d'accès

C ++ réalise le mode d'encapsulation: utilisez des classes pour combiner les propriétés et les méthodes de l'objet pour rendre l'objet plus complet, et fournissez sélectivement son interface aux utilisateurs externes via des autorisations d'accès .

Insérez la description de l'image ici
Description du qualificatif d'accès :

  1. Les membres publics modifiés sont directement accessibles en dehors de la classe
  2. Les membres modifiés protégés et privés ne sont pas accessibles directement en dehors de la classe
  3. L' étendue des droits d'accès commence à partir de l'endroit où le qualificatif d'accès apparaît jusqu'à ce que le qualificatif d'accès suivant apparaisse
  4. L'autorisation d'accès par défaut de la classe est privée et struct est publique (car struct est compatible avec C)

Remarque: le qualificatif d'accès n'est utile qu'au moment de la compilation. Une fois les données mappées à la mémoire, il n'y a aucune différence dans le qualificatif d'accès.

Q1: Quelle est la différence entre struct et class en C ++?

C ++ doit être compatible avec le langage C, donc struct en C ++ peut être utilisé comme structure. De plus, struct en C ++ peut également être utilisé pour définir des classes. C'est la même chose que la classe qui définit la classe. La différence est que la méthode d'accès par défaut des membres de struct est publique et la méthode d'accès par défaut des membres de la classe est privée.

2.2 Emballage

Q1: Trois caractéristiques de l'orientation objet

Encapsulation, héritage, polymorphisme.

Q2: Au stade de la classe et de l'objet, nous étudions uniquement les fonctionnalités d'encapsulation Qu'est-ce que l'encapsulation?

Encapsulation: combinez les données et les méthodes de manipulation des données de manière organique, masquez les propriétés et les détails d'implémentation de l'objet et n'exposez l'interface qu'à l'extérieur pour interagir avec l'objet.
L'encapsulation est essentiellement une sorte de gestion: comment gérer les guerriers en terre cuite? Par exemple, s'il ne reste rien, les guerriers en terre cuite seront détruits à volonté. Ensuite, nous avons d'abord construit une maison pour encapsuler les guerriers en terre cuite. Mais notre objectif est tout encapsulé et ne pas laisser les autres le voir. Par conséquent, nous avons ouvert le canal de vente de billets et pouvons acheter des billets pour percer le paquet et entrer sous un mécanisme de supervision raisonnable. Il en va de même pour les classes: nous utilisons des données de classe et des méthodes pour les encapsuler ensemble. Je ne veux pas que les autres voient, nous utilisons protected / private pour encapsuler les membres . Ouvrez certaines fonctions communes aux membres pour un accès raisonnable aux membres. L' encapsulation est donc essentiellement une sorte de gestion.

Troisièmement, la portée et l'instanciation de la classe

3.1 Portée de la classe

La classe définit une nouvelle portée et tous les membres de la classe sont dans la portée de la classe. Pour définir des membres en dehors de la classe, vous devezUtilisez :: scope resolver pour spécifier à quel domaine de classe un membre appartient

class Person
{
    
    
public:
	void PrintPersonInfo();
private:
	char _name[20];
	char _gender[3];
	int _age;
};

// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{
    
    
cout<<_name<<" "_gender<<" "<<_age<<endl;
}

3.2 Instanciation de la classe

Le processus de création d'objets avec des types de classe est appelé instanciation de classe

  1. Une classe est juste une chose semblable à un modèle, qui limite les membres de la classe, définit une classe et n'alloue pas d'espace mémoire réel pour la stocker
  2. Une classe peut instancier plusieurs objets, les objets instanciés occupent un espace physique réel et stocker des variables de membre de classe
  3. Faites une analogie. Instancier des objets de classe, c'est comme construire une maison à l'aide de dessins de conception architecturale dans la réalité. Les classes sont comme des dessins de conception , ne concevant que ce qui est nécessaire, mais il n'y a pas de bâtiment physique. La même classe est juste une conception, les objets instanciés peuvent en fait stocker des données et occuper espace physique
    Insérez la description de l'image ici

Quatrièmement, le modèle d'objet de classe

4.1 Comment calculer la taille d'un objet de classe?

Il peut y avoir à la fois des variables membres et des fonctions membres dans une classe, alors qu'est-ce qui est contenu dans un objet d'une classe? Comment calculer la taille d'une classe?

4.2 Deviner la méthode de stockage des objets de classe

  • L'objet contient chaque membre de la classe.
    Insérez la description de l'image ici
    Inconvénient: les variables membres de chaque objet sont différentes, mais la même fonction est appelée. Si elle est stockée de cette manière, lorsqu'une classe crée plusieurs objets, chaque objet enregistre un code, enregistrez le même code plusieurs fois, gaspillant de l'espace. Alors, comment le résoudre?

  • Seules les variables membres sont stockées et les fonctions membres sont stockées dans le segment de code commun.
    Insérez la description de l'image ici
    Insérez la description de l'image ici
    Question: Pour les deux méthodes de stockage ci-dessus, dans quel type de méthode l'ordinateur stocke-t-il?
    Analysons et voyons en obtenant les tailles des différents objets ci-dessous.

#include<iostream>
using namespace std;

class A1{
    
    
public:
  void f1(){
    
    };
  private:
  int _a;
};
// 类中仅有成员函数
class A2 {
    
    
public:
  void f2() {
    
    }
};
// 类中什么都没有---空类
class A3
  {
    
    };

int main()
{
    
    
  cout<<sizeof(A1)<<endl;
  cout<<sizeof(A2)<<endl;
  cout<<sizeof(A3)<<endl;
  return 0;
}

résultat
Insérez la description de l'image ici

4.3 La conclusion du calcul de la taille de la classe

Conclusion:
La taille d'une classe est en fait la somme des "variables membres" de la classe. Bien sûr, l'alignement mémoire doit être effectué. Faites attention à la taille de la classe vide. La classe vide est spéciale. Le compilateur donne le classe vide un octet pour identifier de manière unique cette classe.

Cinq, ce pointeur

5.1 Sortir de ce pointeur

Nous définissons d'abord une classe de date

#include<iostream>
using namespace std;

class Date
{
    
    
public:
  void Init(int year, int month, int day)
  {
    
    
    _year = year;
    _month = month;
    _day = day;
  }

  void Print()
  {
    
    
    cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
  }

private:
  int _year;
  int _month;
  int _day;
};

int main()
{
    
    
  Date d1,d2;
  d1.Init(2021,3,1);
  d1.Print();
  d2.Init(2021,2,28);
  d2.Print();
  return 0;
}

Par conséquent
Insérez la description de l'image ici
, il existe deux fonctions membres Init et Print dans la classe Date. Il n'y a pas de distinction entre les différents objets dans le corps de la fonction. Lorsque d1 appelle la fonction Init, comment la fonction sait-elle qu'elle doit définir l'objet d1 au lieu de l'objet d2?

C ++ résout ce problème en introduisant le pointeur this, c'est-à-dire: Le compilateur C ++ ajoute un paramètre de pointeur masqué à chaque "fonction membre non statique", de sorte que le pointeur pointe vers l'objet actuel (l'objet qui appelle la fonction lorsque la fonction est en cours d'exécution), toutes les opérations sur les variables membres dans le corps de la fonction sont accessibles via ce pointeur. C'est juste que toutes les opérations sont transparentes pour l'utilisateur, c'est-à-dire que l'utilisateur n'a pas besoin de le passer, et le compilateur le termine automatiquement.
Insérez la description de l'image ici

5.2 Caractéristiques de ce pointeur

  1. Le type de ce pointeur: type de classe * const, la
    manière suivante est incorrecte
  void Init(Date* this, int year, int month, int day)
  {
    
    
  	//this是隐含的,实参和形参的位置我们不能手动添加会报错
    _year = year;
    _month = month;
    _day = day;
  }

  1. Ce pointeur ne peut être utilisé qu'à l'intérieur de "fonctions membres"
  void Init(int year, int month, int day)
  {
    
    
    cout<<"this:"<<this<<endl;
    this->_year = year;
    this-> _month = month;
    this-> _day = day;
  }

Insérez la description de l'image ici

  1. Le pointeur this est en fait un paramètre formel d'une fonction membre. Lorsqu'un objet appelle une fonction membre, l'adresse de l'objet est transmise au paramètre this en tant que paramètre réel. Ainsi, ce pointeur n'est pas stocké dans l'objet.
  2. Le pointeur this est le premier paramètre de pointeur implicite de la fonction membre. En règle générale, il est automatiquement transmis par le compilateur via le registre ecx et n'a pas besoin d'être transmis par l'utilisateur.

Q1: Où ce pointeur existe-t-il?

Le pointeur this est en fait un paramètre formel d'une fonction membre. Lorsqu'un objet appelle une fonction membre, l'adresse de l'objet est transmise au paramètre this en tant que paramètre réel. Ainsi, ce pointeur n'est pas stocké dans l'objet. En d'autres termes, le pointeur this existe dans la pile, mais afin d'améliorer l'efficacité dans vs, le pointeur this existe dans le registre ecx
Insérez la description de l'image ici

Q2: ce pointeur peut-il être nul?

Nous utilisons le programme suivant pour analyser

class A
{
    
    
public:
	void PrintA()
	{
    
    
		cout<<_a<<endl;
	}
	void Show()
	{
    
    
		cout<<"Show()"<<endl;
	}
private:
	int _a;
};

int main()
{
    
    
	A* p = NULL;
	p->PrintA();
	p->Show();
	return 0;
}

Le code ci-dessus peut être compilé et passé, mais p-> PrintA () plantera lorsqu'il est exécuté séparément, mais p-> Show () peut fonctionner.
Insérez la description de l'image ici
Insérez la description de l'image ici
Raison: bien
Insérez la description de l'image ici
que p soit un pointeur nul, les fonctions membres de la classe sont stockées dans le segment de code public, pas dans l'objet, et p n'est pas déréférencé lors de l'appel, donc Print ne plantera pas.

Je suppose que tu aimes

Origine blog.csdn.net/qq_40076022/article/details/113999669
conseillé
Classement