2011-11-17 17 views
5

mogę zadeklarować wskaźnik do klasy, która nie została jeszcze zdefiniowana w następujący sposób:Deklarowanie klas zagnieżdżonych, zanim zostaną one zdefiniowane

class A ; 
A* p ; 

Ale jak mam to zrobić dla zagnieżdżonych klasy? Chcę to zrobić:

class A ; 
class A::B ; // error: 'B' in class 'A' does not name a type 
A::B* p ; 

Ale nie kompiluje się (używając g ++ 4.5.2). Czy jest jakiś sposób, aby to zadziałało?

+0

Po prostu nie zagnieżdżaj B, jeśli tego potrzebujesz. (Możesz grupować klasy z przestrzeniami nazw Nesting - przynajmniej w C++ 03 - nie dodaje żadnej innej wartości.) – visitor

+0

Nie jest możliwe, dopóki klasa "A" nie zostanie zdefiniowana. Musisz przeprojektować, aby nie używać klas zagnieżdżonych do czasu zdefiniowania klasy zawierającej klasę zagnieżdżoną. –

+0

Zobacz także [Czy istnieje krótsza metoda przekazywania deklaracji klasy w przestrzeni nazw?] (Http://stackoverflow.com/questions/1368642). – outis

Odpowiedz

4

Istnieje szereg części C++ 03, które niemal uniemożliwiają przodu deklaracje klas zagnieżdżonych. W szczególności, § 7.1.5.3 opracowany typu specyfikatory:

  1. Jeśli opracowana-type-specifier jest jedynym składnikiem oświadczenie, deklaracja jest źle sformułowane, chyba że jest wyraźna specjalizacja (14.7.3), wyraźne instancji (14.7.2) lub ma jedną z następujących form:

    class-keyidentifier ; 
    friend class-key ::optidentifier ; 
    friend class-key ::opttemplate-id ; 
    friend class-key ::optnested-name-specifieridentifier ; 
    friend class-key ::optnested-name-specifiertemplateopt 
    template-id ; 
    
  2. 3.4.4 opisuje sposób wpływy wyszukiwanie nazw dla identyfikatora w specyfikator typu opracowanego. Jeśli identyfikator postanawia o nazwa-klasy lub enum-name The opracowana-type-specifier wprowadza go do deklaracji ten sam sposób prosty typu specifier wprowadza jego nazwa-typu. [...] Jeśli wyszukiwanie nazwy nie znajduje deklaracji dla nazwy, specyfikacja typu opracowanego jest niepoprawnie sformułowana, chyba że jest w postaci prostegoklucz klasy identyfikator, w którym to przypadku identyfikator jest deklarowane jak opisano w 3.3.1.

W skrócie, gdy identyfikator jest zawężona, kompilator musi spróbować rozwiązać ten identyfikator. Gdy zasięg jest klasą, kompilator musi wyszukać deklarację dla identyfikatora w zewnętrznej klasie. Kiedy klasa zewnętrzna nie została jeszcze zdefiniowana, nie można tego zrobić, a rezultatem jest źle sformułowany program.

3

Zastanów się przestrzeni nazw zamiast zagnieżdżonej klasy.

class A; 
A * pa; 
namespace A_help 
{ 
    class B; 
} // namespace A_help 
A_help::B * pb; 
Powiązane problemy