[Conceptos básicos de C++: 25]: [Plantilla importante] Sobrecarga del operador aritmético (asignación) de C++ y sobrecarga del operador de incremento y decremento automático [Tome la clase de fecha Fecha como ejemplo]

Descripción del artículo de la serie.

Esta serie de artículos relacionados con C ++ es solo para las notas de estudio del autor. ¡Utilizaré mi propio conocimiento para registrar el estudio! La serie de aprendizaje de C ++ se dividirá en tres etapas: conceptos básicos, STL y estructuras y algoritmos de datos avanzados . Los contenidos clave relevantes son los siguientes:

  1. Conceptos básicos : clases y objetos (que involucran las tres características principales de C++, etc.);
  2. STL : aprenda a utilizar las bibliotecas relacionadas con STL proporcionadas por C++ ;
  3. Algoritmos y estructuras de datos de alto orden : implemente manualmente su propia biblioteca STL y diseñe e implemente estructuras de datos de alto orden , como árbol B, árbol B +, árbol rojo-negro, etc.

Conjunto de estudio:



Prefacio

  • El aprendizaje básico de las clases ha llegado a una determinada etapa, por lo que el contenido que el autor compartirá contigo en los artículos recientes es: " 运算符重载小专题"! Actualmente actualizado: 关系运算符的重载(点击跳转)resolvió 输入输出运算符重载(点击跳转)el problema de comparación y entrada y salida de tipos/objetos personalizados.
  • En este artículo, el autor compartirá con usted 自定义类型 / 对象el problema de cálculo de ! Es decir: 自增自减运算符重载及算术运算符重载.

1. Sobrecarga del operador aritmético (asignación) de C++

1. Descripción

