Declaración de reenvío de estándares de codificación c ++

La razón para discutir este problema es que al usar el espacio de nombres en línea, encontré el uso de una declaración de reenvío en el archivo de encabezado del código del módulo, lo que causó la modificación del código. Al modificar un módulo, el código de otros módulos debe modificarse en Al mismo tiempo. Tampoco puede ser procesado por el espacio de nombres aliase, que cumple con la descripción en la sección siguiente para determinar la desventaja 2.
Hay muchos artículos que abogan por el uso de declaraciones forward. Vamos a juzgar que cada uno tiene méritos y deméritos. Libc ++ todavía tiene mucho uso de declaraciones forward. Por ejemplo, el archivo de encabezado iosfwd es una buena explicación.

La fuente de las siguientes reglas:
https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/magic/

Declaración de reenvío

Evite el uso de declaraciones de reenvío tanto como sea posible. Utilice #include para incluir los archivos de encabezado necesarios.

definición:

La llamada "declaración hacia adelante" es una declaración pura de clases, funciones y plantillas sin acompañar sus definiciones.

ventaja:

  1. Las declaraciones hacia adelante pueden ahorrar tiempo de compilación, y el #include adicional obligará al compilador a expandir más archivos y procesar más entradas.
  2. La declaración hacia adelante puede ahorrar tiempo de recompilación innecesario. #include hace que el código se vuelva a compilar varias veces debido a cambios irrelevantes en el archivo de encabezado.

Desventajas:

  1. La declaración de reenvío oculta las dependencias.Cuando se cambia el archivo de encabezado, el código del usuario omitirá el proceso de recompilación necesario.

  2. Las declaraciones futuras pueden romperse por cambios posteriores en la biblioteca. La declaración previa de funciones o plantillas a veces evita que los desarrolladores de encabezados cambien sus API. Por ejemplo, expandir los tipos de parámetros, agregar un parámetro de plantilla con parámetros predeterminados, etc.

  3. Cuando la declaración directa proviene del símbolo del espacio de nombres std ::, su comportamiento es indefinido.

  4. Es difícil determinar cuándo usar declaraciones de reenvío y cuándo usar #include. En casos extremos, reemplazar las inclusiones con declaraciones hacia adelante incluso cambiará secretamente el significado del código:

// b.h:
struct B {
    
    };
struct D : B {
    
    };

// good_user.cc:
#include "b.h"
void f(B*);
void f(void*);
void test(D* x) {
    
     f(x); }  // calls f(B*)

Si #include es reemplazado por la declaración de avance de B y D, test () llamará f (void *)
5. La declaración de avance de símbolos del archivo de encabezado será más detallada que la inclusión de una sola línea.
6. Refactorizar el código solo para poder reenviar declaraciones (como reemplazar miembros de objeto con miembros de puntero) hará que el código sea más lento y complicado.

En conclusión:

  • Trate de evitar declarar entidades que están definidas en otros proyectos.
  • Función: siempre utilizado #include.
  • Plantilla de clase: usar primero #include.

Supongo que te gusta

Origin blog.csdn.net/yao_zhuang/article/details/113575686
Recomendado
Clasificación