2012-04-23 14 views
10

Io di solito uso in avanti dichiarazione prevalentemente, se ho una classe che non ha bisogno di completa definizione nel file di .hppdichiarazione anticipata di variabili/classi di namespace 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(); 
    } 
} 

scrivo questo tipo di codice. Penso che salverà includendo di nuovo l'intero hpp. (Sentitevi liberi di commentare, se la vostra cosa, questo non è salutare)

C'è un modo che io possa fare lo stesso per gli oggetti/le classi nello spazio dei nomi std? Se c'è un modo, va bene o ha effetti collaterali?

risposta

20

È possibile inoltrare le proprie classi nei file di intestazione per salvare i tempi di compilazione. Ma non puoi per le classi nello spazio dei nomi std. Secondo il C++ 11 di serie, 17.6.4.2.1:

Il comportamento di un programma C++ è indefinito se si aggiunge dichiarazioni o definizioni di namespace std o per uno spazio dei nomi all'interno di namespace std se non diversamente specificato .

Si noti che alcune di queste classi sono typedef di classi basate su modelli, pertanto una semplice dichiarazione di inoltro non funzionerà. È possibile utilizzare #include<iosfwd> invece di #include<iostream> per esempio, ma non ci sono intestazioni simili con le dichiarazioni appena avanti per string, vector, ecc

Vedi GotW #34, Forward Declarations per ulteriori informazioni.

+2

+1. È abbastanza prevedibile anche il precedente impostato da "": preferire un'intestazione di dichiarazione in avanti, inclusa dall'intestazione "normale" per ottenere i controlli in fase di compilazione per la validità in corso e dai client che hanno solo bisogno delle dichiarazioni di inoltro . Dovrebbe "vivere" ed essere mantenuto con la libreria il cui codice è in avanti dichiara, non il codice cliente! Il motivo esatto fornito in GotW sopra lo guida: le strutture possono diventare typedef di template, i template possono aggiungere argomenti ecc .. –

Problemi correlati