C ++ я должен использовать предварительное объявление? - PullRequest
2 голосов
/ 28 октября 2011

Я нашел этот вопрос Когда использовать предварительное объявление? , что полезно, но оно носит описательный, а не предписывающий характер.

Мой сценарий, как правило, использует указатель на другой класс либокак аргумент члена класса или функции, так что все, что мне нужно в заголовке, - это предварительное объявление (также в качестве отступления, если бы я переключился на использование boost shared_ptr, они были бы совместимы с использованием предварительных объявлений?).В настоящее время я просто включаю заголовки, но теперь мне интересно, следует ли мне использовать предварительные объявления.

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

ОБНОВЛЕНИЕ

Просто, чтобы расширить вопрос с shared_ptr (я не использую их сейчас, но рассматриваю переключение).Если бы я использовал их, я думаю, я бы использовал практику typedef для определения типа shared_ptr внутри класса.Например:

class Customer
{
public:
    typedef std::tr1::shared_ptr<Customer> SharedPointer;

    Customer() {}   
    virtual ~Customer() {}

    virtual std::string GetName() const;
};

Похоже, что это может усложнить ситуацию.Будет ли это проблематично с предварительным объявлением, и если да, то есть ли простой обходной путь?

Ответы [ 4 ]

5 голосов
/ 28 октября 2011

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

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

Так что мой (субъективный) ответ будет Да, вы должны .

1 голос
/ 28 октября 2011

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

1 голос
/ 28 октября 2011

Да, вы должны. Помните, что все, что вы включаете в заголовок, также включается, когда клиенты вашего кода используют его. Лучше всего включать в заголовок только минимальное количество файлов. Кроме того, если вам не нужно включать весь файл, и предварительное объявление является адекватным, это кажется простым выбором.

0 голосов
/ 28 октября 2011

Они обычно говорят, что вы должны использовать предварительные декларации везде, где это возможно.Это правило, как и все правила, имеет исключения.Для меня исключительные случаи часто бывают, когда имя типа слишком сложно (например, template ) или когда слишком много имен.Например, следующее является предварительным объявлением:

namespace foo
{
    namespace bar
    {
        template <typename T1, typename T2, int X>
        class MyNiftyType;
        // Hmm, maybe declare more types here?
    }
    // Hmm, maybe declare even more types here?
}

Если этого можно избежать, просто набрав #include "MyNiftyStuff.h", я бы лучше #include!

Кстати, естьстандартный заголовочный файл <iosfwd>, содержащий предварительные объявления для некоторых типов потоков.Кажется, он придуман специально для того, чтобы вы могли объявить operator<<(std::ostream&, ...) (это мое личное мнение, извините, если оно все-таки неправильно).


Редактировать: относительно shared_ptr<type>.

* 1017Грубо говоря, единственное, что вы можете сделать с общими указателями (для объявленных вперед типов), это объявить функции.Если вы хотите определить функцию, которая делает что-то полезное с shared_ptr<type>, вы не можете просто объявить type.Например:

MyCode.h

class MyClass;
void DoMuchStuff(shared_ptr<MyClass> ptr); // declaration - OK
inline void DoDoubleStuff(shared_ptr<MyClass> ptr) // definition - not OK!
{
    void DoMuchStuff(ptr);
    void DoMuchStuff(ptr);
}

Если бы я использовал обычный указатель вместо shared_ptr, это работало бы с предварительными объявлениями.Но это неудобство редко поражает вас - либо у вас есть просто объявления в ваших .h файлах, либо ваши встроенные функции достаточно сложны, так что вам все равно нужно #include полное объявление для вашего класса.

...