2012-04-23 15 views
10

por lo general utiliza el avance declaración predominantemente, si tengo una clase que no necesita definición completa en el archivo .hppDeclaración de variables Forward/clases de espacio de nombres std

Ex)

//B.hpp 

namespace A_file { 
    class A; 
} 

namespace B_file { 

    class B { 
    public: 
     B(); 
    private: 
     A *ptr_to_A; 
    } 
} 

//B.cpp 

#include "A.hpp" 
using namespace A_file; 

namespace B_file { 

    B(int value_) { 
     *ptr_to_A = new A(value_); 
    } 

    int some_func() { 
     ptr_to_A->some_func_in_A(); 
    } 
} 

escribo esto tipo de código Creo que lo salvará, incluyendo todo el hpp nuevamente. (Siéntase libre de comentar, si lo cree, esto no es saludable)

¿Hay alguna forma de que yo pueda hacer lo mismo con los objetos/clases en el espacio de nombres estándar? Si hay alguna manera, ¿está bien o tiene efectos secundarios?

Respuesta

20

Puede reenviar declarar sus propias clases en archivos de encabezado para ahorrar tiempo de compilación. Pero no se puede para las clases en namespace std. De acuerdo con el estándar de C++ 11, 17.6.4.2.1:

El comportamiento de un programa en C++ no está definido si se agrega declaraciones o las definiciones de espacio de nombres std o para un espacio de nombres dentro del espacio de nombres std menos que se especifique lo contrario .

Tenga en cuenta que algunas de estas clases son typedefs de clases con plantillas, por lo que una simple declaración directa no funcionará. Se puede utilizar en lugar de #include<iosfwd>#include<iostream> por ejemplo, pero no hay cabeceras similares con declaraciones justo adelante para string, vector, etc.

Ver GotW #34, Forward Declarations para más información.

+2

+1. De manera predecible, el precedente establecido por '' también es la mejor práctica: prefiere tener un encabezado de declaración adicional, incluido por el encabezado "normal" para obtener verificaciones en tiempo de compilación para la validez continua, y por clientes que solo necesitan las declaraciones directas . Debería "vivir" y mantenerse con la biblioteca cuyo código es "forward" declara, ¡no el código del cliente! La razón exacta dada en el método anterior de GotW dirige esto: las estructuras pueden convertirse en tipos de plantillas, las plantillas pueden agregar argumentos, etc. –

Cuestiones relacionadas