Niedawno utknąłem w takiej sytuacji:
class A
{
public:
typedef struct/class {...} B;
...
C::D *someField;
}
class C
{
public:
typedef struct/class {...} D;
...
A::B *someField;
}
Zwykle możesz zadeklarować nazwę klasy:
class A;
Nie można jednak zadeklarować typu zagnieżdżonego, ponieważ powoduje to błąd kompilacji.
class C::D;
Jakieś pomysły?
c++
class
nested
forward-declaration
Calmarius
źródło
źródło
Odpowiedzi:
Nie możesz tego zrobić, to dziura w języku C ++. Musisz odblokować co najmniej jedną z zagnieżdżonych klas.
źródło
Potrzebowałem referencji takich jak:
Moim obejściem było:
Później, kiedy mogłem użyć pełnej definicji:
Ta technika byłaby prawdopodobnie większym problemem niż jest warta, gdyby istniały skomplikowane konstruktory lub inne specjalne funkcje składowe, które nie zostałyby odziedziczone płynnie. Mogłem sobie wyobrazić, że pewna magia szablonu źle reaguje.
Ale w moim bardzo prostym przypadku wydaje się, że działa.
źródło
using basename::basename;
klasy pochodnej, więc nie ma problemu ze skomplikowanymi wskaźnikami.typedef
Jeśli naprawdę chcesz uniknąć # włączenia nieprzyjemnego pliku nagłówka do pliku nagłówka, możesz to zrobić:
plik hpp:
plik CPP
Ale wtedy:
Więc tak, kompromisy ...
źródło
hpp
plik?Można to zrobić przez zadeklarowanie klasy zewnętrznej jako przestrzeni nazw .
Przykład: musimy użyć zagnieżdżonej klasy others :: A :: Nested in others_a.h, która jest poza naszą kontrolą.
inne_a.h
moja_klasa.h
moja_klasa.cpp
źródło
a::b
jest zniekształcone w ten sam sposób, bez względu naa
to, czy jest to klasa, czy przestrzeń nazw.Nie nazwałbym tego odpowiedzią, ale mimo to ciekawym znaleziskiem: jeśli powtórzysz deklarację swojej struktury w przestrzeni nazw o nazwie C, wszystko jest w porządku (przynajmniej w gcc). Po znalezieniu definicji klasy C wydaje się, że dyskretnie zastępuje obszar nazw C.
źródło
Byłoby to obejście (przynajmniej dla problemu opisanego w pytaniu - nie dla rzeczywistego problemu, tj. Gdy nie ma się kontroli nad definicją
C
):źródło
Jeśli masz dostęp do zmiany kodu źródłowego klas C i D, możesz osobno wyjąć klasę D i wprowadzić jej synonim w klasie C:
źródło