C/C++前向声明与包含
当您包含某些文件时会发生什么以及当您转发声明某些函数/类时会发生什么?如果两个文件包含相同的文件,第一个文件会成功读取所有函数,第二个文件会失败,但仍然能够使用这些函数?
当我转发声明某个函数时会发生什么?这个函数现在是“已保存”并且我可以在任何地方使用它还是仅针对同一文件已知?那么为什么两个带有 include 的文件(到带有防护的文件)会起作用?
我可以将所有内容都包含在主要内容中而不再打扰吗?
编辑:
为什么 cpp 文件应包含其标头?如果我不包括它们怎么办?
What is happening when you include some file and what is happening when you forward declare some function/class? If two files include the same file will the first one success to read all the function the second will fail but still be able to use the functions??
What happens when I forward declare some function? Is this function now "saved" and I can use it anywhere or it's known only for the same file? then why two files with include(to a file with guards) will work?
Can I just include every thing in the main and won't bother any longer?
EDIT:
And why the cpp files should include their headers?? What If i won't include them?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您包含文件时,预处理器会将其内容“复制并粘贴”到包含源中。当您转发声明一个函数/类时,您声明了一个不完整的类型,让翻译单元的其余部分知道存在具有该名称的函数/类,并使其在允许不完整声明的上下文中可用。
如果包含的文件包含正确的包含防护,则同一翻译单元中的第二个包含将实际上是无操作。如果两个不同的源文件包含相同的头文件,则完整内容将包含在两个文件中。
该函数只能在包含前向声明的翻译单元内使用。通常,每个源文件 (.cpp) 都是不同的翻译单元,宏定义(标头防护的宏定义)以及声明/定义在该翻译单元内有效。标头防护可防止同一标头文件在同一翻译单元中多次包含,从而防止出现多个声明错误。
When you include a file, its contents get "copy and pasted" into the inclusion source by the preprocessor. When you forward declare a function/class you are declaring an incomplete type, letting the rest of the translation unit know that a function/class with that name exist and making it usable within context where an incomplete declaration is allowed.
If the included file includes proper include guards, the second inclusion within the same translation unit will be effectively a no-op. If two different source files include that same header file, the full content will be included in both files.
The function can only be used within the translation unit that contains the forward declaration. Generally each source file (.cpp) is a different translation unit, macro definitions (those of the header guards) as well as declarations/definitions are valid within that translation unit. Header guards prevent the same header file from being included more than once within the same translation unit, to prevent multiple declaration errors.
当您
包含
文件时,预处理器会有效地将整个包含
文件复制粘贴到执行包含
操作的文件中。当您转发声明一个函数/类时,您是在告诉编译器它存在,但不需要整个头文件。当您有循环依赖时,这是必需的,并且大大减少其他地方的编译时间。如果同一个文件在一个翻译单元(
.cpp
文件)中包含两次,则两者都会“成功”,但如果标头具有任何类型的包含保护,则第二次不会加载任何内容,因为预处理器已经将其“复制”到翻译单元中,并且第二次执行此操作会复制所有内容,这将是一个错误。因此,所有涉及的文件都可以使用到目前为止包含的所有标头中的所有函数。是的,如果您在标头中转发声明函数/类,则包含该标头的任何其他文件都可以使用它。
大概。一旦您遇到更复杂的示例,您最终会遇到循环依赖关系,这需要按特定顺序声明和/或定义某些内容。除此之外,是的。您可以将所有内容都包含在 main 中并保持简单。但是,您的代码将需要很长时间才能编译。
那么
.cpp
文件将不知道其自身之外还存在任何其他内容。不太有用。When you
include
a file, the preprocessor effectively copy pastes the entireincluded
file into the file doing theinclude
ing. When you forward declare a function/class, you're telling the compiler that it exists, but you don't need the entire header file. This is required when you have circular dependancies, and and greatly reduce compile times in other places.If the same file gets included twice in one translation unit (
.cpp
file), then the both will "succeed", but if the header has include guards of any sort, nothing will be loaded the second time, because the preprocessor has already "copied" it into the translation unit, and to do it a second time would make duplicates of everything, which would be a bug. So all files involved can use all the functions in all the headers included up to that point.Yes, if you forward declare a function/class in a header, it can be used by any other file that includes that header.
Probably. Once you get to more complicated examples, you'll end up with circular dependancies, which require certain things to be declared and/or defined in a certain order. Other than that, yes. You can include everything in main and keep it simple. However, your code will take FOREVER to compile.
Then that
.cpp
file won't know that anything else exists outside of itself. Not very useful.简短回答:
转发类/函数允许编译器实际上不必编译整个类/函数,除非需要。
长答案:
转发类/函数就像声明类/函数而不定义它一样。您承诺稍后定义它,但现在您只想通知编译器它存在。您通常在头文件中执行这些向前减速。这通常会导致更快的编译时间,因为在包含标头的 .cpp 文件中,只有那些实际需要您转发的类并包含其适当的头文件的文件才需要实际编译该包含类的代码。
Short answer:
Forwarding a class/function allows the compiler to not actually have to compile the entire class/function unless needed.
Long answer:
Forwarding a class/function is just like declaring a class/function without defining it. You're promising to define it later, but for now you just want to inform the compiler it exists. You usually do these forward decelerations in header files. This generally results in faster compile times because in .cpp files that include your header, only those that actually need the class you've forwarded and include it's appropriate header file need to actually compile that included class's code.