Clases y objetos C ++ (activado): los conceptos básicos de clases, calificadores de clase y encapsulación y este puntero de funciones miembro de clase

Uno, el concepto básico de clase.

1.1 Definición de clase

class className
{
    
    
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
  • Class es la palabra clave para definir la clase , ClassName es el nombre de la clase , {} es el cuerpo principal de la clase , preste atención al punto y coma después del final de la definición de la clase .
  • Los elementos de la clase se denominan miembros de la clase; los datos de la clase se denominan atributos o variables miembro de la clase; las funciones de la clase se denominan métodos o funciones miembro de la clase .

1.2 Dos formas de definir una clase

  1. Las declaraciones y definiciones se colocan en el cuerpo de la clase Nota: Si se define una función miembro en la clase , el compilador puede tratarla como una función en línea .
    Inserte la descripción de la imagen aquí
  2. La declaración se coloca en el archivo .h, y la definición de clase se coloca en el archivo .cpp (generalmente de esta manera)
    Inserte la descripción de la imagen aquí

En segundo lugar, el calificador de acceso y el empaquetado de la clase.

2.1 Calificador de acceso

C ++ se da cuenta de la forma de encapsulación: use clases para combinar las propiedades y métodos del objeto para hacer que el objeto sea más completo y proporcionar selectivamente su interfaz a usuarios externos a través de permisos de acceso .

Inserte la descripción de la imagen aquí
Descripción del calificador de acceso :

  1. Se puede acceder directamente a los miembros públicos modificados fuera de la clase
  2. No se puede acceder directamente a los miembros protegidos y privados modificados fuera de la clase
  3. El alcance de los derechos de acceso comienza desde donde aparece el calificador de acceso hasta que aparece el siguiente calificador de acceso
  4. El permiso de acceso predeterminado de la clase es privado y la estructura es pública (porque la estructura es compatible con C)

Nota: El calificador de acceso solo es útil en tiempo de compilación. Después de que los datos se mapean en la memoria, no hay diferencia en el calificador de acceso

P1: ¿Cuál es la diferencia entre estructura y clase en C ++?

C ++ debe ser compatible con el lenguaje C, por lo que la estructura en C ++ se puede utilizar como estructura. Además, la estructura en C ++ también se puede utilizar para definir clases. Es lo mismo que la clase que define la clase, la diferencia es que el método de acceso predeterminado de los miembros de la estructura es público y el método de acceso predeterminado de los miembros de la clase es privado.

2.2 Embalaje

P1: Tres características de la orientación a objetos

Encapsulación, herencia, polimorfismo.

P2: En la etapa de clase y objeto, solo estudiamos las características de encapsulación. ¿Qué es la encapsulación?

Encapsulación: combine datos y métodos de manipulación de datos orgánicamente, oculte las propiedades y los detalles de implementación del objeto y solo exponga la interfaz al exterior para interactuar con el objeto.
La encapsulación es esencialmente un tipo de gestión: ¿cómo gestionamos a los guerreros de terracota? Por ejemplo, si no queda nada, los guerreros de terracota serán destruidos a voluntad. Luego, primero construimos una casa para encapsular a los guerreros de terracota. Pero nuestro propósito está todo encapsulado y no dejar que otros lo vean. Por lo tanto, hemos abierto el canal de venta de boletos y podemos comprar boletos para romper el paquete e ingresar bajo un mecanismo de supervisión razonable. Lo mismo ocurre con las clases. Usamos datos de clase y métodos para encapsularlos juntos. No queremos que otros vean, usamos protected / private para encapsular a los miembros . Abra algunas funciones de miembros comunes para un acceso razonable a los miembros. Por tanto, la encapsulación es esencialmente una forma de gestión.

Tres, el alcance y la instanciación de la clase.

3.1 Alcance de la clase

La clase define un nuevo ámbito y todos los miembros de la clase están en el ámbito de la clase. Para definir miembros fuera de la clase, necesitaUse :: resolver de alcance para especificar a qué dominio de clase pertenece un miembro

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 Instanciación de la clase

El proceso de creación de objetos con tipos de clases se denomina instanciación de clases.

  1. Una clase es solo una cosa similar a un modelo, que limita los miembros de la clase, define una clase y no asigna espacio de memoria real para almacenarla.
  2. Una clase puede crear instancias de múltiples objetos, los objetos instanciados ocupan espacio físico real y almacenar variables de miembros de clase
  3. Haz una analogía. Crear instancias de objetos de clase es como construir una casa utilizando dibujos de diseño arquitectónico en la realidad. Las clases son como dibujos de diseño , solo diseñan lo que se necesita, pero no hay un edificio físico. La misma clase es solo un diseño, los objetos instanciados pueden almacenar datos y ocupar espacio fisico
    Inserte la descripción de la imagen aquí

Cuarto, el modelo de objetos de clase

4.1 ¿Cómo calcular el tamaño de un objeto de clase?

Puede haber tanto variables miembro como funciones miembro en una clase, entonces, ¿qué está contenido en un objeto de una clase? ¿Cómo calcular el tamaño de una clase?

4.2 Adivinar el método de almacenamiento de objetos de clase

