1

老实说,我对头文件中函数(有时是数据成员)声明中的关键字与实现文件中的关键字感到困惑。

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

(根据评论更新)

  • 头文件不包含实现,除非函数被声明为“内联”
  • 数据成员不包含默认值,除非类型为 static、const、int/enum(C++11 除外)
  • public/private/protected 通常出现在头文件中
  • “静态”通常出现在头文件中,而不是实现文件中。

你还有其他我可以遵循的规则吗?常数?

继承权呢?我认为“虚拟”只出现在头文件中?如果我从A类继承虚函数到B类,B类的头文件是否必须声明它覆盖的虚函数?A类中的纯虚函数怎么样,当我在B类中重写时,我是否必须在派生类的头文件中包含纯虚函数定义?

4

2 回答 2

2

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

于 2013-03-01T13:30:22.170 回答
1

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

为了完整性:一旦预处理器将所有包含的文件转储到要求它们的位置,编译器就会分别编译每个文件。这通常会给您留下一堆没有实现的声明和一堆没有声明的实现:链接器会整理出这些引用。因此,如果您遇到链接器错误,则意味着您在某处不匹配某些内容:也许您声明了两次,或者从未实现过。

我们实际上拥有的是一系列关于我们想要在头文件中什么以及我们想要在源文件中什么的最佳实践。通常,我们喜欢在头文件中声明。换句话说,头文件应该告诉我(程序员)我希望在实现中找到什么。通常,这些是声明:因此您通常只能在标题中看到访问修饰符(公共、私有、受保护)。一些程序员会做一些“奇怪”的事情,比如在头文件中编写构造函数:这是有效的,但通常不是预期的——你希望你的头文件告诉我我可以从你的代码中使用什么,而不是你的代码是如何工作的。

于 2013-03-01T13:36:32.597 回答