Mi informacion de contacto
Correo[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Tabla de contenido
4.Funciones miembro predeterminadas de las clases.
Formato de definición de clase
clase es la palabra clave que define la clase, Pila es el nombre de la clase y {} es el cuerpo de la clase. Tenga en cuenta que el punto y coma al final de la definición no se omite. Los contenidos del cuerpo de la clase se denominan miembros de la clase: las variables de la clase se denominan atributos o las variables miembro de la clase las funciones de la clase se denominan métodos o funciones miembro de la clase.
- //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 ++ es una forma de implementar la encapsulación: utiliza clases para combinar las propiedades y métodos de un objeto para hacerlo más completo y proporciona selectivamente su interfaz a usuarios externos a través de derechos de acceso.
- //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;
- }
Notas adicionales:
La clase define un nuevo ámbito. Todos los miembros de la clase están en el ámbito de la clase. Al definir miembros fuera de la clase, debe utilizar el operador ::scope para indicar a qué ámbito de clase pertenece el miembro.
El dominio de clase afecta las reglas de búsqueda de compilación. Si Init en el siguiente programa no especifica la pila de dominio de clase, el compilador tratará a Init como una función global. Si no puede encontrar miembros como _top durante la compilación, irá al. dominio de clase para encontrarlos.
- //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;
- }
Aviso:
- //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;
- }
-
-
Reglas de alineación de la memoria
- 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,为了占位标识对象存在
Después de que el compilador compila, las funciones miembro de la clase agregarán un puntero a la clase actual en la primera posición del parámetro formal de forma predeterminada, llamado este puntero.
Por ejemplo, el prototipo de Init en la clase Date es void Init (Fecha * const this, int año, int mes, int día). Al acceder a variables miembro en las funciones miembro de la clase, se accede a la esencia a través de este puntero. como _año en la función Iniciar, este->_año=año.
prototipo:
- 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();
-
prototipo real
- 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 ++ estipula que no está permitido escribir este puntero en la posición de los parámetros reales y los parámetros formales (el compilador lo manejará al compilar), pero este puntero se puede usar explícitamente en el cuerpo de la función. Este puntero no se puede modificar, pero el. El contenido al que apunta este puntero puede
este puntero se almacena en la pila
La función miembro predeterminada es una función miembro que el usuario no define explícitamente y el compilador la genera automáticamente. Se denomina función miembro predeterminada.
El constructor es una función miembro especial. Cabe señalar que aunque el constructor se llama constructor, el contenido principal del constructor no es abrir espacio para crear objetos (el objeto local que usualmente usamos es el espacio que se abre cuando se abre). se crea el marco de pila)), pero el objeto se inicializa cuando se crea una instancia del objeto. La esencia del constructor es reemplazar la función Init que escribimos antes en las clases Stack y Date. La llamada automática del constructor reemplaza perfectamente la función Init.
Características del constructor:
- 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;
-
- };
El constructor sin parámetros, el constructor predeterminado y el constructor generado por el compilador de forma predeterminada cuando no escribimos un constructor se denominan constructores predeterminados. Pero sólo uno de estos tres puede existir, no al mismo tiempo. Aunque el constructor sin parámetros y el constructor predeterminado completo constituyen una sobrecarga de funciones, habrá ambigüedad al llamarlos.Tenga en cuenta que no solo el constructor predeterminado es el que genera el compilador de forma predeterminada, sino que es el constructor, el constructor sin parámetros, y el constructor predeterminado completo también es el constructor predeterminado. En resumen, se puede llamar sin pasar parámetros.
No lo escribimos. La construcción generada por el compilador de forma predeterminada no tiene requisitos para la inicialización de variables miembro de tipo integradas, es decir, si se inicializa o no, depende del compilador.
- //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++ divide los tipos en tipos personalizados y tipos integrados (tipos básicos). Los tipos integrados son los tipos de datos nativos proporcionados por el lenguaje, como int/char/double/pointer, etc. Los tipos personalizados son tipos que definimos nosotros mismos usando palabras clave como class/struct.El constructor aquí se inicializa automáticamente y VS también inicializa el tamaño de tipo incorporado. Los diferentes compiladores tienen diferentes valores de inicialización y C ++ no los especifica.
Para variables miembro de tipo personalizado, es necesario llamar al constructor predeterminado de esta variable miembro para inicializarla.Si esta variable miembro no tiene un constructor predeterminado, se informará un error. Si queremos inicializar esta variable miembro, necesitamos usar una lista de inicialización para resolverlo.
Resumen: en la mayoría de los casos, necesitamos implementar el constructor nosotros mismos. En algunos casos, es similar a MyQueue y cuando Stack tiene un constructor predeterminado, MyQueue se puede generar y usar automáticamente.
- ~Stack()
- {
- free(_a);
- _a = nullptr;
- _top = _capacity = 0;
- }
Características del destructor:
1. El nombre del destructor está precedido de caracteres ~
2. Sin parámetros ni valor de retorno (consistente con el constructor)
3. Una clase sólo puede tener un destructor.Si no se muestra la definición, el sistema generará automáticamente un destructor predeterminado.
4. Cuando finalice el ciclo de declaración de objetos, el sistema llamará automáticamente al destructor.
5. Al igual que el constructor, no escribimos el destructor generado automáticamente por el compilador y no procesamos los miembros de tipo integrados. Los miembros de tipo personalizado llamarán a otros destructores.
6. También debe tenerse en cuenta que cuando mostramos el destructor, también se llamará al destructor del miembro de tipo personalizado, lo que significa que el destructor del miembro de tipo personalizado se llamará automáticamente sin importar la situación.
- //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;
- }
El destructor en MyQueue no hace nada, pero C ++ estipula que se llamará a otros destructores para liberar la memoria.
Si no se solicitan recursos, no es necesario escribir el destructor y el destructor predeterminado generado por el compilador se puede usar directamente, como Fecha. Si se puede usar el destructor predeterminado generado, no es necesario escribir explícitamente el destructor. como MyQueue, pero hay una aplicación de recursos al destruir, asegúrese de escribir el destructor directamente, de lo contrario provocará una pérdida de recursos como 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;
- }