就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the help center寻求指导。
9年前关闭。
社区在 5 个月前审查了是否重新打开此问题并将其关闭:
原始关闭原因未解决
为什么 C++ 有头文件和 .cpp 文件?
最佳答案
C++ 编译
C++ 中的编译分两个主要阶段完成:
HPP 在所有这些过程中的位置如何?
一个可怜的孤独的CPP文件......
每个 CPP 文件的编译独立于所有其他 CPP 文件,这意味着如果 A.CPP 需要 B.CPP 中定义的符号,例如:
// A.CPP
void doSomething()
{
doSomethingElse(); // Defined in B.CPP
}
// B.CPP
void doSomethingElse()
{
// Etc.
}
它不会编译,因为 A.CPP 无法知道“doSomethingElse”的存在......除非 A.CPP 中有声明,例如:// A.CPP
void doSomethingElse() ; // From B.CPP
void doSomething()
{
doSomethingElse() ; // Defined in B.CPP
}
然后,如果您有使用相同符号的 C.CPP,则复制/粘贴声明...复制/粘贴警告!
是的,有问题。复制/粘贴是危险的,并且难以维护。这意味着如果我们有一些方法可以不复制/粘贴,并且仍然声明符号会很酷......我们该怎么做?通过包含一些文本文件,通常以 .h、.hxx、.h++ 或我更喜欢的 C++ 文件后缀 .hpp 为后缀:
// B.HPP (here, we decided to declare every symbol defined in B.CPP)
void doSomethingElse() ;
// A.CPP
#include "B.HPP"
void doSomething()
{
doSomethingElse() ; // Defined in B.CPP
}
// B.CPP
#include "B.HPP"
void doSomethingElse()
{
// Etc.
}
// C.CPP
#include "B.HPP"
void doSomethingAgain()
{
doSomethingElse() ; // Defined in B.CPP
}
include
如何工作?从本质上讲,包含文件将解析其内容,然后将其内容复制粘贴到 CPP 文件中。
例如,在以下代码中,带有 A.HPP header :
// A.HPP
void someFunction();
void someOtherFunction();
...来源B.CPP:// B.CPP
#include "A.HPP"
void doSomething()
{
// Etc.
}
... 包含后将变为:// B.CPP
void someFunction();
void someOtherFunction();
void doSomething()
{
// Etc.
}
一件小事——为什么在 B.CPP 中包含 B.HPP?在当前情况下,这不是必需的,B.HPP 有
doSomethingElse
函数声明,B.CPP 有 doSomethingElse
函数定义(它本身就是一个声明)。但在更一般的情况下,B.HPP 用于声明(和内联代码),可能没有相应的定义(例如,枚举、普通结构等),因此如果 B.CPP 可能需要包含使用 B.HPP 的那些声明。总而言之,默认情况下包含其标题的源是“好品味”。结论
因此头文件是必要的,因为 C++ 编译器无法单独搜索符号声明,因此,您必须通过包含这些声明来帮助它。
最后一句话:你应该在你的HPP文件的内容周围放置标题保护,以确保多个包含不会破坏任何东西,但总而言之,我相信上面解释了HPP文件存在的主要原因。
#ifndef B_HPP_
#define B_HPP_
// The declarations in the B.hpp file
#endif // B_HPP_
甚至更简单(虽然不是标准的)#pragma once
// The declarations in the B.hpp file
关于c++ - 为什么要有头文件和 .cpp 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60264014/