需要转发声明或完整定义

Forward declaration or complete definition required

本文关键字:定义 声明 转发      更新时间:2023-10-16

尽管我使用正向声明已经有相当长的一段时间了,但从未认真考虑过(我的错误)

如果有人能给我关于以下问题的建议或任何链接,这将是有帮助的:

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

我想说:

  1. 如果您只需要一个引用或指针指向头->中的类,请使用正向声明
  2. include的开销是编译器将看到当前标头的更多依赖项,因此可能会不必要地重新编译c++主体文件
  3. 如果可能的话,是的
当编译器只需要知道某个对象存在,而不需要它的大小或对象的其他详细信息时,总是可以使用正向声明。

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

MyClass *foo(MyClass *p);

示例1.cpp:

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

示例2.cpp:

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

示例3.cpp:

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

这里有一个使用指针的函数原型。指针的大小总是已知的,所以这里可以使用正向声明。

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

为了避免额外的头依赖性,您可以在上面的示例中使用.h文件中的正向声明,并且只在cpp文件本身中执行include。