2010-09-29 12 views
6

Ho letto alcune dichiarazioni in avanti, incluso in questo forum. Tutti dicono che ci salva dalla incluso il file di intestazione, tuttavia il seguente codice genera un errore:la dichiarazione di inoltro genera un errore di tipo incompatibile

#ifndef CLASSA_H_ 
#define CLASSA_H_ 

class B; 

class A { 

public: 
    A(); 
    ~A(); 
    int getCount(); 
private: 
    static int _count; 
    int _num; 
    B _b1; //ERROR 

}; 

compilatore dice: A.h:23: error: field ‘_b1’ has incomplete type

Ho notato che se faccio _b1 di tipo B* il problema è risolto.

Quindi la dichiarazione è valida solo per i tipi di puntatore?
Se voglio A per contenere l'oggetto B devo #inlcude "B.h"?

grazie!

+0

Un po 'di auto-promozione: ecco una risposta che spiega [cosa puoi o non puoi fare con i tipi incompleti] (http://stackoverflow.com/questions/553682/when-to-to use-forward-declaration/553869 # 553869) (es tipi dichiarati ma non ancora definiti). –

risposta

10

Il compilatore deve conoscere la definizione esatta della classe B per determinare almeno le dimensioni da assegnare alla classe A. Se usi un puntatore, ne conosce la dimensione.

Si noti che le dipendenze circolari non sono possibili. Se si desidera

class A { B b; }; 
class B { A a; }; 

poi A e B devono avere dimensione infinita ...

+0

+1 sono stupito di non saperlo –

0

Sì, si dovrà

#include "B.h" 

se si desidera includere B nella classe A.

0

Sì, le dichiarazioni previsionali funzionano solo se si utilizza puntatori e riferimenti al tipo forward-dichiarata . Se si utilizza l'oggetto in base al valore, è necessario includere il file di intestazione completo.

+0

Bene, le dichiarazioni di inoltro funzionerebbero per utilizzarlo come un tipo nella funzione _declarations_, anche: 'B f (B); 'Tuttavia, è necessaria la definizione completa di' B' per definire _define_ questa funzione. – sbi

6

È possibile utilizzare un tipo forward-dichiarato a

  1. uso puntatori e riferimenti ad esso come dati membri
  2. usarlo come argomento (anche prendendo per copia) o restituire tipo (anche restituendo per copia) per la funzione dichiarat ioni.

Avrete bisogno una definizione completa di un tipo al fine di

  1. utilizzarlo come membro di dati di classe
  2. utilizzarlo in funzione definizioni.

Se si ricorda che un forward-dichiarazione in realtà è un misnomed dichiarazione (there is no other way of declaring a class type, così ogni dichiarazione di un tipo di classe è una dichiarazione in avanti), e che, ogni volta che si sta aprendo le parentesi dopo class/struct/union più identificativo, sei definire una classe, tutto quello che dovete ricordare è che si:

  • bisogno di una definizione completa per utilizzare il tipo stesso di definizioni
  • cavarsela con solo una dichiarazione di utilizzare il tipo stesso nelle dichiarazioni
  • scappare solo con una dichiarazione quando si utilizza solo i puntatori e riferimenti e non si tenta per accedere ai membri o tipi nidificati (qualsiasi cosa con ., ->, e :: nella parte anteriore)
Problemi correlati