需要转发声明或完整定义

时间:2013-07-12 06:33:15

标签: c++ compiler-construction forward-declaration

虽然我在很长一段时间内一直使用前瞻声明,但从未认真考虑过它(我的错误)

如果有人可以给我指针或关于以下查询的任何链接,那将会很有帮助:

  1. 我们如何确定是否需要转发声明或包含是否必需?
  2. 在这种情况下编译器如何实际工作?任何开销?
  3. 假设我有两个相互依赖的类A和B.它们都使用彼此的对象,我是否需要在两个类中转发声明。

2 个答案:

答案 0 :(得分:2)

我会说:

  1. 如果您只需要一个引用或指向标题中类的指针 - >使用前瞻性声明。
  2. 带有include的开销是编译器会看到当前头的更多依赖关系,因此可能会不必要地重新编译你的c ++ body文件。
  3. 如果可能的话。

答案 1 :(得分:0)

当编译器只需要知道某个对象存在但不需要它的大小或对象的其他细节时,总是可以使用前向声明。

例如,在某些.h文件中,您有:

MyClass *foo(MyClass *p);

在example1.cpp中:

// No include needed, forward declaration is ok.
MyClass *foo(MyClass *p)
{
    foo2(p);
    return p;
}

在example2.cpp中:

// include needed, forward declaration is not ok.
MyClass *foo(MyClass *p)
{
    p->ClassFkt();
    return p;
}

在example3.cpp中:

// include needed, forward declaration is not ok.
MyClass *foo(MyClass *p)
{
    MyClass *n = new MyClass();
    foo2(p, n);
    return n;
}

这里有一个带指针的函数原型。指针始终具有已知大小,因此可以在此处使用前向声明。

只要您只使用指针(例如将其传递给其他函数),您就不需要包含。如果您尝试访问某些成员或执行其他需要了解更多详细信息的操作,则还需要包含头文件。在上面的例子1中,您不需要完整的声明,前向声明就足够了。在secaond示例中它不是,因为编译器不知道您的类是否具有被调用的函数。在第三个示例中,仅使用指针,但由于new需要知道大小,因此前向声明是不够的。

为了避免额外的头依赖关系,您可以使用上例中的.h文件中的forward声明,并仅在cpp文件本身中执行include。