[C++]——Una breve introducción a las nuevas características de C++11

Prefacio:

  • A partir de este número, lo llevaré a aprender nuevos conocimientos relevantes sobre C ++ 11. Sin más preámbulos, comencemos directamente el estudio de hoy.

Tabla de contenido

(1) Introducción a C ++ 11

(2) Inicialización de lista unificada

1. {} inicialización

2、std::initializer_list

(3) Declaración

1 、 automático

2、tipo de declive

3、nuloptr

(4) Rango para bucle

(5) Algunos cambios en STL

Resumir


(1) Introducción a C ++ 11

En 2003, el Comité de Estándares de C++ presentó una corrección técnica (TC1 para abreviar), de modo que el nombre C++03 reemplazó el nombre del último estándar de C++ antes de que C++98 se llamara C++11. Sin embargo, dado que C++03 (TC1) soluciona principalmente las lagunas del estándar C++98 y la parte central del lenguaje no ha cambiado, la gente habitualmente combina los dos estándares y lo llama C++98/03. estándar. . Desde C ++ 0x hasta C ++ 11, el estándar C ++ ha estado funcionando durante 10 años y el segundo estándar verdadero llegó tarde. En comparación con C++ 98/03, C++ 11 ha traído una cantidad considerable de cambios, incluidas alrededor de 140 características nuevas y correcciones de alrededor de 600 defectos en el estándar C++ 03, lo que hace que C ++ 11 se parezca más a un Nuevo lenguaje nacido de C++98/03. En comparación, C++ 11 se puede utilizar mejor para el desarrollo de sistemas y bibliotecas, la sintaxis es más general y simplificada, más estable y segura, no solo la función es más poderosa, sino que también puede mejorar la eficiencia del desarrollo de los programadores. El actual de la empresa también se utiliza con frecuencia en el desarrollo de proyectos, por lo que debemos estudiarlo como foco. Las características gramaticales agregadas por C ++ 11 son muy extensas y no podemos explicarlas una por una aquí, por lo que este curso explica principalmente la gramática más práctica en la práctica.

[ Expansión del conocimiento ]
1998 fue el primer año en que se estableció el Comité de Estándares C++. Originalmente se planeó actualizar el estándar cada cinco años según las necesidades reales. Cuando el Comité de Estándares Internacionales de C++ estaba estudiando la próxima versión de C++03, El plan inicial fue lanzado en 2007, por lo que el estándar se llamó inicialmente C++07. Pero en 2006, los funcionarios sintieron que C++ 07 definitivamente no se completaría en 2007, y los funcionarios sintieron que tal vez no se completaría en 2008. Al final, se llamó simplemente C++ 0x. x significa que no sé si estará terminado en 2007, 2008 o 2009. Como resultado, no se completó en 2010 y el estándar C++ finalmente se completó en 2011. Así que finalmente se llamó C++11.


(2) Inicialización de lista unificada

A continuación, comenzaremos oficialmente a aprender la primera característica nueva de C ++ 11: ¡conocimiento sobre la inicialización de listas unificadas!

1. {} inicialización

La inicialización mediante llaves {} proporciona un comportamiento coherente en diferentes situaciones y tiene algunas reglas y semánticas de inicialización especiales.

Aquí hay algunos ejemplos de inicialización usando llaves en C++11:

  • Inicialización directa:
int main()
{
	int x{ 42 }; // 使用大括号直接初始化 x 为 42
	string str{ "Hello" }; // 使用大括号直接初始化字符串对象

	cout << x << endl;
	cout << str << endl;
	return 0;
}

Pantalla de salida:

 

  • Inicialización predeterminada:
int main()
{
	int x{}; // 使用大括号进行默认初始化,x 的值为 0
	string str{}; // 使用大括号进行默认初始化,str 为空字符串

	cout << x << endl;
	cout << str << endl;
	return 0;
}

Pantalla de salida:

  •  Inicialización de matriz o estructura

En C++98, el estándar permite el uso de llaves {} para la inicialización uniforme de la lista de elementos de matriz o estructura. Por ejemplo:
 

