C++多次包含头文件
C++ Including header file multiple times
我只是想知道根据下面的示例包含特定头文件的必要性/权利在哪里。假设我有一个异常类的定义:
//exc.hpp
#ifndef EXC_H
#define EXC_H
class MyException : public exception {
};
#endif /* EXC_H */
然后我有另一个类定义抛出这样的异常:
//a.cpp
void SomeClass::someMethod(void) {
throw MyException(...);
}
并有另一个文件处理该异常,例如:
//main.cpp
#include "a.hpp"
int main() {
...
catch(MyException & e) { ... }
}
所以我的问题是,我应该把#include "exc.hpp"
放在哪里?只是为了a.hpp
,还是a.hpp
和main.cpp
?
当涉及到makefile
...在此类文件中应如何指定目标?
throw
或catch
该类型的例外的每个翻译单元都需要能够看到其定义。
粗略地说,这意味着每个包含与该异常相关的throw
或catch
的.cpp
文件都必须包含您的.hpp
文件。
即使您只通过引用捕获并且从不检查异常对象,这在C++的其他领域(前向声明就可以)并非如此。
生成文件是不相关的。
带有实现的文件(a.cpp
)和所有使用该类的文件(main.cpp
)都应该有#include
。
没有包含的a.cpp
不得编译。
您需要在main.cpp和a.cpp中包含.hpp文件。 #ifndef 序列的目的是防止意外的多重包含(通过间接 #includes)。 MS编译器中还有一个 #pragma once指令可以做同样的事情。
编译器根据.cpp文件中的 #includes 确定要读取的.h/.hpp文件;不涉及make文件。
请记住,编译器独立处理每个源文件,并且在完成处理后不会记住源文件中的任何内容。 即使在单个编译器命令行上列出多个源文件也是如此。
您有一个定义类型的头文件。 当然,您必须在需要定义该类型的每个源文件中#include
头文件。(编译器不会记得在处理早期源文件时见过这些类型。
在其他标头中#include
标头可能很诱人,这样您就不必在 .c 或 .cpp 文件中#include
太多内容,但应尽可能避免这种情况。 它产生所谓的"标头耦合",并且它使代码以后很难在其他项目中重用。
在我上面所说的中还有一个很好的观点:"你需要定义该类型的地方"。 在 C 和 C++ 中有两个非常具体的概念与变量相关:
- 声明 -- 当您让编译器知道存在某个类型时,以及
- 定义 -- 告诉编译器类型的详细信息。
您需要在需要定义的任何位置#include
标头。 即,当您打算实例化该类型的对象时,在另一个结构或类中定义该类型的成员,或调用其方法之一(假设C++)。 相反,如果您只想存储对该类型的对象的引用而不创建或使用它们,则声明就足够了,您只需前向声明该类即可。 即,
class MyException;
void setFileNotFoundExceptionObject(const MyException *exc) { ... }
许多 API 专门设计为仅使用指向对象的指针或引用,因此 API 标头只需要类型的前向划分,而不是完整的定义(这会隐藏对象的内部成员以防止开发人员滥用它们。
- 使用mongocxx驱动程序时包含头文件问题
- 如何为包含头文件的目标编写生成文件?
- 如何在 CMakeLists.txt Qt Creator 中包含头文件?
- 当包含头文件的文件不在根项目文件夹中时,如何包含它
- 在生成文件先决条件中包含头文件的原因
- My Project的属性配置正确,但Visual Studio仍然无法打开包含头文件
- 在 PostgreSQL C 扩展中包含头文件
- 是否可以在C++中以间接方式包含头文件
- 是否需要包含头文件?
- 如何在不包含完整的文件系统头的情况下使用文件系统的类路径C++17?
- 我收到未声明的标识符错误,但我已包含头文件?
- 为什么我们需要构建一个提升库,仅仅包含头文件还不够吗,因为提升是模板
- C++:当顺序真正重要时,如何保证在项目中包含头文件的顺序
- 如何在C++中包含头文件时错误地重载
- 我在C++中无效使用不完整的类型类错误,如何正确包含头文件?
- 虚幻引擎4.16,C++包含头文件
- C++多次包含头文件
- 令牌之前的预期类名 '{' - 包含头文件和 CPP 文件
- 可以将标头文件包含在多个源文件中,而无需重复保护
- 有条件地将文件包含在C++标头中