2010-09-29 12 views
6

Czytałem niektóre z deklaracji dotyczących przyszłości, w tym na tym forum. Wszyscy mówią, że ratuje nas przed tym pliku nagłówkowego, jednak poniższy kod generuje błąd:Zgłoszenie do przodu generuje niezgodny błąd typu

#ifndef CLASSA_H_ 
#define CLASSA_H_ 

class B; 

class A { 

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

}; 

kompilator mówi: A.h:23: error: field ‘_b1’ has incomplete type

Zauważyłem, że jeśli zrobię _b1 typu B* problem jest rozwiązany.

Czy zatem zgłoszenie do przodu jest dobre tylko dla typów wskaźników?
Jeśli chcę, aby A posiadał obiekt B, muszę mieć #inlcude "B.h"?

dziękuję!

+0

Trochę autopromocji: oto odpowiedź wyjaśniająca [co można i czego nie można zrobić z niekompletnymi typami] (http://stackoverflow.com/questions/553682/when-to- use-forward-declaration/553869 # 553869) (tj typy zadeklarowane, ale jeszcze nie zdefiniowane). –

Odpowiedz

10

Kompilator musi znać dokładną definicję klasy B, aby określić co najmniej rozmiar, jaki należy nadać klasie A. Jeśli używasz wskaźnika, zna on jego rozmiar.

Należy pamiętać, że zależności kołowe nie są możliwe. Jeśli chcesz

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

następnie A i B muszą mieć nieskończoną wielkość ...

+0

+1 Jestem zaskoczony, że tego nie wiedziałem –

0

Tak, trzeba by

#include "B.h" 

jeśli chcesz dołączyć B w klasie A.

0

Tak, terminowe deklaracje działa tylko jeśli używasz wskaźniki i referencje do typu forward-zadeklarowana . Jeśli używasz obiektu według wartości, musisz dołączyć kompletny plik nagłówkowy.

+0

Cóż, deklaracje forward działałyby dla użycia go jako typu w funkcji _declarations_, too: 'B f (B);' Potrzebujesz pełnej definicji 'B' do faktycznie _define_ tej funkcji. – sbi

6

Można użyć rodzajem wybiegające oświadczył do

  1. użyć wskaźników i odniesień do niej jako elementy danych
  2. używają go jako argumentu (nawet biorąc na kopię) lub zwracają typ (nawet zwracając na kopię) dla funkcji jony.

Musisz pełną definicję typu w celu

  1. używać go jako członka danych klasa
  2. używać go w funkcji definicje.

Jeśli pamiętać, że do przodu deklaracja faktycznie jest misnomed deklaracja (there is no other way of declaring a class type, więc Każda deklaracja typu klasy jest naprzód deklaracja), i że przy każdorazowym otwarciu nawiasów po class/struct/union oraz identyfikator, jesteś definiowania klasę, wszystko trzeba pamiętać, jest to, że:

  • potrzebują pełnej definicji użyć samego typu w definicji
  • uciec tylko z deklaracji korzystania z samego typu w deklaracji
  • uciec tylko z deklaracji w przypadku korzystania jedynie wskaźniki i referencje, a nie próbować członków dostępu lub zagnieżdżonych typów (cokolwiek z ., -> i :: z przodu)
Powiązane problemy