  • El objeto contiene a cada miembro de la clase.
    Inserte la descripción de la imagen aquí
    Desventaja: Las variables miembro en cada objeto son diferentes, pero se llama a la misma función. Si se almacena de esta manera, cuando una clase crea varios objetos, cada objeto guardará un código, Guardar el mismo codifique varias veces, desperdiciando espacio. Entonces, ¿cómo solucionarlo?

  • Sólo se almacenan las variables miembro y las funciones miembro se almacenan en el segmento de código común
    Inserte la descripción de la imagen aquí
    Inserte la descripción de la imagen aquí
    Pregunta: Para los dos métodos de almacenamiento anteriores, ¿en qué tipo de método almacena la computadora?
    Analicemos y veamos obteniendo los tamaños de los diferentes objetos a continuación.

#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;
}

resultado
Inserte la descripción de la imagen aquí

4.3 La conclusión del cálculo del tamaño de la clase.

Conclusión:
el tamaño de una clase es en realidad la suma de las "variables miembro" de la clase. Por supuesto, se debe realizar la alineación de la memoria. Preste atención al tamaño de la clase vacía. La clase vacía es especial. El compilador da el clase vacía un byte para identificar de forma exclusiva esta clase.

Cinco, este puntero

5.1 Saliendo de este puntero

Primero definimos una clase de fecha

#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;
}

Como resultado
Inserte la descripción de la imagen aquí
, hay dos funciones miembro Init e Print en la clase Date. No hay distinción entre diferentes objetos en el cuerpo de la función. Cuando d1 llama a la función Init, ¿cómo sabe la función que debe establecer el objeto d1 en lugar de el objeto d2?

C ++ resuelve este problema introduciendo el puntero this, es decir: El compilador de C ++ agrega un parámetro de puntero oculto a cada "función miembro no estática", de modo que el puntero apunta al objeto actual (el objeto que llama a la función cuando la función se está ejecutando), se accede a todas las operaciones de variables miembro en el cuerpo de la función a través de este puntero. Es solo que todas las operaciones son transparentes para el usuario, es decir, el usuario no necesita pasarlo y el compilador lo completa automáticamente.
Inserte la descripción de la imagen aquí

5.2 Características de este puntero

  1. El tipo de este puntero: tipo de clase * const, la
    siguiente forma es incorrecta
  void Init(Date* this, int year, int month, int day)
  {
    
    
  	//this是隐含的,实参和形参的位置我们不能手动添加会报错
    _year = year;
    _month = month;
    _day = day;
  }

  1. Este puntero solo se puede usar dentro de "funciones miembro"
  void Init(int year, int month, int day)
  {
    
    
    cout<<"this:"<<this<<endl;
    this->_year = year;
    this-> _month = month;
    this-> _day = day;
  }

Inserte la descripción de la imagen aquí

  1. El puntero this es en realidad un parámetro formal de una función miembro.Cuando un objeto llama a una función miembro, la dirección del objeto se pasa al parámetro this como un parámetro real. Entonces, este puntero no se almacena en el objeto.
  2. Este puntero es el primer parámetro de puntero implícito de la función miembro. Generalmente, el compilador lo pasa automáticamente a través del registro ecx y no es necesario que el usuario lo pase.

P1: ¿Dónde existe este puntero?

El puntero this es en realidad un parámetro formal de una función miembro.Cuando un objeto llama a una función miembro, la dirección del objeto se pasa al parámetro this como un parámetro real. Entonces, este puntero no se almacena en el objeto. En otras palabras, este puntero existe en la pila, pero para mejorar la eficiencia en vs, este puntero existe en el registro ecx.
Inserte la descripción de la imagen aquí

P2: ¿Puede este puntero ser nulo?

Usamos el siguiente programa para analizar

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;
}

El código anterior se puede compilar y pasar, pero p-> PrintA () se bloqueará cuando se ejecute por separado, pero p-> Show () se puede ejecutar.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Razón:
Inserte la descripción de la imagen aquí
aunque p es un puntero nulo, las funciones miembro de la clase se almacenan en el segmento de código público, no en el objeto, y p no se desreferencia cuando se llama, por lo que Print no se bloqueará.

Supongo que te gusta

Origin blog.csdn.net/qq_40076022/article/details/113999669
Recomendado
Clasificación