Зачем включать заголовок и вперед объявлять класс, содержащийся в том же файле cpp? - PullRequest
5 голосов
/ 08 февраля 2011

Я искал Fear SDK для своего университетского проекта, но заметил такой код:

foo.h

class Foo
{
    public:
        int iSomething;
};

Bar.cpp:

#include "Foo.h"

// Forward declarations
class Foo;

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

EDIT:

Каждый раз, когда я вижу это в коде, оператор include всегда перед предварительным объявлением.

Ответы [ 4 ]

6 голосов
/ 08 февраля 2011

Это больше, чем просто избыточность, это потенциально проблематично.Скажем, Foo.h меняется, так что Foo становится typedef для какого-то конкретного экземпляра общего, шаблонизированного эквивалента - такого рода вещи, которые можно ожидать как часть нормальной эволюции программного обеспечения.Тогда «класс X» из Bar.cpp излишне вызовет ошибку компиляции ala:

--- fwd.h ---
template <typename T>
class XT
{
  public:
    int n_;
};

typedef XT<int> X;

--- fwd.cc ---
#include "fwd.h"

class X;

int main()
{
    X x;
    x.n_ = 0;
    return x.n_;
}

--- compilation attempt ---
~/dev  .../gcc/4.1.1/exec/bin/g++ fwd.cc -o fwd
fwd.cc:3: error: using typedef-name 'X' after 'class'
fwd.h:8: error: 'X' has a previous declaration here

Это одна из причин, по которой я всегда рекомендую использовать выделенные заголовки прямого объявления ala <iosfwd>, поддерживаемые и включаемые основнойзаголовок для обеспечения постоянной согласованности.Я никогда не ставлю "класс X";в файле реализации, если там тоже не определен класс.Помните, что кажущиеся преимущества "класса X";Форвардные декларации не столько ограничивают #include, сколько в том, что включаемые в них файлы могут быть большими и, в свою очередь, включать в себя множество других файлов: выделенные заголовки форвардных деклараций обычно в любом случае избегают подавляющего большинства.

3 голосов
/ 08 февраля 2011

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

2 голосов
/ 08 февраля 2011

Оригинал class Foo; мог быть рудиментарным.

Помните, что если источник использует только указатели на класс Foo [и фактически не пытается создавать объекты Foo или разыменовывать указатели Foo], вам не нужно определять класс перед его использованием.

Не видя код, я рискнул бы предположить, что исходная версия bar.cpp содержала код, который не требовал определения foo

Я использую предварительные объявления в больших проектах, чтобы уменьшитьвремя компиляции.Время компиляции не проблема, если на это уходит секунда, а когда на создание проектов уходит час, каждая секунда помогает:)

1 голос
/ 08 февраля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...