2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Table des matières
4.Fonctions membres par défaut des classes
Format de définition de classe
class est le mot-clé qui définit la classe, Stack est le nom de la classe et {} est le corps de la classe. Notez que le point-virgule à la fin de la définition n'est pas omis. Le contenu du corps de la classe est appelé membres de la classe : les variables de la classe sont appelées attributs ou les variables membres de la classe, les fonctions de la classe sont appelées méthodes ou fonctions membres de la classe.
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
- //成员变量
- int* a;
- int top;
- int capacity;
- //成员函数
- void Push()
- {
-
- }
- void Pop()
- {
-
- }
- };//分号不能省略
- int main()
- {
-
-
- return 0;
- }
- //为区分成员变量,一般前面加_
- //成员变量
- int* _a;
- int _top;
- int _capacity;
C++ est un moyen d'implémenter l'encapsulation, en utilisant des classes pour combiner les propriétés et les méthodes d'un objet afin de rendre l'objet plus complet et de fournir de manière sélective son interface aux utilisateurs externes via des droits d'accès.
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
-
- ///
-
- void Push()
- {
-
- }
- //Push 没给限定符 class默认私有 private
- ///
- public:
- void Pop()
- {
-
- }
- int Swap()
- {
-
- }
- //Pop和Swap 被public修饰,直到下一个限定符出现之前都为公有
- ///
- protected:
- int add();
- //add 被public修饰,直到下一个限定符出现之前都为保护
- /// /
-
- private:
-
- int* _a;
- int _top;
- int _capacity;
- //成员变量被private修饰,直到}结束都为私有
- };
- int main()
- {
- Stack st;
- //公有可以访问
- st.Pop();
- st.Swap();
- //私有不可访问
- st._top;
-
-
-
- return 0;
- }
Notes complémentaires:
La classe définit une nouvelle portée.Tous les membres de la classe sont dans la portée de la classe. Lorsque vous définissez des membres en dehors de la classe, vous devez utiliser l'opérateur ::scope pour indiquer à quelle portée de classe appartient le membre.
Le domaine de classe affecte les règles de recherche de compilation. Si Init dans le programme suivant ne spécifie pas le domaine de classe Stack, le compilateur traitera Init comme une fonction globale. S'il ne trouve pas de membres tels que _top lors de la compilation, il ira dans le domaine de classe. domaine de classe pour les trouver.
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
-
- public:
- void Init(int x, int y);
-
- };
- void Stack::Init(int x, int y)
-
- {
- _top = x;
- _capacity = y;
- }
- int main()
- {
-
- return 0;
- }
Avis:
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
- //声明
-
- int* _a;
- int _top;
- int _capacity;
-
- };
-
- int main()
- {
-
- Stack::_top = 2024;
- //编译器报错,_top只是声明,并未实例化
-
- return 0;
- }
-
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
-
- //声明
- int* _a;
- int _top;
- int _capacity;
-
- };
-
- int main()
- {
-
-
- Stack st;
- st._top=2024;
- //Stack实例化出st,系统已经给st分配内存了,可以存储数据,编译通过
-
- return 0;
- }
-
-
Règles d'alignement de la mémoire
- class A
- {
- public:
- void Print()
- {
- cout << _ch << endl;
- }
- private:
- char _ch;
-
- int _i;
- };
- //_ch 是一个字节,默认对齐数是4,最大对齐数是4,所以开辟4个字节用来存在_ch
- // _i是4个字节,默认对齐数是4,最大对齐数是4,所以开辟4个字节用来存储_i
- class B
- {
- public:
- void Print()
- {
- //。。。
- }
-
-
- };
- class B
- {
-
-
- };
- //B和C里面没有存储任何成员变量,只有一个函数,可成员函数不存对象里面
- // 按理来说是0,但是结构体怎么会没大小,为表示对象存在C++对这种规定大小为1,为了占位标识对象存在
Une fois le compilateur compilé, les fonctions membres de la classe ajouteront par défaut un pointeur vers la classe actuelle en première position du paramètre formel, appelé ce pointeur.
Par exemple, le prototype Init dans la classe Date est void Init (Date * const this, int year, intmonth, int day). Lors de l'accès aux variables membres dans les fonctions membres de la classe, l'essence est accessible via le pointeur this, comme _year dans la fonction Init, this->_year=year.
prototype:
- class Date
- {
- void Print()
- {
-
- cout << _year << "n" << _month << "n" << _day << endl;
- }
- void Init( int year, int month,int day)
- {
- _year = year;
- _month = month;
- _day = day;
-
- }
-
- private:
- int _year;
- int _month;
- int _day;
-
- };
-
- Date d1;
- d1.Init(2024,7,10);
-
- d1.Print();
- Date d2;
-
- d2.Init(2024, 7, 9);
- d2.Print();
-
vrai prototype
- class Date
- {
- void Init(Date* const this,int year, int month,int day)
-
- {
- this->_year = year;
- this->_month = month;
- this->_day = day;
-
- }
- void Printf(Date* const this)
-
- {
-
- cout << this->_year << "n" <<this-> _month << "n" << this->_day << endl;
- }
- private:
- int _year;
- int _month;
- int _day;
-
- };
- Date d1;
- d1.Init(&d1,2024,7,10);
- d1.Print(&d1);
-
- Date d2;
- d2.Init(&d2,2024, 7, 9);
- d2.Print();
C++ stipule qu'il n'est pas autorisé d'écrire ce pointeur à la place des paramètres réels et des paramètres formels (le compilateur le gérera lors de la compilation), mais ce pointeur peut être utilisé explicitement dans le corps de la fonction. Ce pointeur ne peut pas être modifié, mais le. le contenu pointé par ce pointeur peut
ce pointeur est stocké sur la pile
La fonction membre par défaut est une fonction membre qui n'est pas explicitement définie par l'utilisateur et qui est automatiquement générée par le compilateur. Elle est appelée fonction membre par défaut.
Le constructeur est une fonction membre spéciale. Il convient de noter que bien que le constructeur soit appelé constructeur, le contenu principal du constructeur n'est pas d'ouvrir de l'espace pour créer des objets (l'objet local que nous utilisons habituellement est l'espace qui est ouvert lorsque le cadre de pile est créé) ), mais l'objet est initialisé lorsque l'objet est instancié. L'essence du constructeur est de remplacer la fonction de la fonction Init que nous avons écrite auparavant dans les classes Stack et Date. L'appel automatique du constructeur remplace parfaitement la fonction Init.
Caractéristiques du constructeur :
- class Date
- {public:
- //1.无参构造函数
- Date()
- {
- _year = 1;
- _month = 1;
- _day = 1;
- }
- //2.带参构造函数
- Date(int year, int month, int day)
- {
- _year = year;
- _month = month;
- _day = day;
- }
-
-
- //3.全缺省构造函数
- Date(int year = 1, int month = 1, int day = 1)
- {
- _year = year;
- _month = month;
- _day = day;
- }
- private:
- int _year;
- int _month;
- int _day;
-
- };
Le constructeur sans paramètre, le constructeur par défaut et le constructeur généré par le compilateur par défaut lorsque nous n'écrivons pas de constructeur sont tous appelés constructeurs par défaut. Mais un seul de ces trois peut exister, pas en même temps. Bien que le constructeur sans paramètre et le constructeur par défaut complet constituent une surcharge de fonctions, il y aura une ambiguïté lors de leur appel.Notez que non seulement le constructeur par défaut est celui généré par le compilateur par défaut, c'est le constructeur, le constructeur sans paramètre, et le constructeur par défaut complet est également le constructeur par défaut. Pour résumer, il peut être appelé sans passer de paramètres.
Nous ne l'écrivons pas.La construction générée par le compilateur n'a aucune exigence pour l'initialisation des variables membres de type intégrées. Il est incertain qu'elle soit initialisée ou non, cela dépend du compilateur.
- //text.cpp
- #include<iostream>
- using namespace std;
- typedef int STDataType;
- class Stack
- {
- public:
- Stack(int n = 4)
- {
- _a = (STDataType*)malloc(sizeof(STDataType) * n);
- if (nullptr == _a)
- {
- perror("malloc申请失败");
- }
- _capacity = n;
- _top = 0;
- }
-
- private:
- STDataType* _a;
- size_t _capacity;
- size_t _top;
- };
- //两个Stack实现队列
- class MyQueue
- {
- private:
- int size;
- Stack pushst;
- Stack popst;
- };
-
- int main()
- {
-
- MyQueue my;
-
-
- return 0;
- }
-
C++ divise les types en types personnalisés et types intégrés (types de base). Les types intégrés sont les types de données natifs fournis par le langage, tels que int/char/double/pointer, etc. Les types personnalisés sont des types que nous définissons nous-mêmes à l'aide de mots-clés tels que class/struct.Le constructeur ici est automatiquement initialisé et VS initialise également la taille de type intégrée. Différents compilateurs ont des valeurs d'initialisation différentes et C++ ne les spécifie pas.
Pour les variables membres de type personnalisé, il est nécessaire d'appeler le constructeur par défaut de cette variable membre pour l'initialiser.Si cette variable membre n'a pas de constructeur par défaut, une erreur sera signalée. Si nous voulons initialiser cette variable membre, nous devons utiliser une liste d'initialisation pour la résoudre.
Résumé : Dans la plupart des cas, nous devons implémenter le constructeur nous-mêmes. Dans quelques cas, il est similaire à MyQueue et lorsque Stack a un constructeur par défaut, MyQueue peut être automatiquement généré et utilisé.
- ~Stack()
- {
- free(_a);
- _a = nullptr;
- _top = _capacity = 0;
- }
Caractéristiques du destructeur :
1. Le nom du destructeur est précédé de caractères~
2. Aucun paramètre et aucune valeur de retour (conforme au constructeur)
3. Une classe ne peut avoir qu’un seul destructeur.Si la définition n'est pas affichée, le système générera automatiquement un destructeur par défaut.
4. Lorsque le cycle de déclaration d'objet se termine, le système appellera automatiquement le destructeur.
5. Semblable au constructeur, nous n'écrivons pas le destructeur généré automatiquement par le compilateur et ne traitons pas les membres de type intégrés qui appelleront d'autres destructeurs.
6. Il convient également de noter que lorsque nous affichons le destructeur, le destructeur du membre de type personnalisé sera également appelé, ce qui signifie que le destructeur du membre de type personnalisé sera automatiquement appelé quelle que soit la situation.
- //text.cpp
- #include<iostream>
- using namespace std;
- typedef int STDataType;
- class Stack
- {
- public:
- Stack(int n = 4)
- {
- _a = (STDataType*)malloc(sizeof(STDataType) * n);
- if (nullptr == _a)
- {
- perror("malloc申请失败");
- }
- _capacity = n;
- _top = 0;
-
-
- }
-
- ~Stack()
- {
- free(_a);
- _a = nullptr;
- _top=_capacity=0;
- }
- private:
- STDataType* _a;
- size_t _capacity;
- size_t _top;
-
- };
- //两个Stack实现队列
- class MyQueue
- {public:
- //编译器默认生成MyQueue的构造函数调用了Stack的构造,完成了两个成员的初始化
- //编译器默认生成MyQueue的析构函数调用了Stack的析构,释放了Stack内部的资源
- //显示写析构也会调用Stack的析构
- ~MyQueue()
- {
- cout << "~MyQueue" << endl;
- }
- private:
-
- Stack pushst;
- Stack popst;
-
- };
-
-
- int main()
- {
-
- MyQueue my;
-
-
- return 0;
- }
Le destructeur de MyQueue ne fait rien, mais C++ stipule que d'autres destructeurs seront appelés pour libérer la mémoire.
Si aucune ressource n'est demandée, le destructeur n'a pas besoin d'être écrit et le destructeur par défaut généré par le compilateur peut être utilisé directement, comme Date. Si le destructeur par défaut généré peut être utilisé, il n'est pas nécessaire d'écrire explicitement le destructeur. comme MyQueue, mais il existe une application de ressources lors de la destruction, assurez-vous d'écrire directement le destructeur, sinon cela entraînera une fuite de ressources comme Stack.
-
-
- bool operator<(Date d1, Date d2)
- {
-
- }
- bool operator==(Date d1,Date d2)
- {
- return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day;
- }
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Date
- {
- public:
- Date(int year, int month, int day)
- {
- _year= year;
- _month = month;
- _day = day;
-
- }
-
-
-
- int _year;
- int _month;
- int _day;
-
- };
-
- bool operator<(Date d1, Date d2)
- {
-
- }
- bool operator==(Date d1,Date d2)
- {
- return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day;
- }
- int main()
- {
-
- Date d1(2024, 7, 10);
- Date d2(2024,7,9);
- //两种用法都可以
- d1 == d2;
- operator==(d1 , d2);
- return 0;
- }