struct Point
{
    int _x;
    int _y;
};
int main()
{
    int array1[] = { 1, 2, 3, 4, 5 };
    int array2[5] = { 0 };
    Point p = { 1, 2 };
    return 0;
}

En C++ 11, el alcance de uso de las listas encerradas entre llaves (listas de inicialización) se ha ampliado para que puedan usarse para todos los tipos integrados y tipos definidos por el usuario. Al usar listas de inicialización, puede agregar una signo igual (= ), o no agregado .

Visualización de código:

int main()
{
	int x1 = 1;
	int x2{ 2 };

	cout << x1 << endl;
	cout << x2 << endl;
	return 0;
}

Pantalla de salida:

 Por lo tanto, las operaciones de inicialización de las estructuras y matrices anteriores se pueden transformar en lo siguiente en C++11:

struct Point
{
	int _x;
	int _y;
};
int main()
{
	//c++98
	/*int array1[] = { 1, 2, 3, 4, 5 };
	int array2[5] = { 0 };
	Point p = { 1, 2 };*/

	//c++11
	int array1[]{ 1, 2, 3, 4, 5 };
	int array2[5]{ 0 };
	Point p{ 1, 2 };

	return 0;
}

Pantalla de salida: 

 

  •  Al crear un objeto, también puede utilizar la inicialización de lista para llamar a la inicialización del constructor.
class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	// old style
	Date d1(2022, 1, 1); 
	
	// C++11支持的列表初始化,这里会调用构造函数初始化
	Date d2{ 2022, 1, 2 };
	Date d3 = { 2022, 1, 3 };
	
	return 0;
}

Pantalla de salida:

 【explicar】

  • La esencia aquí es construcción + copia de construcción, después de la optimización. Si no desea que el compilador realice configuraciones de optimización, puede agregar archivos explícitos.

 【resumen】

  1. El uso de la inicialización de llaves es más seguro y flexible que la asignación tradicional o la inicialización de llaves en muchas situaciones;
  2. Se puede utilizar para resolver problemas de conversión restringidos , proporcionar una sintaxis de inicialización unificada y puede realizar una verificación de tipos más estricta.

2、std::initializer_list

std::initializer_list es un tipo de biblioteca estándar introducido en C++ 11 para representar convenientemente una lista de inicialización. Es una clase contenedora liviana que se utiliza para almacenar un conjunto de valores del mismo tipo.

Utilice std::initializer_list para pasar un conjunto de valores como argumentos a una función o constructor, o para la inicialización de un objeto. Su sintaxis es similar a  la inicialización de llaves, pero proporciona una forma más flexible de pasarla y usarla. {}

A continuación se muestran algunos  usos comunes de std::initializer_list :

  • pasado como parámetro para funcionar
void Point(initializer_list<int> values) {
    for (const auto& value : values) {
        cout << value << " ";
    }
    cout << endl;
}

int main() {
    Point({ 1, 2, 3, 4 }); // 使用初始化列表作为参数
    return 0;
}

Pantalla de salida:

 


  • Como parámetro constructor de un objeto.
class MyClass {
public:
    MyClass(initializer_list<int> values) {
        // 在构造函数中使用初始化列表
        for (const auto& value : values) {
            // 处理每个值
            cout << value << " ";
        }
    }
};

int main() 
{
    MyClass obj({ 1, 2, 3, 4 }); // 使用初始化列表作为构造函数参数
    return 0;
}

Pantalla de salida:

 


  • Utilizado en bucles basados ​​en rango
int main()
{
	initializer_list<int> values = { 1, 2, 3, 4 };
	for (const auto& value : values) {
		// 处理每个值
		cout << value << " ";
	}
	return 0;
}

Pantalla de salida:

 


La principal ventaja de std::initializer_list es que proporciona una forma concisa e intuitiva de pasar una lista de inicialización, especialmente adecuada para funciones o constructores con un número indeterminado de parámetros. Permite recorrer y acceder a valores dentro del mismo de forma similar a los contenedores estándar .

 Esto se debe a que en C++11, vector proporciona el siguiente constructor:

 


Nota : std::initializer_list  es un contenedor de solo lectura y no puede insertar, eliminar ni modificar elementos . Su tipo de elemento es constante, por lo que generalmente se usa const auto& para iterar sobre elementos.

