Они обычно говорят, что вы должны использовать предварительные декларации везде, где это возможно.Это правило, как и все правила, имеет исключения.Для меня исключительные случаи часто бывают, когда имя типа слишком сложно (например, 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
полное объявление для вашего класса.