类 foo;在头文件中
有人能解释一下为什么头文件有这样的东西吗?
class foo; // This here?
class bar
{
bar();
};
使用这个的时候需要include语句吗?
谢谢。
Is some one able to explain why header files have something like this?
class foo; // This here?
class bar
{
bar();
};
Do you need an include statement when using this?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
第一个
class foo;
被称为类 foo 的前向声明 。它只是让编译器知道它存在并且它命名了一个类。这使得 foo 成为所谓的“不完整类型”(除非已经看到 foo 的完整声明)。对于不完整类型,您可以声明该类型的指针,但无法分配该类型的实例或执行任何需要知道其大小或成员的操作。当两种类型都可能具有指向彼此的指针时,经常使用这种前向声明,在这种情况下,两者都需要能够表达指向另一种类型的指针的概念,因此如果没有这样的东西,您将产生循环依赖。之所以需要这样做,主要是因为 C++ 使用单遍机制来解析类型;在 Java 中,无需前向声明即可拥有循环依赖关系,因为 Java 使用多次传递。您还可能会看到前向声明,其中作者有一种错误的印象,即使用前向声明而不是包含所需的标头会减少编译时间;当然,情况并非如此,因为您需要包含完整的声明(即标头),无论如何,如果使用预处理器防护,那么编译时间基本上没有区别。
要回答您是否需要包含的问题...假设您只需要部分类型,那么您的标头不需要直接包含已前向声明的类型的标头;但是,无论谁使用您的标头,当他们使用您的类型时,都需要包含前向声明类型的标头,因此您最好只包含其他标头。
The first
class foo;
is called a forward declaration of the class foo. It simply lets the compiler know that it exists and that it names a class. This makes foo what is called an "incomplete type" (unless the full declaration of foo has already been seen). With an incomplete type, you can declare pointers of that type, but you cannot allocate instances of that type or do anything that requires knowing its size or members.Such forward declarations are frequently used when two types each may have pointers to each other, in which case both need to be able to express the notion of a pointer to the other type, and so you would have a circular dependency without such a thing. This is needed mostly because C++ uses a single pass mechanism for resolving types; in Java, you can have circular dependencies without forward declarations, because Java uses multiple passes. You may also see forward declarations where the author is under the misguided impression that using forward declarations instead of including the required header reduces compile time; that, of course, is not the case, because you need to include the full declaration (i.e. the header), anyway, and if preprocessor guards are used, then there is basically no difference in compile time.
To answer your question on whether you need the include or not... assuming you only need a partial type, then your header does not need to directly include the header for the type that has been forward declared; however, whoever makes use of your header, when they use your type will need to include the header for the forward declared type, and so you might as well just include the other header.
这是一个前向声明。例如,如果类 bar 有一个指向 foo 对象的指针,但您不想立即包含 foo 对象的整个定义,则需要它。
That's a forward declaration. You need it for example if class bar has a pointer to a foo object, but you don't want to include the whole definition of the foo object immediately.
这是该类的前向声明。
根据我的经验,这通常是在有循环依赖时完成的......例如
this is a forward declaration of the class.
In my experience, this is typically done when you have a circular dependency.. for example
只是好奇,为什么我们需要术语“前向声明”?前向声明不就是一个声明(而不是定义)吗?
Just curious, why do we need the term forward declaration at all? Isn't a forward declaration simply a declaration (as opposed to a definition)?
这是一个前瞻性声明。考虑以下示例:
如果您没有以编译器在编译
class bar
的定义之前看到它的方式包含class foo
的定义,则代码将不会编译(编译器会说它不知道foo
的含义),除非你有前向声明。That's a forward declaration. Consider the following example:
If you haven't included the definition of
class foo
in such a way that the compiler sees it before compiling the definition ofclass bar
the code will not compile (the compiler will say it doesn't know whatfoo
means) unless you have the forward declaration.这是“foo”类的前向声明。它允许您声明类的指针和引用,但不能使用它(例如调用成员或确定其大小),因为它尚未定义!随后必须跟上完整的正常声明 (
class foo { ... };
)。它对于声明两个相互保存指针的类非常有用,否则将无法设置它们。
It's a forwards declaration of the class 'foo'. It allows you to declare pointers and references to the class, but not use it (eg. call members or determine its size), because it's not yet defined! It must later be followed up with a full, normal declaration (
class foo { ... };
).It's useful for things like declaring two classes which hold pointers to each other, which otherwise would be impossible to set up.
这称为前向声明。类
foo
的主体将在文件的后面部分定义。进行前向声明是为了避免循环依赖:类 Bar 的定义需要类 Foo,反之亦然。如您所见,
Bar
引用了Foo
,反之亦然。如果您尝试编译它,编译器会抱怨说它不知道有关Foo
的任何信息。解决方案是在Bar
上方声明class Foo
(就像在main
上方声明函数的原型并定义其主体一样)之后)。This is called forward declaration. The body of the class
foo
would be defined at a later part of the file. Forward declaration is done to get around cyclic dependencies: The definition of class Bar requires class Foo and vice versa.As you can see,
Bar
has a reference toFoo
and vice versa. If you try to compile this, the compiler will complaint saying that it doesn't know anything aboutFoo
. The solution is to forward declare theclass Foo
above theBar
(just like you declare the prototype of a function above themain
and define its body later).这称为前向声明。它用于让您的代码知道类 foo 的存在。这又可以被类栏使用。
它通常用于解决循环包含问题。以此为例
,
这会导致循环包含问题,因为 ah 包含 bh,bh 又包含 ah,直到无穷大。您可以通过在每个标头中对每个类进行前向声明来解决此问题,如下所示:
注意: 通常,当您遇到循环包含问题时,这表明存在概念/建模问题。在尝试使用前向声明解决问题之前,您可能应该问自己您的类是否定义良好。
This is called a forward declaration. It is used to make your code aware that the class foo exists. This in turn can be used by the class bar.
It's commonly used to solve circular includes problems. Take this for example
and
This causes a circular include problem, because a.h includes b.h which in turns includes a.h, to infinity. You can solve this problem by making a forward declaration of each class in each header, like so :
Note : Very often when you have a circular include problem, this is indicative of a conception/modelling problem. You should probably ask yourself if your classes are well defined before trying to solve your problem with forward declarations.
尝试考虑这样写:
file bar.h:
file foo.h:
这是行不通的,首先是由于无限的 #include 链,然后如果你删除其中一个包含,则 Foo 将不知道 Bar 是什么是,否则 Bar 不会知道 Foo 是什么。
试试这个:
文件 foo.h:
Try to think of writing this:
file bar.h:
file foo.h:
This won't work, first due to infinite #include chain, then if you get rid of one of the includes, either Foo won't know what Bar is, or Bar won't know what Foo is.
Try this instead:
file foo.h: