在我的C ++项目中何时必须使用头文件的包含(#include "myclass.h"
)?我什么时候必须使用类的前向声明(class CMyClass;
)?
答案 0 :(得分:20)
通常首先尝试前进声明。这将减少编译时间等。如果不编译则转到#include
。如果您需要执行以下任何操作,则必须使用#include:
new
/ delete
,复制等。(来自@Mooing Duck的6,7,8,9)
他们可能更多,但我今天没有得到我的语言法律。
答案 1 :(得分:11)
如果您只需要指向该类的指针,并且您不需要任何有关该类的知识而不需要其名称,则可以使用前向声明。
答案 2 :(得分:11)
转发声明有几个问题:
其他人难以维持前瞻声明。例如,如果头文件包含:
include "MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h"
而不是前向声明
class Foo ;
其他人很容易找到声明类Foo的位置。有了前瞻性声明,它不是那样的 明显;某些IDE(如Eclipse)可能会在用户尝试打开时打开前向声明 声明变量。
"Could not find file MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h"
之类的错误更方便,因为那时您将知道在哪里查找相应的Foo.cpp
并识别包含它的库。如果您认为您的构建花费的时间太长,那么尝试仅在没有链接的情况下进行编译。如果您的代码编译需要10秒钟,链接需要10分钟,则问题与一些额外的包含无关。同样,如果你的头文件包含很多东西,实际上它会导致性能问题,那么你可能需要时间将该文件的内容重构为多个较小的头文件。
那么什么时候可以转发申报?如果您在与真实声明相同的头文件中执行此操作。
示例:
class Foo ;
typedef Foo* FooPtr ;
typedef Foo& FooRef ;
class Foo
{
public:
Foo( ) ;
~Foo( ) ;
}
OR
class TreeNode ;
class Tree
{
private:
TreeNode m_root ;
}
class TreeNode
{
void* m_data ;
} ;
答案 3 :(得分:2)
作为初学者,当你需要使用它们包含的类型或函数时,你应该总是#include头文件 - 不要试图通过向前声明事物“优化”你的构建 - 这几乎不需要,即使在大型项目中也是如此,只要项目设计得很好。
你绝对需要前瞻声明的唯一时间是这样的情况:
struct A {
void f( B b );
};
struct B {
void f( A a );
};
其中每个结构(或类)引用另一个结构(或类)的类型。在这种情况下,您需要B的前向声明来解决问题:
struct B; // forward declaration
struct A {
void f( B b );
};
struct B {
void f( A a );
};
答案 4 :(得分:2)
您应该努力最小化#include
两者,以减少编译时间,同时也有助于模块化和可测试性。正如@ypnos所说,当你只需要指针时,前锋非常出色。
有关如何减少标头依赖关系的一些实用技巧,请参阅例如this article。