为什么要包含标头并向前声明同一 cpp 文件中包含的类?

发布于 2024-10-16 11:55:42 字数 344 浏览 9 评论 0原文

我一直在为我的大学项目查看 Fear SDK,但注意到一些代码,如下所示:

Foo.h

class Foo
{
    public:
        int iSomething;
};

Bar.cpp:

#include "Foo.h"

// Forward declarations
class Foo;

是否有任何特殊原因需要转发声明并在同一 cpp 文件中包含适当的标头?或者前向声明是否多余,因为包含了标头?

编辑:

每次我在代码中看到它时,包含语句总是位于前向声明之前。

I've been looking at the Fear SDK for my university project, but have noticed some code like so:

Foo.h

class Foo
{
    public:
        int iSomething;
};

Bar.cpp:

#include "Foo.h"

// Forward declarations
class Foo;

Is there any particular reason to forward declare AND include the appropriate header in the same cpp file? Or is the forward declaration redundant because the header is being included?

EDIT:

Every time that I have seen it in the code, the include statement is always before the forward declaration.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

睫毛溺水了 2024-10-23 11:55:42

这不仅仅是多余的,而且还可能存在问题。假设 Foo.h 发生变化,那么 Foo 就会成为通用、模板化等价物的某些特定实例的 typedef - 这种事情可以预见为正常软件演化的一部分。那么 Bar.cpp 的“class X”将不必要地导致编译错误 ala:

--- fwd.h ---
template <typename T>
class XT
{
  public:
    int n_;
};

typedef XT<int> X;

--- fwd.cc ---
#include "fwd.h"

class X;

int main()
{
    X x;
    x.n_ = 0;
    return x.n_;
}

--- compilation attempt ---
~/dev  .../gcc/4.1.1/exec/bin/g++ fwd.cc -o fwd
fwd.cc:3: error: using typedef-name 'X' after 'class'
fwd.h:8: error: 'X' has a previous declaration here

这是我总是建议使用专用前向声明标头 ala 的原因之一,由主标头维护并包含在主标头中以确保持续的一致性。我从来没有把“X类;”在实现文件中,除非该类也在其中定义。请记住“X 级”看似的好处;前向声明并不是说它们避免了 #include,更重要的是它们包含的文件可能很大,进而包含许多其他文件:专用前向声明标头通常会避免绝大多数文件无论如何。

It's more than simply redundant, it's potentially problematic. Say Foo.h changes so Foo becomes a typedef to some particular instantiation of a generic, templatised equivalent - the kind of thing that can be anticipated as part of normal software evolution. Then Bar.cpp's "class X" will needlessly cause a compilation error ala:

--- fwd.h ---
template <typename T>
class XT
{
  public:
    int n_;
};

typedef XT<int> X;

--- fwd.cc ---
#include "fwd.h"

class X;

int main()
{
    X x;
    x.n_ = 0;
    return x.n_;
}

--- compilation attempt ---
~/dev  .../gcc/4.1.1/exec/bin/g++ fwd.cc -o fwd
fwd.cc:3: error: using typedef-name 'X' after 'class'
fwd.h:8: error: 'X' has a previous declaration here

This is one reason I always recommend using dedicated forward-declaration headers ala <iosfwd>, maintained with and included by the main header to ensure ongoing consistency. I never put "class X;" in an implementation file unless the class is defined in there too. Remember that the seeming benefits of "class X;" forward declarations is not so much that they avoid an #include, and more that the files they include can be large and in turn include a lot of other files: dedicated forward-declaration headers typically avoid the overwhelming majority of that anyway.

淡淡離愁欲言轉身 2024-10-23 11:55:42

如果前向声明出现在包含之前,则可能会消除依赖性。在定义它的实际 .h 文件之后什么也不做。

If the forward declaration came before the includes, it might eliminate a dependency. Coming after the actual .h file that defines it does nothing.

很酷不放纵 2024-10-23 11:55:42

原来的class Foo;可能已经退化了。

请记住,如果源仅使用指向 Foo 类的指针 [并且实际上并未尝试创建 Foo 对象或取消引用 Foo 指针],则在使用它之前不需要定义该类。

如果没有看到代码,我会冒险猜测 bar.cpp 的原始版本具有不需要定义 foo 的代码。

我在大型项目中使用前向声明来减少编译时间。当需要一秒钟的时间时,编译时间不是问题,但是当项目需要一个小时来构建时,每一秒都会有帮助:)

The original class Foo; may have been vestigial.

Remember that, if the source only uses pointers to Foo class [and does not actually try to create Foo objects or dereference Foo pointers], you dont need to define the class before using it.

Without seeing the code, I'd hazard the guess that the original version of bar.cpp had code that did not require the definition of foo

I use forward declarations in large projects to reduce compile time. compile time is not a problem when it takes a second, but when projects take an hour to build every second helps :)

夕色琉璃 2024-10-23 11:55:42

前置声明是多余的,但也无害。也许作者使用了大量的前向声明,并且没有严格确保它们始终是必需的。

The forward declaration is redundant, but also quite harmless. Maybe the author uses a lot of forward declarations, and doesn't rigorously ensure they are always required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文