[C ++ clases y objetos]: la relación entre este puntero y los métodos de miembros, punteros a los miembros de la clase

Primero, la relación entre este puntero y los métodos de miembro

Tomemos la clase de productos básicos que escribimos en el artículo anterior, todos sabemos que todos los métodos miembros son métodos ordinarios.
El código del producto se implementa de la siguiente manera:

class CDate
{
public:
	CDate(int y, int m, int d)
	{
		_year = y;
		_month = m;
		_day = d;
	}
	void show()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
class CGoods
{
public:
	CGoods(const char* n, int a, double p,int y,int m,int d):_data(y,m,d)
	{
		strcpy(_name, n);
		_amount = a;
		_price = p;
	}
	void show()
	{
		cout << "name: " << _name << endl;
		cout << "amount:" << _amount << endl;
		cout << "price:" << _price << endl;
		_data.show();
	}
private:
	char _name[20];
	int _amount;
	double _price;
	CDate _data;
};

1. Métodos de miembros ordinarios

El objeto debe llamar a los métodos miembros ordinarios, porque después de la compilación, la dirección del objeto se pasará a la función como un parámetro real.Durante el proceso de compilación, estos métodos miembros agregarán una variable adicional de este parámetro para recibir su objeto invocador.
Tiene las siguientes características:

  • Alcance perteneciente a clase
  • Debe confiar en un objeto al llamar a este método (a menudo no se pueden llamar los objetos)
  • Las variables miembro privadas que pueden acceder al objeto arbitrariamente no se consideran protegidas, solo se consideran públicas y privadas.

2. Métodos de miembros estáticos

Si queremos agregar un requisito a la categoría de productos mencionados anteriormente, cuente el número total de todos los productos

Mejora uno: agregue un _count ++ en el constructor; registre el número de todos los objetos nuevos generados

CGoods(const char* n, int a, double p, int y, int m, int d)
		:_data(y, m, d)
		{
			strcpy(_name, n);
			_amount = a;
			_price = p;
			_count++;
		}

Mejora 2: agregue un método de miembro estático para imprimir la información compartida por todos los productos

static void showCGoodsCount()
	{
		cout << "所有商品的种类数量是: " << _count << endl;
	}

Mejora tres: defina una variable miembro estática en privado.

private:
	char _name[20];
	int _amount;
	double _price;
	CDate _data;
	static int _count;

Esto es solo una declaración, que se definirá e inicializará fuera de la clase. No pertenece al objeto, sino que pertenece al nivel de la clase. No ocupa memoria de objeto, en la sección .data

Mejora 3: Inicializar fuera de la clase

int CGoods::_count = 0;

Características del método del miembro estático: este parámetro no se generará

  • Alcance perteneciente a clase

  • Método de llamada con alcance de nombre de clase

  • Puede acceder a los miembros privados del objeto de forma arbitraria, limitado a los miembros que no dependen del objeto (solo se puede llamar a otros miembros estáticos)

    La diferencia entre los métodos de miembro ordinario y los métodos de miembro estático: el
    primero tiene un CGoods * esto, el último no necesita este puntero, no necesita recibir la dirección de una llamada a un objeto

3. Métodos regulares para miembros

Agregue un requisito sobre la base de la clase de mercancía anterior. Para declarar un objeto de mercancía en la función principal, la mercancía solo se puede ver

int main()
{
const CGoods good5("非卖品商品5",100, 35.0, 2019, 5, 12);
	good5.show();
	return 0;
}

Tenga en cuenta que el método común show () llamado aquí será incorrecto, porque el objeto común llama al método común CGoods :: show (& good5) const CGoods * -> CGoods * este error, el método llamado por el objeto común debe ser el método habitual

Mejora uno: define un método común de un espectáculo

void show() const//const CGoods *this
	{
		cout << "name: " << _name << endl;
		cout << "amount:" << _amount << endl;
		cout << "price:" << _price << endl;
		_data.show();
	}

El programa llamado por tiempo también debería ser el método habitual

void show() const
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}

Los métodos de miembros constantes y los métodos de miembros ordinarios sobrecargan los objetos ordinarios y se pueden invocar objetos constantes. Siempre que los métodos de miembros de la operación de solo lectura, todos los métodos de miembros constantes se implementen

Características del método de miembro constante: generar const CGoods * this

  • Alcance perteneciente a clase
  • La llamada depende de un objeto, ya sea objetos ordinarios u objetos regulares
  • Puede acceder a los miembros privados del objeto de forma arbitraria, pero solo puede leer, no escribir

Dos, consejos para los miembros de la clase.

Tenemos tal clase:

class Test
{
public:
	void func() { cout << "call Test :: func" << endl; }
	static void static_func() { cout << "Test::static_func" << endl; }
	int ma;
	static int mb;
};
int Test::mb;

¿Cómo deberíamos implementarlo cuando queremos definir un puntero a una variable o método miembro?
Atencion El puntero debe estar precedido por un puntero de alcance de clase
(1) a las variables miembro ordinarias

Test t1;
	Test* t2 = new Test();
int Test::* p = &Test::ma;
	t1.*p = 20;
	cout << t1.*p << endl;

	t2->*p = 30;
	cout << t2->*p << endl;
	delete t2;

(2) Puntero a la variable miembro estática, no depende del objeto

int* p1 = &Test::mb;
	*p1 = 40;
	cout << *p1 << endl;
	

(3) Método de puntero al miembro (el método del miembro ordinario debe depender del objeto)

void (Test :: * pfunc)() = &Test::func;
	(t1.*pfunc)();
	(t2->*pfunc)();
Publicado 98 artículos originales · ganado elogios 9 · vistas 3672

Supongo que te gusta

Origin blog.csdn.net/qq_43412060/article/details/105098230
Recomendado
Clasificación