2011-12-26 2 views
2

В этом проблема. Мне нужно написать файл заголовка с двумя классами, например класс A и класс B.о объявлении класса в файле заголовка C++

В классе AI есть функция, которая использует объект класса B и наоборот, т.е. в классе BI есть функция, которая использует объекты класса A.

Если A объявлено первым, тогда будет ошибка, что класс B не был объявлен. Как с этим бороться? Стараюсь функцию класса А объявить после объявления класса B:

void classA::myfunc (classB *b); 

Но я получил ошибку, что функция MyFunc не объявлена. Опытные люди на C++, что делать?

Добавлен: вот хорошая ссылка about header

ответ

8

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

Я уверен, что вы просто используете указатели для доступа к этим классам, у которых есть ссылка на другую, не так ли? Знаете, потому что, если вы используете экземпляры, вы получаете цикл экземпляра. Используйте форвардные декларации.

Вот пример того, как можно использовать вперед деклараций:

Ах

class B; 
class C; 
class D; 
class E; 

class A { 
    B* pointer; //To just have a pointer to another object. 
    void doThings(C* object); //if you just want to tell that a pointer of a object is a param 
    D* getThings(); //if you wanna tell that a pointer of such class is a return. 
    E invalid(); //This will cause an error, because you cant use forward declarations for full objects, only pointers. For this, you have to use #include "E.h". 
}; 

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

Bh

class A; 
class B { 
    A* pointer; //That can be done! But if you use a includes instead of the forward declarations, you'll have a include looping, since A includes B, and B includes A. 
} 

Как упоминалось Тони Делрой (большое спасибо ему) Вы не должны t ВСЕГДА используйте этот дизайн. Он предоставляется компилятором C++, но это не очень хорошая практика. Лучше всего, чтобы обеспечить ссылочный заголовок, так что ваш код будет выглядеть следующим образом:

Ач

#include "B.fwd.h" 
#include "C.fwd.h" 
#include "D.fwd.h" 
#include "E.fwd.h" 

class A { 
    B* pointer; //To just have a pointer to another object. 
    void doThings(C* object); //if you just want to tell that a pointer of a object is a param 
    D* getThings(); //if you wanna tell that a pointer of such class is a return. 
    E invalid(); //This will cause an error, because you cant use forward declarations for full objects, only pointers. For this, you have to use #include "E.h". 
}; 

и ваши вперед заголовки вроде этого:

B.fwd.h:

class B; 

В вашем fwds вы должны иметь декларацию о своем классе и любые typedefs, которые прилагаются к ней.

Я не упоминая #pragma once или #ifndef B.H... вы знаете, что они будут там: D

Ваш код будет на стандартном определенном <iosfwd> и лучше поддерживать, особенно, если они являются шаблонами.

+0

Это касается не только указателей, но и параметров методов и типа возврата. – Geoffroy

+0

Да, я знаю, но я не сказал, что это просто для указателей, я сказал, что если вам не нужен полный объект, то есть реализация. И ах, простите меня, но почему вы отметили мой ответ, а @boydc один не полезен? это не так, lol –

+0

Объявление, а не реализация :) А также, если вам нужно знать размер объекта, обычно при объявлении переменной экземпляра этого типа. – Geoffroy

3

Короткий ответ:

class classA; 

Тогда вы определили свой ClassB, а затем декларация CLASSA.

Это называется предобъявлением, и там, чтобы решить вашу проблему :)

+1

Обычно вы хотите объявить общие классы, если необходимо, в общий заголовок. Предварительно скомпилированные заголовки или общий заголовок библиотеки (с перечислениями и классами и т. Д.) Подходят для этого. – ssube

0
you can do like this: 

try to add a uncomplete decleration of a class before you use it with a ref or ptr 

classA.h: 


class classB; 

class classA { 
     void fun(classB * b); 
} 


classB.h: 

class classA; 

class classB { 
     void fun(classA * a); 
} 


classA.cpp: 

#include "classA.h" 
#include "classB.h" 

... 

classB.cpp: 

#include "classA.h" 
#include "classB.h" 

... 
+0

Попытайтесь объяснить, что вы делаете. – Geoffroy

+0

объяснил ..... – boydc

+0

Не совсем нет :) И попробуйте правильно отформатировать ваш ответ :) – Geoffroy

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