¡ Este artículo tomará +、-、+=、-=como ejemplo el diseño e implementación de la sobrecarga de operadores aritméticos (asignaciones)! [Nota: En la descripción anterior de la sobrecarga del operador, se mencionó que la sobrecarga del operador no puede cambiar su propio significado.


2. += / -= sobrecarga del operador [tome la clase de calendario Fecha como ejemplo]

符号含义:

  • +=: Operador de suma y asignación, asigna el resultado de sumar el operando derecho al operando izquierdo al operando izquierdo.
  • -=: Operador de resta Y asignación, asigna el resultado de restar el operando derecho del operando izquierdo al operando izquierdo

Para nuestra clase de fecha Fecha, las interfaces generalmente proporcionadas incluyen: Calcular el problema de fecha de sumar o restar cuántos días después de la fecha actual.
En este momento aparecerán situaciones de cálculo como: 2023-6-16 += o + 15 días! ¡Obviamente es imposible realizar cálculos utilizando los operadores originales! (Como se muestra abajo)

Insertar descripción de la imagen aquí


2.1 Ideas de diseño

Por lo tanto, ¡necesitamos sobrecargar a nuestros operadores! 由于 + 或 - 可以基于 += 或 -= 来实现¡Así que el autor da prioridad a implementarlo += / -= 的重载!


Implementar ideas de diseño:

  1. 参数问题: Obviamente, es necesario pasar varios días para la operación recursiva. No es necesario cambiar el valor, por lo que se puede modificar con const.
  2. 日期迭代计算问题: Debido al cambio de fecha involucrado, nosotros 需要考虑的每个月的天数问题! ¡Y 可能出现闰年二月的情形!

2.2 Solución: Problema del año bisiesto (Introducción a las reglas de cálculo y origen)

Acerca de: ¡problema del año bisiesto!

  • 判断闰年的方式(1582年后的计算准则):该年可以被 400 整除 或 概念可以被 4 整除但不能被 100 整除,如:1900年不是闰年!

Respecto al origen de los años bisiestos: (¡Las reglas de cálculo anteriores para los años bisiestos son las posteriores a 1582!)

  • Las reglas del salto del calendario gregoriano desde 1582:
  • Año bisiesto ordinario: si el año del calendario gregoriano es múltiplo de 4 y no múltiplo de 100, es un año bisiesto (como 2004, 2020, etc. son años bisiestos).
  • Año bisiesto del siglo: el año del calendario gregoriano es cien y debe ser un múltiplo de 400 para ser un año bisiesto (por ejemplo, 1900 no es un año bisiesto, pero 2000 sí lo es).
  • La convención antes de 1582: hay un año bisiesto cada cuatro años; si A (número positivo) en el año A AD se puede dividir por 4, entonces es un año bisiesto; si B (número positivo) en el año B BC divide 4 y el resto es 1, entonces es un año bisiesto y también es un año bisiesto.

Implementación de la función de juicio de año bisiesto (como sigue):

  • Parámetros: año
  • Valor de retorno: sí/no
/* 闰年判断 */
bool IsLeapYear(int year) {
    
    
	return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}

2.3 Edición de días del mes

Para facilitar el cálculo, el autor diseñó la adquisición del número de días del mes como una función.


Ideas de diseño:

  • Parámetros: año, mes
  • Valor de retorno: tipo int (número de días)
  • Procesamiento especial: febrero está configurado en 28 días de forma predeterminada. Si se encuentra un año bisiesto, el valor de retorno es +1;
  • 优化处理:由于获取月份天数可能使用频率较高,建议使用数组存储数据(设计如下:注意注释解释),并设定为静态数组!(避免每次调用函数新建数组的性能开销!)。

El código se implementa de la siguiente manera:

/* 获取月份天数 */
int GetMonthDay(int year, int month) {
    
    
	/* 设置为静态数组提升效率 */
	/* 数组大小设置为 13 ,即为了直接使用 days[month] 访问到数据 */
	static int days[13] = {
    
     0,31,28,31,30,31,30,31,31,30,31,30,31 };
	
	if (month == 2 && IsLeapYear(year)) {
    
    
		return days[month] + 1;
	}
	return days[month];
}

2.4 Diseño de sobrecarga e implementación del operador += o -=

设计思路(注意点):


  1. La idea básica: siempre sumar/disminuir el número de días para calcular la fecha. Durante el proceso, ¡preste atención a juzgar el cambio de mes y año!
  2. Parámetros: Extrapola el número de días transcurridos.
  3. 返回值:日期的引用!
  4. 其他细节见注释!

+= 运算符重载(实现如下)

/* += 赋值运算符重载 */
Date& Date::operator += (const int day) {
    
    
	_day += day;									/* 直接递增天数 */
	while (_day > GetMonthDay(_year, _month)) {
    
    		/* 日期“合法性”判断 */
		/* 若:天数大于本月的固定天数,则 天数 - 本月天数,并将月份 + 1 */
		_day -= GetMonthDay(_year, _month);			/* 天数更跌 */
		_month += 1;								/* 月份更迭 */
		if (_month == 13) {
    
    							/* 年份更迭 */
			_month = 1;
			_year++;
		}
	}
	return *this;
}

-= 运算符重载(实现如下)

Date& Date::operator -= (const int day) {
    
    
	_day -= day;
	while (_day < 1) {
    
    								/* 判断天数合法性 */
		if (_month == 1) {
    
    							/* 特殊点:年份更迭 */
			_month = 13;							/* 注意此处:13,为的是后续统一的月份更迭计算 */
			_year--;
		}
		_day += GetMonthDay(_year, _month - 1);
		_month--;
	}
	return *this;
}

2.5 Resultados de la leyenda de prueba

Insertar descripción de la imagen aquí


3. + o - sobrecarga del operador

Combinado con lo mencionado en el artículo anterior para mejorar la reutilización del código, puede usar directamente el += o -= existente para implementar los puntos clave del operador + o -.

3.1 Diseño, implementación y prueba de sobrecarga del operador +

+ 运算符重载(实现如下,注意注释提示)

  • 注意返回值:不是引用!
/* 
	在该函数中,不会去修改 Date 对象本身,
	而是返回一个新的对象,
	函数外部可以赋值给原对象或新对象!
*/
Date Date::operator+(const int day) const		
{
    
    
	// Date ret(*this);			/* 拷贝构造 */
	Date ret = *this;			
	ret += day;
	return ret;
}

Insertar descripción de la imagen aquí


3.2 - Diseño, implementación y prueba de sobrecarga del operador

+ 运算符重载(实现如下,注意注释提示)

  • 注意返回值:不是引用!
/* 
	在该函数中,不会去修改 Date 对象本身,
	而是返回一个新的对象,
	函数外部可以赋值给原对象或新对象!
*/
Date Date::operator-(const int day) const		
{
    
    
	// Date ret(*this);			/* 拷贝构造 */
	Date ret = *this;			
	ret -= day;
	return ret;
}

Insertar descripción de la imagen aquí


4. Acerca del diseño e implementación de sobrecarga *, /, *=, /=

  • Con respecto al diseño e implementación de la sobrecarga de *, /, *=, /=, según el contenido anterior, ¡simplemente sigue el ejemplo!

2. Sobrecarga del operador de incremento y decremento automático de C++

1.Comprensión básica

¡En C/C++, podemos usarlo ++ / --para realizar operaciones de incremento y decremento en las variables de datos que definimos! Estos dos operadores pueden describirse como una pesadilla para los recién llegados, especialmente en los exámenes finales de los estudiantes universitarios, que no tienen importancia práctica en la evaluación de la combinación de operadores de incremento y decremento. [¡El uso básico se muestra en la imagen a continuación!


En estudios anteriores, es posible que hayas escuchado más o menos: 前置自增自减 效率高于 后置自增自减. [Por supuesto, casi no debe haber diferencia con los compiladores actuales y ya ha sido optimizado]


Se sabe que 自增自减运算符分为:前置 和 后置la principal diferencia es:

  • Preposicionar significa: dar prioridad a su propia operación antes de participar en otras operaciones;
  • La posposición es: ¡primero participar en otras operaciones y luego realizar su propia operación!

Insertar descripción de la imagen aquí


2. Implementación de sobrecarga de operadores de incremento y decremento automático

Parte delantera y trasera ++ / --En el uso real, escribimos la diferencia entre la parte delantera y la trasera, pero ¿qué debemos hacer al sobrecargar?

  • 函数写法:使用函数重载!
  • 重载函数的区分方式: Utilice un parámetro para distinguir ! 方案:前置使用无参形式,后置使用含参形式[ Nota: Después de la implementación real, no necesitamos mostrar el parámetro pasado en el proceso posterior a la implementación. El compilador identificará automáticamente los parámetros distintivos de la sobrecarga del operador de incremento y decremento automático]
  • 函数返回值:对象本身(引用返回)

El código de diseño es el siguiente (tenga en cuenta la reutilización del código):

2.1 Implementación de sobrecarga de operador con prefijo ++ o –

  • 前置 ++ ,即先 +1 再返回!
  • 前置 -- ,即先 -1 再返回!
/* 前置 ++ */
Date& Date::operator++()
{
    
    
	return *(this + 1);
}

/* 前置 -- */
Date& Date::operator--()
{
    
    
	return *(this - 1);
}

2.2 Implementación de sobrecarga de operadores de Postfix ++ o –

  • 后置 ++ ,即先返回,再运算!(Con la ayuda de: objetos temporales)
  • 后置 -- ,即先返回,再运算!(Con la ayuda de: objetos temporales)
/* 后置 ++ */
Date& Date::operator++(int)
{
    
    
	Date ret(*this);
	*this += 1;
	return ret;
}

/* 后置 -- */
Date& Date::operator--(int)
{
    
    
	Date ret(*this);
	*this += 1;
	return ret;
}

2.3 Leyenda del resultado de la prueba

Insertar descripción de la imagen aquí


Artículos relacionados

1. [Capítulo básico de C++: 21]: amigo Los amigos hicieron cuatro preguntas: ¿Qué es un amigo? ¿Clase de amigos? ¿Función de amigo? ¿Cuándo usar amigos?
2. [Conceptos básicos de C++: 22]: Objetos constantes y funciones/métodos de miembros constantes de clases y problemas comunes que involucran const en clases.
3. [Conceptos básicos de C++: 23]: [Plantilla importante] Diseño e implementación de sobrecarga de operadores relacionales: [ > , < , >= , <= , != , == ] sobrecarga [tomando la clase Fecha y hora como ejemplo]


Supongo que te gusta

Origin blog.csdn.net/weixin_53202576/article/details/131215397
Recomendado
Clasificación