头文件与源/实现文件中关键字包含C++ "Rules"

C++ "Rules" for keyword inclusion in Header file vs Source/Implementation file

本文关键字:文件 C++ 包含 Rules 关键字 实现      更新时间:2023-10-16

必须诚实,我在头文件中的函数(有时是数据成员)声明中的关键字与实现文件中的关键字之间感到困惑。

要遵循的规则是什么?例如

(按注释更新)

  • 头文件不包含实现,除非函数声明为"inline"
  • 数据成员不包含默认值,除非类型是static、const、int/enum(除非c++ 11)
  • Public/private/protected通常出现在头文件
  • "Static"通常出现在头文件中,而不是实现文件。

还有什么我可以遵循的规则吗?常量?

继承呢?我假定"虚拟"只在头文件中?如果我从类A继承虚函数到类B,类B的头文件必须声明它覆盖的虚函数吗?a类中的纯虚函数怎么样,当我在B类中重写时,我必须在派生类的头文件中包含纯虚函数定义吗?

看起来你在不了解它是如何工作的情况下试图制定一些正式的规则。但它真的很简单,当预处理器看到#include指令时,它只是将其替换为该文件的内容(就像命令复制整个文件并粘贴在这里)。因此,与其制定正式的规则,不如问问自己:这个语句应该出现在使用这个头文件的每个.cpp文件中吗?它们还会编译吗?我真的需要它无处不在,还是它可以只在一个提供实现的.cpp文件中?如果答案是肯定的,那么该语句应该进入头文件,如果答案是否定的,那么将其放入.cpp实现文件中。

C和c++中的#include语句比你想象的要简单得多:它获取include 'd文件的内容,并将其直接转储到包含文件中。这可以是任何东西(我在我的工作中看到很多新手开发人员)。如果它是磁盘上的一个文件,在某些时候有人试图include它:甚至。cpp文件。你可以,如果你想证明给自己看,复制&将包含的文件的内容粘贴到include中-一切都应该像以前一样工作。

为了完整性:一旦预处理器将所有包含的文件转储到需要它们的位置,编译器将分别编译每个文件。这通常会给你留下一堆没有实现的声明和一堆没有声明的实现:链接器会对这些引用进行分类。所以如果你有一个链接器错误,那意味着你在某个地方错配了一些东西:可能你声明了一些东西两次,或者从来没有实现过它。

我们实际上拥有的是一系列关于头文件和源文件的最佳实践。通常,我们喜欢在头文件中进行声明。换句话说,头文件应该告诉我(程序员)我希望在实现中找到什么。通常,这些都是声明:因此,您通常只在头文件中看到访问修饰符(public、private、protected)。有些程序员会做一些"奇怪"的事情,比如在头文件中编写构造函数:这是有效的,但通常不被期望-你希望你的头文件告诉我我可以从你的代码中使用什么,而不是你的代码如何工作。