2013-11-25 6 views
1

У меня проблема с компиляцией с круговыми зависимостями. Я сделал некоторые исследования, и люди рекомендовали использовать форвардную декларацию. У меня все еще есть проблема с этим, потому что класс, который имеет объявление вперед, использует методы из перенаправленного класса. Это заставляет компилятор дать мне ошибку «Класс A имеет неполное поле b». Как я могу обойти круговую зависимость, где A требует B, а B - A?Убивание круговой зависимости

хиджры:

#ifndef A_H_ 
#define A_H_ 

#include <iostream> 
//#include "B.h" 

class A 
{ 
    class B; 
    private: 
     B b; 
    public: 
     A(); 
     ~A(); 
     void method(); 
}; 
#endif 

a.cpp:

#include <iostream> 
#include "A.h" 

A::A() 
{ 
} 

A::~A() 
{ 
} 

void A::method() 
{ 
    b.method(); 
} 

B.h:

#ifndef B_H_ 
#define B_H_ 

#include <iostream> 
//#include "A.h" 

class B 
{ 
    class A; 
    private: 
     A a; 
    public: 
     B(); 
     ~B(); 
     void method(); 
}; 
#endif 

B.cpp:

#include <iostream> 
#include "B.h" 

B::B() 
{ 
} 

B::~B() 
{ 
} 

void B::method() 
{ 
    a.method(); 
} 
+2

Таким образом, объект 'A' содержит' B', который содержит 'A', который содержит' B', который содержит 'A', который содержит' B' ... – crashmstr

+1

Вы не можете имеют 'A' внутри' B' и 'B' внутри' A'. Вы можете сделать указатель на A внутри B или указатель на B внутри A – balki

ответ

3

Это не будет работать, как вы построили его как A требует полного знания о размере B и B требует того же A, который предоставляется только путем просмотра полной декларации.

Следующая недействительный:

class B; 
class A { 
    B b; 
}; 

Почему? Сколько места мы выделяем для экземпляра A? sizeof(A) = sizeof(B) = undefined Существует обходной путь, однако:

class B; 
class A { 
    B* b_ptr; 
    B& b_ref; 
}; 

Это вполне допустимо, так как указатель и размер Reference, как известно, независимо от типа они указывают.

3

В на по крайней мере, один случай (либо A, либо B), вы должны удалить зависимость от полного типа. Например, ниже я удалил необходимость A иметь полный тип B внутри файла в A.h заголовка:

// A.h 
class B; 

// B used as a reference only, so the complete type 
// is not needed at this time 
class A 
{ 
public: 
    A(B& b) : b_(b) {} 

    void method(); 

private: 
    B& b_; 
}; 

// A.cpp 
// B is used, and the complete type is required 
#include "B.h" 

void A::f() 
{ 
    b.method(); 
} 
7

Ваши классы не могут работать. Каждый A содержит B, который содержит A, который содержит B и т. Д., До бесконечности.

2

Вы можете попробовать заменить один из членов указателем на другой класс:

class B; 
class A 
{ 
    private: 
     B* b; 
    public: 
     A(); 
     ~A(); 
     void method(); 
}; 
Смежные вопросы