gcc: компиляция перекрестных ссылок на классы - PullRequest
0 голосов
/ 24 января 2012

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

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_ */

производный.h:

#ifndef DERIVED_H_
#define DERIVED_H_

#include "base.h"

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

#endif /* DERIVED_H_ */

(оба соответствующих файла .cpp содержат только конструкторы, которыеназначьте указанный другой класс * переменным-членам)вставьте весь вывод 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

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

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

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

1 Ответ

0 голосов
/ 24 января 2012

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

Для справки, решение таково:

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

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

    класс другой класс;

    в base.h и производном.h и

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

    в otherclass.h, но

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

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

...