2009-12-03 2 views
19

Итак, у меня есть класс A, где я хочу назвать некоторые функции класса B. Поэтому я включаю «b.h». Но, в классе B, я хочу вызвать функцию класса A. Если я включаю «a.h», он заканчивается бесконечным циклом, верно? Что я могу сделать с этим?Может ли два класса видеть друг друга с помощью C++?

ответ

26

Каждый класс (A и B) должен иметь заголовочный файл и файл реализации.

Каждого файл заголовок (например, A.h) не должен включать в себя другой файл заголовок (например, B.h), но может включать в себя прямую ссылку на другой класс (например, заявление, как class B;), а затем могут использовать указатели и/или ссылки на другой класс в его объявлении (например, class A может содержать B* в качестве элемента данных и/или в качестве параметра метода).

Каждый файл CPP (например, A.cpp) может содержать более одного файла заголовка (например, A.h и B.h). Рекомендуется, чтобы каждый файл CPP сначала включал свой собственный заголовочный файл (например, A.cpp должен включать A.h, а затем B.h, тогда как B.cpp должен включать B.h, а затем A.h).

Каждый заголовочный файл должен содержать только объявление, а не определение класса: например, он будет перечислять подписи методов класса, но не тела/реализации метода (тела/реализации метода будут находиться в файл .cpp, а не в файле заголовка). Поскольку файлы заголовков не содержат сведений о реализации, они поэтому не зависят от (не нужно видеть) деталей других классов; в лучшем случае им нужно знать, что, например, B - это имя класса: которое оно может получить из forward declaratin, а не путем включения файла заголовка в другой заголовочный файл.

35

Вставьте только объявления функций-членов в файлы заголовка (.h) и поместите определения функций-членов в файлы реализации (.cpp). Тогда ваши файлы заголовков не должны включать друг друга, и вы можете включить оба заголовка в файл реализации.

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

class A; 

Это позволяет использовать указатели и ссылочные типы (A* и A&), хотя и не A сам. Он также не позволяет вам звонить членам.

Пример:

// a.h 
struct B; // forward declaration 

struct A { 
    void foo(B* b); // pointers and references to forward-declared classes are ok 
}; 


// b.h 
struct A; // forward declaration 

struct B { 
    void bar(A& a); // pointers and references to forward-declared classes are ok 
}; 


// a.cpp 
#include "a.h" 
#include "b.h" 

void A::foo(B* b) { 
    b->bar(*this); // full declaration of B visible, ok to call members now 
} 


// b.cpp 
#include "a.h" 
#include "b.h" 

void B::bar(A& a) { 
    a.foo(this); // full declaration of A visible, ok to call members now 
} 
-7

Попробуйте ввести #ifndef, #define и #endif вокруг ваших файлов .h.

+1

Этот пост не отвечает на вопрос .. –

Смежные вопросы