1. Insertar informe de errores

 

2. Eliminar informe de errores

 

3. Modificar el informe de errores

 

【resumen】

  • En resumen, std::initializer_list proporciona una forma concisa y conveniente de manejar listas de inicialización, y se usa ampliamente en C++ 11 y versiones posteriores;
  • Nos permite manejar listas de inicialización de una manera más intuitiva y segura y simplifica el paso de parámetros a funciones y constructores.

(3) Declaración

C++ 11 proporciona varias formas de simplificar las declaraciones, especialmente cuando se utilizan plantillas.
 

1 、 automático

En C++98, auto es un especificador de tipo de almacenamiento, lo que indica que la variable es un tipo de almacenamiento automático local. Sin embargo, las variables locales definidas en un dominio local tienen por defecto un tipo de almacenamiento automático, por lo que auto no tiene valor. El uso original de auto se abandona en C++ 11 y se usa para implementar la inferencia automática de tipos. Esto requiere una inicialización explícita, lo que permite al compilador establecer el tipo del objeto definido en el tipo del valor inicializado .

A continuación se muestran algunos  auto ejemplos de uso de:

  • inferencia automática de tipos
int main()
{
	auto num = 42; // 推断 num 的类型为 int

	auto str = "Hello"; // 推断 str 的类型为 const char*

	auto arr = std::vector<int>(); // 推断 vec 的类型为 std::vector<int>

	return 0;
}

Pantalla de salida:

 En estos ejemplos, auto la palabra clave infiere el tipo de variable en función de su expresión de inicialización y declara la variable en consecuencia.


  • Usado en combinación con bucles basados ​​en rango (hemos estado usando esto, así que no entraremos en detalles)

 

  • Inferencia del tipo de retorno de función
auto add(int a, int b) {
    return a + b;
}

En este ejemplo, auto se utiliza para inferir el tipo de retorno de la función. El compilador infiere automáticamente el tipo de retorno de la función según el tipo de expresión de retorno.


【resumen】

  1. auto Los tipos inferidos se determinan en tiempo de compilación, no en tiempo de ejecución. Esto significa que las variables declaradas utilizando  auto una variable se infieren en el tipo en tiempo de compilación según el tipo de expresión inicializadora y luego se tratan como si tuvieran un tipo determinado en el código posterior.
  2. Además, debido a que  auto el tipo se infiere en función de la expresión de inicialización, en algunos casos puede generar resultados de inferencia de tipos inesperados o tipos ambiguos. En estos casos, se pueden utilizar declaraciones de tipos explícitas u otras herramientas de inferencia de tipos más específicas (como operadores de conversión de tipos) para eliminar la ambigüedad.

2、tipo de declive

La palabra clave decltype declara que el tipo de una variable es el tipo especificado por la expresión.

Ejemplo de código:

int main()
{
	const int x = 1;
	double y = 2.2;

	decltype(x * y) ret; // ret的类型是double
	decltype(&x) p; // p的类型是 const int*

	cout << typeid(ret).name() << endl;
	cout << typeid(p).name() << endl;


	return 0;
}

Pantalla de salida:

 


3、nuloptr

Dado que NULL en C++ se define como literal 0, esto puede causar algunos problemas, porque 0 puede representar tanto una constante de puntero como una
constante entera. Por lo tanto, en aras de la claridad y la seguridad, se agrega nullptr en C++ 11 para representar un puntero nulo.
 

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

(4) Rango para bucle

Esto ya lo hemos explicado con gran detalle en cursos anteriores, por lo que no lo explicaremos aquí.


(5) Algunos cambios en STL

Contenedores nuevos
En un círculo naranja se encuentran algunos de los contenedores nuevos en C++ 11, pero los más útiles son unordered_map y
unordered_set. Ya hemos explicado estos dos con gran detalle antes, puedes conocer los demás.
 

 


Resumir

Lo anterior es la introducción a las nuevas características de C++11 en este número. El contenido anterior es un contenido familiar en el reclutamiento escolar, ¡solo conócelo y úsalo!

 

Supongo que te gusta

Origin blog.csdn.net/m0_56069910/article/details/132460924
Recomendado
Clasificación