2012-01-24 2 views
0

Если у вас довольно простой вопрос (по крайней мере, я надеюсь, что так), но я не могу понять, что делать, чтобы сказать g ++ в каком порядке «завершить» мои классы. Я уменьшил его до этого простого примера:gcc: компиляция класса перекрестных ссылок

base.h:

#ifndef BASE_H_ 
#define BASE_H_ 

#include "otherclass.h" 
class otherclass; 

class base { 
    public: 
     base(otherclass* other); 

    protected: 
     otherclass* m_other; 
}; 

#endif /* BASE_H_ */ 

derived.h:

#ifndef DERIVED_H_ 
#define DERIVED_H_ 

#include "base.h" 

class derived : public base { 
    public: 
     derived(otherclass* other); 
}; 

#endif /* DERIVED_H_ */ 

(как соответствующие .cpp файлов содержат только конструкторы, назначающие данные OtherClass * в переменные-члены)

otherclass.h:

#ifndef OTHERCLASS_H_ 
#define OTHERCLASS_H_ 

#include "derived.h" 

class otherclass { 
    public: 
     otherclass(); 

    protected: 
     derived* m_derived; 
}; 

#endif /* OTHERCLASS_H_ */ 

otherclass.cpp:

#include "otherclass.h" 

otherclass::otherclass() { 
    m_derived = new derived(this); 
} 

Поскольку это может иметь отношение я вставить весь вывод SCons:

g++ -o base.o -c base.cpp 
g++ -o derived.o -c derived.cpp 
In file included from otherclass.h:4:0, 
      from base.h:4, 
      from base.cpp:1: 
derived.h:8:29: error: expected class-name before '{' token 
g++ -o main.o -c main.cpp 
In file included from base.h:4:0, 
      from derived.h:4, 
      from derived.cpp:1: 
otherclass.h:11:3: error: 'derived' does not name a type 

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

Я действительно не вижу проблемы здесь (за исключением сообщения об ошибке, конечно).

Может кто-нибудь просветить меня?

ответ

0

Ha! Поиск с помощью Google для моей проблема не помогла мне, но вкладка связанных вопросов в StackOverflow сделали;)

Для справки, решение заключается в следующем:

В заголовочных файлах, если у вас есть только указатели на класс вас должны

  1. predeclare класс (это то, что я делал раньше), как

    класс OtherClass;

    в base.h и derived.h и

    класс, производный;

    в otherclass.h, но

  2. сделать не включать соответствующие файлы заголовков. Только включают их в свои .cpp-файлы (вот что я не смог).

Объяснение: Так как указатели всегда одного и того же размера и их целевой тип имеет значение, только если вы на самом деле работать с (т.е. разыменования) им, что вполне достаточно для GCC принять производный * если вы сообщите ему о существование идентификатора «производного» (т.е. предположения). На самом деле все в порядке, если вы избегаете включения в заголовок (собственных) заголовочных файлов, тип которых используется только таким образом (не обязательно должен быть завершен).

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