недопустимое предварительное объявление структуры

-- РЕДАКТИРОВАТЬ -- Извините, что я запутал людей, я просто быстро набрал этот код вместо копирования и вставки, поэтому я фактически делаю #ifndef A_H #define A_H в своем коде. Я изменил приведенный ниже код, чтобы показать, что
-- Завершить редактирование --

У меня есть два класса, каждый из которых содержит указатель на экземпляр другого класса, но это создает мне проблемы. Мой код похож на следующий

// A.h
#ifndef A_H
#define A_H

class B; // compiler error here

class A
{
  B* foo;
  // other members and functions
};

#endif

// A.cpp
#include "A.h"
#include "B.h"
/*
 declare functions and use methods in both A and B
*/

// B.h
#ifndef B_H
#define B_H

class A;

class B
{
  A** bar;
// other stuff
};

#endif

//B.cpp
#include "A.h"
#include "B.h" 
/*
declare functions and use methods in both A and B
*/

Мне сказали, что будет работать предварительное объявление другого класса в заголовочном файле, а затем включение другого файла в файл cpp, но в отмеченной строке я получаю сообщение об ошибке, которое просто говорит: «упреждающее объявление« структуры b »».

Может ли кто-нибудь сказать мне, что я делаю неправильно?


person Raphael    schedule 09.09.2012    source источник
comment
Я собираюсь предположить, что ваши охранники включения испортили имена классов.   -  person chris    schedule 09.09.2012
comment
Согласен, #define blah \n class blah будет заменен на class [nothing here].   -  person Chris Eberle    schedule 09.09.2012
comment
@Raphael, я советую вам прочитать какой-нибудь подлинный исходный код POSIX. Они всегда используют #ifndef __FILENAME_H__ и т. д.   -  person    schedule 09.09.2012
comment
@H2CO3, правда? Это плохо (по крайней мере, для кода без реализации). Я согласен с логикой, стоящей за этим, но stackoverflow.com/questions/228783/. Я всегда использую FILENAME_H.   -  person chris    schedule 09.09.2012
comment
@OP, с закомментированными включениями код работает на GCC 4.7.1.   -  person chris    schedule 09.09.2012
comment
@chris Я имею в виду код реализации. И я знаю о наличии этого вопроса, но я не собираюсь подчиняться его «правилам». Они глупые.   -  person    schedule 09.09.2012
comment
@ H2CO3: реализации не разрешено использовать такие имена, как A_H, потому что они зарезервированы для использования обычными смертными (нами). Точно так же нам не разрешено использовать имена, начинающиеся с подчеркивания, потому что они зарезервированы для реализации. Правила в другом вопросе совсем не глупые. Они выделяют независимые фрагменты пространства имен, чтобы и пользователи, и разработчики могли работать, не нарушая случайно код друг друга.   -  person Jonathan Leffler    schedule 09.09.2012


Ответы (1)


Включите один заголовок, скажем, b.h в a.h. Не пересылать объявление B в a.h. b.h может остаться как есть.

В противном случае вы получите что-то вроде

class B {};
....
class B;

Всегда разумно выполнять предварительную обработку только таких ошибок.

person PiotrNycz    schedule 09.09.2012